Skip to content

Commit a504a5e

Browse files
pbackusdlang-bot
authored andcommitted
Fix Issue 23182 - Can't assign struct with opAssign to SumType in CTFE
SumType.opAssign now avoids calling core.lifetime.move or core.lifetime.forward during CTFE whenever possible.
1 parent 1206fc9 commit a504a5e

1 file changed

Lines changed: 46 additions & 4 deletions

File tree

std/sumtype.d

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,19 @@ public:
635635

636636
this.match!destroyIfOwner;
637637

638-
mixin("Storage newStorage = { ",
639-
Storage.memberName!T, ": forward!rhs",
640-
" };");
638+
static if (isCopyable!T)
639+
{
640+
// Workaround for https://issues.dlang.org/show_bug.cgi?id=21542
641+
mixin("Storage newStorage = { ",
642+
Storage.memberName!T, ": __ctfe ? rhs : forward!rhs",
643+
" };");
644+
}
645+
else
646+
{
647+
mixin("Storage newStorage = { ",
648+
Storage.memberName!T, ": forward!rhs",
649+
" };");
650+
}
641651

642652
storage = newStorage;
643653
tag = tid;
@@ -678,7 +688,17 @@ public:
678688
{
679689
import core.lifetime : move;
680690

681-
rhs.match!((ref value) { this = move(value); });
691+
rhs.match!((ref value) {
692+
static if (isCopyable!(typeof(value)))
693+
{
694+
// Workaround for https://issues.dlang.org/show_bug.cgi?id=21542
695+
this = __ctfe ? value : move(value);
696+
}
697+
else
698+
{
699+
this = move(value);
700+
}
701+
});
682702
return this;
683703
}
684704
}
@@ -1569,6 +1589,28 @@ version (D_BetterC) {} else
15691589
}
15701590
}
15711591

1592+
// Assignment of struct with overloaded opAssign in CTFE
1593+
// https://issues.dlang.org/show_bug.cgi?id=23182
1594+
@safe unittest
1595+
{
1596+
static struct HasOpAssign
1597+
{
1598+
void opAssign(HasOpAssign rhs) {}
1599+
}
1600+
1601+
static SumType!HasOpAssign test()
1602+
{
1603+
SumType!HasOpAssign s;
1604+
// Test both overloads
1605+
s = HasOpAssign();
1606+
s = SumType!HasOpAssign();
1607+
return s;
1608+
}
1609+
1610+
// Force CTFE
1611+
enum result = test();
1612+
}
1613+
15721614
/// True if `T` is an instance of the `SumType` template, otherwise false.
15731615
private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);
15741616

0 commit comments

Comments
 (0)