Bug 20006 – [REG 2.086.0] DIP1000: return scope ref outlives the scope of the argument

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-06-25T17:22:56Z
Last change time
2020-03-13T10:05:49Z
Assigned to
No Owner
Creator
Eugene Wissner

Comments

Comment #0 by belka — 2019-06-25T17:22:56Z
The following code doesn't compile with 2.085 (as expected): static struct Inserter { int* i; private this(return scope ref int) @safe { } } auto func() @safe { int i; return Inserter(i); } but compiles with 2.086. It should produce an error: "test.d(13): Error: returning Inserter(null).this(i) escapes a reference to local variable i". -preview=dip1000 is assumed in both cases.
Comment #1 by dfj1esp02 — 2019-06-27T09:00:58Z
Doesn't look like your example escapes a reference to local variable.
Comment #2 by belka — 2019-08-28T18:43:11Z
The constructor parameter is marked with "return scope ref" and it means that Inserter isn't allowed to outlive it. You can also write this(return scope ref int i) @trusted { this.i = &i; } and it worked prior to 2.086 as well.
Comment #3 by bugzilla — 2020-03-13T10:05:49Z
Let's rewrite the example as: ---- struct Inserter { int* i; } ref Inserter ctor(return scope ref int) @safe; Inserter func() @safe { int i; return ctor(i); } --- because, as I endlessly point out, in order to understand what is going on, REWRITE IN SIMPLE TERMS. I.e. lower like the compiler does. In this case, get rid of auto, get rid of member functions, etc. Note constructors return by ref. The reason no error is given is because ctor() is told to attach the address of i to ctor()'s return value, which is a reference to an instance of Inserter. Now, because Inserter is returned by value, not by reference, the referred to value is returned, NOT THE REFERENCE! Only the ref is protected, not the value being referenced. Not a bug. I know this is complicated, and the ONLY way to understand it is to peel away the complexity by lowering it to ref's and pointer's and nothing else.