Bug 18672 – Error in @safe transitive propagation with associative arrays

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-03-27T20:56:24Z
Last change time
2024-12-13T18:58:00Z
Keywords
safe
Assigned to
No Owner
Creator
Seb
Moved to GitHub: dmd#19414 →

Comments

Comment #0 by greensunny12 — 2018-03-27T20:56:24Z
cat > main.d << EOF void main() @safe { struct ThrowingElement { int i; ~this() { assert(1); } } ThrowingElement[int] aa; aa[0] = ThrowingElement(0); } EOF (resubmission of the example of #18592 as I do believe that the compiler should
Comment #1 by greensunny12 — 2018-03-27T21:02:44Z
Argh I accidentally hit submit. The reason for the resubmission is that the following code compiles fine already: cat > main.d << EOF void main() @safe { struct Foo { int i; ~this() // <- no need to annotate with @safe explicitly here { assert(1); } void m(){} // <- no need to annotate with @safe explicitly here } Foo foo; foo.m(); } EOF So DMD already does transitively apply @safe, but apparently if it generated for associative arrays this generation doesn't work in all cases.
Comment #2 by ag0aep6g — 2018-03-27T21:22:16Z
(In reply to Seb from comment #1) > So DMD already does transitively apply @safe, but apparently if it generated > for associative arrays this generation doesn't work in all cases. It's not the associative array. It's just that the generated opAssign isn't @safe (for no reason): ---- void main() @safe { struct ThrowingElement { ~this() {} } ThrowingElement aa; /* Accepted. The destructor is apparently inferred as @safe. */ aa = aa; /* Error: @safe function D main cannot call @system generated function onlineapp.main.ThrowingElement.opAssign */ } ----
Comment #3 by razvan.nitu1305 — 2018-03-29T14:52:12Z
(In reply to ag0aep6g from comment #2) > (In reply to Seb from comment #1) > > So DMD already does transitively apply @safe, but apparently if it generated > > for associative arrays this generation doesn't work in all cases. > > It's not the associative array. It's just that the generated opAssign isn't > @safe (for no reason): > > ---- > void main() @safe > { > struct ThrowingElement > { > ~this() {} > } > > ThrowingElement aa; > /* Accepted. The destructor is apparently inferred as @safe. */ > aa = aa; > /* Error: @safe function D main cannot call @system generated > function onlineapp.main.ThrowingElement.opAssign */ > } > ---- That's because the generated opAssign is not @safe. Look at [1] : it injects a pointer which is void initialized, after that the function is inferred to be @system. I tried replacing the void initializer with null, or with a new ExpInitializer(loc, new ThisExp(loc)). That solves the current test case, but ends up failing other tests (for reasons unknown) [1] https://github.com/dlang/dmd/blob/master/src/dmd/clone.d#L273
Comment #4 by greensunny12 — 2018-04-02T22:44:46Z
@RazvanN how about setting the opAssign to @trusted instead when we now that the dtor is @safe? The problem is that sd.dtor.isSafe() returns 0 :/ Maybe we need to go through semantic first before looking at this? Also there seems to be an existing check for this already - it just doesn't get triggered ``` stc = mergeFuncAttrs(stc, sd.dtor); if (stc & STC.safe) ``` Well at least the high-level isSafe traits infers the safety correctly: https://run.dlang.io/is/6ePqDY
Comment #5 by razvan.nitu1305 — 2018-08-23T16:56:57Z
Comment #6 by robert.schadek — 2024-12-13T18:58:00Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19414 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB