https://issues.dlang.org/show_bug.cgi?id=23305
Issue ID: 23305 Summary: Tuple.expand generates garbage values when passed to multiple lazy parameters Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: krzysztof.jajesn...@student.put.poznan.pl import std.stdio; import std.typecons; auto foo(lazy int a, lazy int b, lazy int c, lazy int d) { return tuple(d, c, b, a); } void main() { auto r = foo(tuple(3,4,5,6).expand); writeln(r); } This code prints "Tuple!(int,int,int,int)(0, 0, <random garbage>, 3)" on my machine (DMD 2.100.0) and gives similar results on run.dlang.io (DMD 2.099.1). The bug only occurs if Tuple is obtained directly from a function call - using a Tuple stored in a variable works fine: // this works auto t = tuple(3,4,5,6); auto r = foo(t.expand); The bug also occurs with any struct/class declaring multiple fields using an AliasSeq of types, not just std.typecons.Tuple: // also affected struct vec2 { AliasSeq!(float,float) expand; } Looking at output of -vcg-ast it seems that when a Tuple is obtained directly from a function call and .expand is passed to multiple lazy parameters, the Tuple is put in a local variable inside the body of the delegate generated for the first parameter, and the other delegates reuse the same variable. I'm assuming this causes the other delegates to read whatever is in the same location on the stack, hence semi-random garbage. void main() { Tuple!(int, int, int, int) r = foo( delegate int() pure nothrow @nogc @safe => (Tuple!(int, int, int, int) __tup82 = tuple(3, 4, 5, 6);) , __tup82.__expand_field_0, delegate int() pure nothrow @nogc @safe => __tup82.__expand_field_1, delegate int() pure nothrow @nogc @safe => __tup82.__expand_field_2, delegate int() pure nothrow @nogc @safe => __tup82.__expand_field_3 ); writeln(r); return 0; } For reference, LDC (1.30.0) refuses to compile foo(tuple(3,4,5,6).expand) and gives the following error message: app.d(9): Error: function `app.main.__dgliteral3` cannot access frame of function `app.main.__dgliteral2` app.d(9): Error: function `app.main.__dgliteral4` cannot access frame of function `app.main.__dgliteral2` app.d(9): Error: function `app.main.__dgliteral5` cannot access frame of function `app.main.__dgliteral2` GDC (12.1.1) also gives a similar error message. --