Bug 14771 – Hidden @nogc violation around closure creation

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-07-05T05:15:12Z
Last change time
2024-12-13T18:43:41Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Kenji Hara
Moved to GitHub: dmd#19012 →

Comments

Comment #0 by k.hara.pg — 2015-07-05T05:15:12Z
The variable x in makeS() function is actually placed in closure object on heap, but it's not checked by the @nogc. struct S(alias f) { auto foo()() { return f(0); } void dummy() {} } auto makeS() @nogc { int x = 10; S!(a => x) s; // instantiating foo inside makeS will raise the @nogc violation error. //assert(s.foo() == 10); return s; } void main() @nogc { auto s = makeS(); // the hidden field of s is actually non-null, // that points closure object on heap. assert(s.tupleof[$-1] !is null); // instantiating foo outside makeS will place the variable x in closure // *after* the semantic3 completion of the function. // --> @nogc attribute on makeS() is ignored! // --> @nogc on main() has no effect, so foo itself has no GC-allocation. assert(s.foo() == 10); }
Comment #1 by k.hara.pg — 2015-07-07T17:11:29Z
Issue 5730 is also related with the closure handling timing.
Comment #2 by ag0aep6g — 2015-08-30T13:57:53Z
A variant is to make makeS a template instead of S.foo: ---- struct S(alias f) { auto foo() { return f(0); } } auto makeS()() @nogc { int x = 10; S!(a => x) s; return s; } void main() @nogc { auto s = makeS(); } ---- Compiles, but shouldn't. Some change in 2.068's Phobos makes it possible to accidentally do this with std.algorithm.map: ---- import std.algorithm: equal, map; import std.range: only; auto foo()(int[] a, immutable int b) { return a.map!(x => x + b); } void main() @nogc { int[3] test = [1,2,3]; assert(test[].foo(3).equal(only(4,5,6))); } ---- I've seen this twice recently: http://forum.dlang.org/post/[email protected] http://forum.dlang.org/post/[email protected]
Comment #3 by stanislav.blinov — 2021-12-08T18:12:51Z
Still an issue in 2.098.
Comment #4 by robert.schadek — 2024-12-13T18:43:41Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19012 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB