Bug 18802 – [REG2.080] Safe block causing lifetime problem

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-04-27T13:07:44Z
Last change time
2018-12-19T19:19:40Z
Assigned to
No Owner
Creator
Tomáš Chaloupka

Comments

Comment #0 by chalucha — 2018-04-27T13:07:44Z
--- @safe { struct Foo { string[] bars; this(string[] bars...) { this.bars = bars; } } } void main() { auto f = Foo("a", "b", "c"); } --- Ends with: Error: scope variable bars assigned to this with longer lifetime With dmd-2.080-beta.1 This worked before
Comment #1 by razvan.nitu1305 — 2018-12-19T15:14:11Z
Actually, I think that the bug report might not be invalid. Although this used to work, its consistent that now it doesn't. What happens here: 1. When the D-style variadic function is defined : `this(string[] bars...)`, the compiler sees it as `this(scope string[] bars)` and everytime it gets called (i.e `Foo("a", "b", "c")`) it rewrites the call to match the function definition (i.e. `Foo(["a", "b", "c"])). The important thing here is that the documentation specifies that the array may be constructed on the stack. 2. When `this.bars = bars` is semantically analyzed the reference to the possibly stack constructed array is passed to `this.bars` which has a longer lifetime. This is an unsafe operation, so it is not possible in a safe function. Your slightly modified example: struct Foo { int* bars; @safe this(scope int* bars) { this.bars = bars; } } void main() { int a; auto f = Foo(&a); } This code started issuing an error since 2.074, so I'm guessing the direction the compiler is heading is this one. Note how the above code is almost identical to the one generated by the compiler in your original post: struct Foo { string[] bars; @safe this(scope string[] bars) { this.bars = bars; } } void main() { auto f = Foo(["a", "b", "c"]); // -> the string[] is on the stack constructed } I suggest we close this as invalid.
Comment #2 by chalucha — 2018-12-19T19:19:40Z
Thanks for thorough explanation. Makes sense to work this way, so this should probably really be closed as invalid.