Issue 10194. Variant does not call struct destructors.

This commit is contained in:
uran 2014-05-06 13:06:31 +03:00
parent 24fffa6ecc
commit 0c40d1ea64

View file

@ -187,7 +187,7 @@ private:
// the "handler" function below.
enum OpID { getTypeInfo, get, compare, equals, testConversion, toString,
index, indexAssign, catAssign, copyOut, length,
apply }
apply, destruct }
// state
ptrdiff_t function(OpID selector, ubyte[size]* store, void* data) fptr
@ -224,6 +224,8 @@ private:
string * target = cast(string*) parm;
*target = "<Uninitialized VariantN>";
break;
case OpID.destruct:
break;
case OpID.get:
case OpID.testConversion:
case OpID.index:
@ -544,6 +546,13 @@ private:
}
break;
case OpID.destruct:
static if (hasElaborateDestructor!A)
{
typeid(A).destroy(zis);
}
break;
default: assert(false);
}
return 0;
@ -561,6 +570,11 @@ public:
opAssign(value);
}
~this()
{
fptr(OpID.destruct, &store, null);
}
/** Assigns a $(D_PARAM VariantN) from a generic
* argument. Statically rejects disallowed types. */
@ -570,6 +584,9 @@ public:
static assert(allowed!(T), "Cannot store a " ~ T.stringof
~ " in a " ~ VariantN.stringof ~ ". Valid types are "
~ AllowedTypes.stringof);
// Assignment should destruct previous value
fptr(OpID.destruct, &store, null);
static if (is(T : VariantN))
{
rhs.fptr(OpID.copyOut, &rhs.store, &this);
@ -2239,3 +2256,32 @@ unittest
}
}
}
unittest
{
// https://issues.dlang.org/show_bug.cgi?id=10194
static struct S
{
~this()
{
++cnt;
}
static size_t cnt;
}
Variant v;
// assigning a new value should destroy the existing one
{
v = S();
immutable n = S.cnt;
v = 0;
assert(S.cnt == n + 1);
}
// destroying the variant should destroy it's current value
{
v = S();
immutable n = S.cnt;
destroy(v);
assert(S.cnt == n + 1);
}
}