From 8cd44a9ca30d8041eec2b56ec1c1bf0fdfe6a2aa Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 18 Dec 2023 11:42:57 +0000 Subject: [PATCH] Fix Issue 24285 - Cannot swap a std.typecons.Tuple --- std/algorithm/mutation.d | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/std/algorithm/mutation.d b/std/algorithm/mutation.d index 61b6a5e4eff..0c31b6ba43e 100644 --- a/std/algorithm/mutation.d +++ b/std/algorithm/mutation.d @@ -2831,6 +2831,16 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs)))) { if (&lhs != &rhs) { + static if (__traits(compiles, lhs.tupleof = rhs.tupleof)) + { + if (__ctfe) + { + // can't reinterpret cast + foreach (i, ref e; lhs.tupleof) + swap(e, rhs.tupleof[i]); + return; + } + } // For structs with non-trivial assignment, move memory directly ubyte[T.sizeof] t = void; auto a = (cast(ubyte*) &lhs)[0 .. T.sizeof]; @@ -3074,6 +3084,18 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs)))) swap(a3, a4); } +// https://issues.dlang.org/show_bug.cgi?id=21429 +@safe unittest +{ + enum e = (){ + Tuple!int a = 5, b = 6; + swap(a, b); + assert(a[0] == 6); + assert(b[0] == 5); + return 0; + }(); +} + /// ditto void swap(T)(ref T lhs, ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))