Bug 21626 – foreach create reference to rvalue tuple returned by front

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-02-10T13:25:24Z
Last change time
2024-12-13T19:14:40Z
Assigned to
No Owner
Creator
vitamin
Moved to GitHub: dmd#18022 →

Comments

Comment #0 by submada — 2021-02-10T13:25:24Z
If range return rvalue tuple from front and foreach unpack tuple then temporary value to front is ref and after leaving scope destructor is not called: import std.range; import std.stdio; import std.typecons; int created, destroyed; ///struct count destructions and constructions struct S{ int val; @disable this(); this(int val) { this.val = val; created++; } this(ref inout const typeof(this) rhs)inout { this.val = rhs.val; created++; } ~this() { destroyed++; } } //range, for each call of front return rvalue Tuple!(S, S) struct Generator(T){ int n; this(int n){ this.n = n; } @property Tuple!(T, T) front(){ return tuple(T(n), T(n)); } @property void popFront(){ n -= 1; } @property bool empty()const{ return n < 1; } } ///This work OK: void test_A(){ foreach(s; Generator!S(10)){ assert(s[0].val == s[1].val); } assert(created == destroyed); } ///This fail: void test_B(){ foreach(s1, s2; Generator!S(10)){ assert(s1.val == s2.val); } writeln(": created ", created, " vs destroyed ", destroyed); ///created != destroyed assert(created == destroyed); ///FAIL!! } void main() { test_A(); test_B(); } test_B AST: void test_B() { { Generator!(S) __r101 = __r101 = 0 , __r101.this(10); for (; !__r101.empty(); __r101.popFront()) { ref Tuple!(S, S) __front102 = __r101.front(); ///PROBLEM! reference to rvalue, destructor is not called! ref S s1 = __front102.__expand_field_0; ref S s2 = __front102.__expand_field_1; assert(s1.val == s2.val); } } writeln(": created ", created, " vs destroyed ", destroyed); assert(created == destroyed); }
Comment #1 by nick — 2024-05-16T11:26:04Z
Confirmed with dmd v2.108.0-rc.1.
Comment #2 by robert.schadek — 2024-12-13T19:14:40Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18022 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB