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()`