-------- import std.algorithm, std.stdio; @safe: auto foo() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs[].map!(x => x); } void main() { writeln(foo()); } -------- Observed: this compiles and (for me) prints [0, 0, -2132056872, 22008, 0, 0]. Expected: fail to compile with error about the escaped local reference.
This is a duplicate of https://issues.dlang.org/show_bug.cgi?id=8838, which was closed as fixed based on the fact that -dip1000 fixes the problem. It's still quite broken without -dip1000 though.
It is still broken with -dip1000 https://run.dlang.io/is/gJi2Fa
Reduced: @safe: struct A(alias fun) { int[] r; this(int[] q){r=q;} } template m(alias fun) { auto m(int[] r) { return A!fun(r); } } auto foo() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs[].m!(x => x); } void main() { auto a=foo(); }
@safe: struct A(T) { int[] r; this(int[] q){r=q;} } int[] escape(T)(int[] r) { return A!int(r).r; } int[] f() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs.escape!int; }
Under dip1000, what I think is that slicing a static array should always be considered scope. Also, calling a functions with a scope slice with the parameter for the slice not annotated as scope should result in an error if the compiler can't prove that the parameter can't escape.
Same for pointers: @safe: struct A(T) { int* r; this(int* q){r=q;} } int* escape(T)(int* r) { return A!int(r).r; } int* f() { int x; return escape!int(&x); }
(In reply to anonymous4 from comment #6) > Same for pointers: [...] Resolving the templates shows that this is related to `pure`: ---- @safe: struct A { int* r; this(int* q) pure { r = q; } } int* escape(int* r) pure { return A(r).r; } int* f() { int x; return escape(&x); } ----
Works for me as in v2.087.1
(In reply to Mike Franklin from comment #8) > Works for me as in v2.087.1 Most of the test cases are correctly rejected now with -dip1000. But the one from comment #7 is still accepted. Moved to issue 20150.