Bug 22775 – The __traits does not see the scope attribute

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-02-15T07:23:07Z
Last change time
2022-02-17T07:28:52Z
Keywords
safe
Assigned to
No Owner
Creator
cbleser

Attachments

IDFilenameSummaryContent-TypeSize
1841interface_match.dExample of the problemapplication/x-dsrc1417

Comments

Comment #0 by cr — 2022-02-15T07:23:07Z
Comment #1 by cr — 2022-02-15T07:33:58Z
Created attachment 1841 Example of the problem Compile it with dmd -dip25 -dip1000 interface_match.d -unittest -main
Comment #2 by cr — 2022-02-15T08:00:09Z
I have detected a problem when using interfaces and scope variables. It seems that the compile does not check the scope attributes. The flowing compiles ``` struct S { int x; } @safe interface I { int func(ref scope S s) @nogc; } @safe class C : I { int func(ref S s) { return 2*s.x; } } ``` The problem is that the interface function has a (ref scope S) parameter but the class implements a (ref S). (The code should be compiled with dip25 and dip1000) The biggest problem is that sometimes it results in a segmentation fault. Due to that, the compiler seems to treats it as two different when it is called from the interface. Note. It seems that the @nogc is carried to the C.func. (Maybe it is just auto-adapted) See. The attached example. Keep up the good work tanks.
Comment #3 by bugzilla — 2022-02-17T06:43:02Z
The attached example: -------------------------- import std.traits; import std.meta; struct S { int x; } @safe interface I { int func(ref scope S s) @nogc; } @safe class C : I { int func(ref S s) { return 2*s.x; } } @safe class Cscope : I { int func(ref scope S s) { return 2*s.x; } } @safe class Cconst : I { int func(ref const S s) { return 2*s.x; } } @safe struct ST { int func(ref S s) { return 2*s.x; } } @safe struct STscope { int func(ref scope S s) { return 2*s.x; } } @safe struct STconst { int func(ref const S s) { return 2*s.x; } } alias getMemberType(alias O, string name)=typeof(__traits(getMember, O, name)); static unittest { pragma(msg, I, " : ", getMemberType!(I, "func")); pragma(msg, C, " : ", getMemberType!(C, "func")); pragma(msg, Cscope, " : ", getMemberType!(Cscope, "func")); pragma(msg, Cconst, " : ", getMemberType!(Cconst, "func")); pragma(msg, getMemberType!(Cscope, "func").stringof); static assert(getMemberType!(Cscope, "func").stringof == q{@nogc @safe int(ref scope S s)}); } static unittest { pragma(msg, ST, " : ", getMemberType!(ST, "func")); pragma(msg, STscope, " : ", getMemberType!(STscope, "func")); pragma(msg, STconst, " : ", getMemberType!(STconst, "func")); static assert(getMemberType!(STscope, "func").stringof == q{@safe int(ref scope S s)}); }
Comment #4 by bugzilla — 2022-02-17T07:28:52Z
What's happening is that `S` does not have any pointers in it. `scope` only applies to pointers, otherwise it is ignored. That's why it never shows up. If `S` has a pointer member, it shows up. This is expected behavior.