Skip to content

Commit

Permalink
Merge pull request #2418 from 9rnsr/fix13284
Browse files Browse the repository at this point in the history
[REG2.066a] Issue 13284 - Cannot match shared classes at receive
  • Loading branch information
complexmath authored and 9rnsr committed Aug 13, 2014
1 parent f670ad8 commit af2bd8b
Showing 1 changed file with 157 additions and 64 deletions.
221 changes: 157 additions & 64 deletions std/variant.d
Expand Up @@ -297,14 +297,26 @@ private:
alias UA = Unqual!A;
alias MutaTypes = TypeTuple!(UA, ImplicitConversionTargets!UA);
alias ConstTypes = staticMap!(ConstOf, MutaTypes);
alias SharedTypes = staticMap!(SharedOf, MutaTypes);
alias SharedConstTypes = staticMap!(SharedConstOf, MutaTypes);
alias ImmuTypes = staticMap!(ImmutableOf, MutaTypes);

static if (is(A == immutable))
alias AllTypes = TypeTuple!(ImmuTypes, ConstTypes);
else static if (is(A == const))
alias AllTypes = ConstTypes;
else //static if (isMutable!A)
alias AllTypes = TypeTuple!(MutaTypes, ConstTypes);
alias AllTypes = TypeTuple!(ImmuTypes, ConstTypes, SharedConstTypes);
else static if (is(A == shared))
{
static if (is(A == const))
alias AllTypes = SharedConstTypes;
else
alias AllTypes = TypeTuple!(SharedTypes, SharedConstTypes);
}
else
{
static if (is(A == const))
alias AllTypes = ConstTypes;
else
alias AllTypes = TypeTuple!(MutaTypes, ConstTypes);
}

foreach (T ; AllTypes)
{
Expand All @@ -322,7 +334,10 @@ private:
*zat = *src;
}
}
else static if (is(T V == const(U), U) || is(T V == immutable(U), U))
else static if (is(T == const(U), U) ||
is(T == shared(U), U) ||
is(T == shared const(U), U) ||
is(T == immutable(U), U))
{
auto zat = cast(U*) target;
if (src)
Expand Down Expand Up @@ -751,7 +766,10 @@ public:
union Buf
{
TypeInfo info;
Unqual!T result;
static if (is(T == shared))
shared(Unqual!T) result;
else
Unqual!T result;
}
auto p = *cast(T**) &store;
Buf buf = { typeid(T) };
Expand Down Expand Up @@ -2164,87 +2182,162 @@ unittest
unittest
{
// http://d.puremagic.com/issues/show_bug.cgi?id=7069
Variant v;

int i = 10;
Variant v = i;
assertNotThrown!VariantException(v.get!(int));
assertNotThrown!VariantException(v.get!(const(int)));
assertThrown!VariantException(v.get!(immutable(int)));
assertNotThrown!VariantException(v.get!(const(float)));
assert(v.get!(const(float)) == 10.0f);
v = i;
foreach (qual; TypeTuple!(MutableOf, ConstOf))
{
assert(v.get!(qual!int) == 10);
assert(v.get!(qual!float) == 10.0f);
}
foreach (qual; TypeTuple!(ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!int));
}

const(int) ci = 20;
v = ci;
assertThrown!VariantException(v.get!(int));
assertNotThrown!VariantException(v.get!(const(int)));
assertThrown!VariantException(v.get!(immutable(int)));
assertNotThrown!VariantException(v.get!(const(float)));
assert(v.get!(const(float)) == 20.0f);
foreach (qual; TypeTuple!(ConstOf))
{
assert(v.get!(qual!int) == 20);
assert(v.get!(qual!float) == 20.0f);
}
foreach (qual; TypeTuple!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!int));
assertThrown!VariantException(v.get!(qual!float));
}

immutable(int) ii = ci;
v = ii;
assertThrown!VariantException(v.get!(int));
assertNotThrown!VariantException(v.get!(const(int)));
assertNotThrown!VariantException(v.get!(immutable(int)));
assertNotThrown!VariantException(v.get!(const(float)));
assertNotThrown!VariantException(v.get!(immutable(float)));
foreach (qual; TypeTuple!(ImmutableOf, ConstOf, SharedConstOf))
{
assert(v.get!(qual!int) == 20);
assert(v.get!(qual!float) == 20.0f);
}
foreach (qual; TypeTuple!(MutableOf, SharedOf))
{
assertThrown!VariantException(v.get!(qual!int));
assertThrown!VariantException(v.get!(qual!float));
}

int[] ai = [1,2,3];
v = ai;
assertNotThrown!VariantException(v.get!(int[]));
assertNotThrown!VariantException(v.get!(const(int[])));
assertNotThrown!VariantException(v.get!(const(int)[]));
assertThrown!VariantException(v.get!(immutable(int[])));
assertThrown!VariantException(v.get!(immutable(int)[]));
foreach (qual; TypeTuple!(MutableOf, ConstOf))
{
assert(v.get!(qual!(int[])) == [1,2,3]);
assert(v.get!(qual!(int)[]) == [1,2,3]);
}
foreach (qual; TypeTuple!(ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!(int[])));
assertThrown!VariantException(v.get!(qual!(int)[]));
}

const(int[]) cai = [1,2,3];
const(int[]) cai = [4,5,6];
v = cai;
assertThrown!VariantException(v.get!(int[]));
assertNotThrown!VariantException(v.get!(const(int[])));
assertNotThrown!VariantException(v.get!(const(int)[]));
assertThrown!VariantException(v.get!(immutable(int)[]));
assertThrown!VariantException(v.get!(immutable(int[])));
foreach (qual; TypeTuple!(ConstOf))
{
assert(v.get!(qual!(int[])) == [4,5,6]);
assert(v.get!(qual!(int)[]) == [4,5,6]);
}
foreach (qual; TypeTuple!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!(int[])));
assertThrown!VariantException(v.get!(qual!(int)[]));
}

immutable(int[]) iai = [1,2,3];
immutable(int[]) iai = [7,8,9];
v = iai;
assertThrown!VariantException(v.get!(int[]));
assertNotThrown!VariantException(v.get!(immutable(int)[]));
// Bug ??? runtime error
//assertNotThrown!VariantException(v.get!(immutable(int[])));
assertNotThrown!VariantException(v.get!(const(int[])));
assertNotThrown!VariantException(v.get!(const(int)[]));
//assert(v.get!(immutable(int[])) == [7,8,9]); // Bug ??? runtime error
assert(v.get!(immutable(int)[]) == [7,8,9]);
assert(v.get!(const(int[])) == [7,8,9]);
assert(v.get!(const(int)[]) == [7,8,9]);
//assert(v.get!(shared(const(int[]))) == cast(shared const)[7,8,9]); // Bug ??? runtime error
//assert(v.get!(shared(const(int))[]) == cast(shared const)[7,8,9]); // Bug ??? runtime error
foreach (qual; TypeTuple!(MutableOf))
{
assertThrown!VariantException(v.get!(qual!(int[])));
assertThrown!VariantException(v.get!(qual!(int)[]));
}

class A {}
class B :A {}
class B : A {}
B b = new B();
v = b;
assertNotThrown!VariantException(v.get!(B));
assertNotThrown!VariantException(v.get!(const(B)));
assertNotThrown!VariantException(v.get!(A));
assertNotThrown!VariantException(v.get!(const(A)));
assertNotThrown!VariantException(v.get!(Object));
assertNotThrown!VariantException(v.get!(const(Object)));
assertThrown!VariantException(v.get!(immutable(B)));
foreach (qual; TypeTuple!(MutableOf, ConstOf))
{
assert(v.get!(qual!B) is b);
assert(v.get!(qual!A) is b);
assert(v.get!(qual!Object) is b);
}
foreach (qual; TypeTuple!(ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!B));
assertThrown!VariantException(v.get!(qual!A));
assertThrown!VariantException(v.get!(qual!Object));
}

const(B) cb = new B();
v = cb;
assertThrown!VariantException(v.get!(B));
assertNotThrown!VariantException(v.get!(const(B)));
assertThrown!VariantException(v.get!(immutable(B)));
assertThrown!VariantException(v.get!(A));
assertNotThrown!VariantException(v.get!(const(A)));
assertThrown!VariantException(v.get!(Object));
assertNotThrown!VariantException(v.get!(const(Object)));
foreach (qual; TypeTuple!(ConstOf))
{
assert(v.get!(qual!B) is cb);
assert(v.get!(qual!A) is cb);
assert(v.get!(qual!Object) is cb);
}
foreach (qual; TypeTuple!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))
{
assertThrown!VariantException(v.get!(qual!B));
assertThrown!VariantException(v.get!(qual!A));
assertThrown!VariantException(v.get!(qual!Object));
}

immutable(B) ib = new immutable(B)();
v = ib;
assertThrown!VariantException(v.get!(B));
assertNotThrown!VariantException(v.get!(const(B)));
assertNotThrown!VariantException(v.get!(immutable(B)));
assertNotThrown!VariantException(v.get!(const(A)));
assertNotThrown!VariantException(v.get!(immutable(A)));
assertThrown!VariantException(v.get!(Object));
assertNotThrown!VariantException(v.get!(const(Object)));
assertNotThrown!VariantException(v.get!(immutable(Object)));
foreach (qual; TypeTuple!(ImmutableOf, ConstOf, SharedConstOf))
{
assert(v.get!(qual!B) is ib);
assert(v.get!(qual!A) is ib);
assert(v.get!(qual!Object) is ib);
}
foreach (qual; TypeTuple!(MutableOf, SharedOf))
{
assertThrown!VariantException(v.get!(qual!B));
assertThrown!VariantException(v.get!(qual!A));
assertThrown!VariantException(v.get!(qual!Object));
}

shared(B) sb = new shared B();
v = sb;
foreach (qual; TypeTuple!(SharedOf, SharedConstOf))
{
assert(v.get!(qual!B) is sb);
assert(v.get!(qual!A) is sb);
assert(v.get!(qual!Object) is sb);
}
foreach (qual; TypeTuple!(MutableOf, ImmutableOf, ConstOf))
{
assertThrown!VariantException(v.get!(qual!B));
assertThrown!VariantException(v.get!(qual!A));
assertThrown!VariantException(v.get!(qual!Object));
}

shared(const(B)) scb = new shared const B();
v = scb;
foreach (qual; TypeTuple!(SharedConstOf))
{
assert(v.get!(qual!B) is scb);
assert(v.get!(qual!A) is scb);
assert(v.get!(qual!Object) is scb);
}
foreach (qual; TypeTuple!(MutableOf, ConstOf, ImmutableOf, SharedOf))
{
assertThrown!VariantException(v.get!(qual!B));
assertThrown!VariantException(v.get!(qual!A));
assertThrown!VariantException(v.get!(qual!Object));
}
}

unittest
Expand Down

0 comments on commit af2bd8b

Please sign in to comment.