@@ -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.
15731615private enum bool isSumTypeInstance(T) = is (T == SumType! Args, Args... );
15741616
0 commit comments