diff --git a/source/taggedalgebraic.d b/source/taggedalgebraic.d index ef8738f..cd27433 100644 --- a/source/taggedalgebraic.d +++ b/source/taggedalgebraic.d @@ -88,14 +88,12 @@ struct TaggedAlgebraic(U) if (is(U == union) || is(U == struct)) this(TaggedAlgebraic other) { - import std.algorithm : swap; - swap(this, other); + rawSwap(this, other); } void opAssign(TaggedAlgebraic other) { - import std.algorithm : swap; - swap(this, other); + rawSwap(this, other); } // postblit constructor @@ -1298,3 +1296,17 @@ private void rawEmplace(T)(void[] dst, ref T src) tdst[0] = src; } } + +// std.algorithm.mutation.swap sometimes fails to compile due to +// internal errors in hasElaborateAssign!T/isAssignable!T. This is probably +// caused by cyclic dependencies. However, there is no reason to do these +// checks in this context, so we just directly move the raw memory. +private void rawSwap(T)(ref T a, ref T b) +@trusted { + void[T.sizeof] tmp = void; + void[] ab = (cast(void*)&a)[0 .. T.sizeof]; + void[] bb = (cast(void*)&b)[0 .. T.sizeof]; + tmp[] = ab[]; + ab[] = bb[]; + bb[] = tmp[]; +}