File tree Expand file tree Collapse file tree 2 files changed +45
-11
lines changed
Expand file tree Collapse file tree 2 files changed +45
-11
lines changed Original file line number Diff line number Diff line change @@ -2885,6 +2885,17 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
28852885 {
28862886 if (&lhs != &rhs)
28872887 {
2888+ static if (__traits(compiles, lhs.tupleof = rhs.tupleof))
2889+ {
2890+ if (__ctfe)
2891+ {
2892+ // can't reinterpret cast
2893+ foreach (i, ref e; lhs.tupleof)
2894+ swap(e, rhs.tupleof[i]);
2895+ return ;
2896+ }
2897+ }
2898+
28882899 // For structs with non-trivial assignment, move memory directly
28892900 ubyte [T.sizeof] t = void ;
28902901 auto a = (cast (ubyte * ) &lhs)[0 .. T.sizeof];
@@ -3128,6 +3139,18 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
31283139 swap(a3, a4);
31293140}
31303141
3142+ // https://issues.dlang.org/show_bug.cgi?id=21429
3143+ @safe unittest
3144+ {
3145+ enum e = (){
3146+ Tuple ! int a = 5 , b = 6 ;
3147+ swap(a, b);
3148+ assert (a[0 ] == 6 );
3149+ assert (b[0 ] == 5 );
3150+ return 0 ;
3151+ }();
3152+ }
3153+
31313154/**
31323155Swaps two elements in-place of a range `r`,
31333156specified by their indices `i1` and `i2`.
Original file line number Diff line number Diff line change @@ -980,24 +980,35 @@ if (distinctFieldNames!(Specs))
980980 {
981981 import std.algorithm.mutation : swap;
982982
983- static if (is (R == Tuple ! Types) && ! __traits(isRef, rhs) && isTuple! R)
983+ /*
984+ This optimization caused compilation failures with no error message available:
985+
986+ > Error: unknown, please file report on issues.dlang.org
987+ > std/sumtype.d(1262): Error: template instance `std.sumtype.SumType!(Flag, Tuple!(This*))` error instantiating
988+ */
989+ version (none )
984990 {
985- if (__ctfe )
991+ static if (is (R == Tuple ! Types) && ! __traits(isRef, rhs) && isTuple ! R )
986992 {
987- // Cannot use swap at compile time
988- field[] = rhs.field[];
993+ if (__ctfe)
994+ {
995+ // Cannot use swap at compile time
996+ field[] = rhs.field[];
997+ }
998+ else
999+ {
1000+ // Use swap-and-destroy to optimize rvalue assignment
1001+ swap! (Tuple ! Types)(this , rhs);
1002+ }
9891003 }
9901004 else
9911005 {
992- // Use swap-and-destroy to optimize rvalue assignment
993- swap ! ( Tuple ! Types)( this , rhs) ;
1006+ // Do not swap; opAssign should be called on the fields.
1007+ field[] = rhs.field[] ;
9941008 }
9951009 }
996- else
997- {
998- // Do not swap; opAssign should be called on the fields.
999- field[] = rhs.field[];
1000- }
1010+
1011+ field[] = rhs.field[];
10011012 return this ;
10021013 }
10031014
You can’t perform that action at this time.
0 commit comments