[Issue 21626] New: foreach create reference to rvalue tuple returned by front
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Wed Feb 10 13:25:24 UTC 2021
https://issues.dlang.org/show_bug.cgi?id=21626
Issue ID: 21626
Summary: foreach create reference to rvalue tuple returned by
front
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: major
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: submada at gmail.com
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);
}
--
More information about the Digitalmars-d-bugs
mailing list