Bug 24175 – DIP1000 fails to determine proper lifetime for struct

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-10-05T16:58:58Z
Last change time
2023-10-06T21:11:36Z
Assigned to
No Owner
Creator
Grim Maple

Comments

Comment #0 by grimmaple95 — 2023-10-05T16:58:58Z
Consider the code below: ``` struct A { this(int[] data) @safe { a = data; } int[] a; } void main() @safe { int[3] test = [1, 2, 3]; A a = A(test); } ``` It fails to compile with dip1000, saying: Error: reference to local variable `test` assigned to non-scope parameter `data` calling `this` However, both `a` and `test` should have same lifetime and therefore this code should be allowed
Comment #1 by dkorpel — 2023-10-05T19:00:36Z
> However, both `a` and `test` should have same lifetime and therefore this code should be allowed To communicate that, you need to add `return scope` to parameter `data`, or make the constructor a template function so it's inferred. Otherwise the constructor could assign the stack allocated slice to a global variable.
Comment #2 by grimmaple95 — 2023-10-06T17:03:19Z
I don't understand how this is invalid, when the code I wrote is completely valid, doesn't escape references, yet is marked as "escaping references"
Comment #3 by maxsamukha — 2023-10-06T17:49:59Z
(In reply to Grim Maple from comment #2) > I don't understand how this is invalid, when the code I wrote is completely > valid, doesn't escape references, yet is marked as "escaping references" The problem is separate compilation/lack of lifetime inference: struct A { this(int[] data) @safe; int[] a; } Now, compiler doesn't know whether the constructor stores the argument in a location outliving 'this'. People are busy trying to be compatible with stone-age technologies, so it's unlikely to change.
Comment #4 by apz28 — 2023-10-06T21:11:36Z
SCOPE & dip1000 is not for prime-time yet. Still having bug & not easier to use as below sample @safe: class C1 { @safe: int i; } struct A1 { @safe: this(C1 c1, return scope int[] a) { this.a = a; this.c1 = c1; this.c1s.reserve(10); } C1 compute() { return c1; } int[] a; C1[] c1s; C1 c1; } int main() { int n; { // Simulate a scope block C1 c1 = new C1(); int[3] a = [1, 2, 3]; A1 a1 = A1(c1, a[]); n = a1.compute().i; } return n; } onlineapp.d(18): Error: scope variable `this` assigned to non-scope parameter `arr` calling `reserve` /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3931): which is not `scope` because of `cast(void[]*)&arr` onlineapp.d(38): Error: scope variable `a1` calling non-scope member function `A1.compute()`