From 953198a293daca33a5591ce2d26bd444f2b1eb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 23 Feb 2019 21:49:08 +0100 Subject: [PATCH] Fix using non-copyable types with TaggedUnion. --- source/taggedalgebraic/taggedunion.d | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/source/taggedalgebraic/taggedunion.d b/source/taggedalgebraic/taggedunion.d index b302e10..0eb6181 100644 --- a/source/taggedalgebraic/taggedunion.d +++ b/source/taggedalgebraic/taggedunion.d @@ -76,12 +76,12 @@ struct TaggedUnion(U) if (is(U == union) || is(U == struct) || is(U == enum)) static if (!isUnitType!(FieldTypes[ti])) { this(FieldTypes[ti] value) { - set!(cast(Kind)ti)(value); + set!(cast(Kind)ti)(move(value)); } void opAssign(FieldTypes[ti] value) { - set!(cast(Kind)ti)(value); + set!(cast(Kind)ti)(move(value)); } } @@ -394,6 +394,21 @@ unittest { // test woraround for Phobos issue 19696 static assert(is(TU.FieldTypes[0] == T)); } +unittest { // non-copyable types + import std.traits : isCopyable; + + struct S { @disable this(this); } + struct U { + int i; + S s; + } + alias TU = TaggedUnion!U; + static assert(!isCopyable!TU); + + auto tu = TU(42); + tu.setS(S.init); +} + /** Dispatches the value contained on a `TaggedUnion` to a set of visitors. @@ -741,7 +756,7 @@ package void rawEmplace(T)(void[] dst, ref T src) } else { import std.conv : emplace; emplace!T(&tdst[0]); - tdst[0] = src; + rawSwap(tdst[0], src); } }