From 2de6f8da22615e97e016a0e7aecb39f6d5e322d0 Mon Sep 17 00:00:00 2001 From: Steven Schveighoffer Date: Mon, 4 Jun 2018 10:52:01 -0400 Subject: [PATCH] Fix issue 18934 - make std.variant support getting types that have const members. --- std/variant.d | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/std/variant.d b/std/variant.d index 392fcb45a..0819a0eee 100644 --- a/std/variant.d +++ b/std/variant.d @@ -299,7 +299,14 @@ private: if (targetType != typeid(T)) continue; - static if (is(typeof(*cast(T*) target = *src)) || + // SPECIAL NOTE: variant only will ever create a new value with + // tryPutting (effectively), and T is ALWAYS the same type of + // A, but with different modifiers (and a limited set of + // implicit targets). So this checks to see if we can construct + // a T from A, knowing that prerequisite. This handles issues + // where the type contains some constant data aside from the + // modifiers on the type itself. + static if (is(typeof(delegate T() {return *src;})) || is(T == const(U), U) || is(T == shared(U), U) || is(T == shared const(U), U) || @@ -3003,3 +3010,21 @@ if (isAlgebraic!VariantType && Handler.length > 0) static struct Foo15827 { Variant v; this(Foo15827 v) {} } Variant v = Foo15827.init; } + +@system unittest +{ + // Bugzilla 18934 + static struct S + { + const int x; + } + + auto s = S(42); + Variant v = s; + auto s2 = v.get!S; + assert(s2.x == 42); + Variant v2 = v; // support copying from one variant to the other + v2 = S(2); + v = v2; + assert(v.get!S.x == 2); +}