Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions src/sumtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -499,26 +499,27 @@ public:
/**
* Assigns a value to a `SumType`.
*
* Assigning to a `SumType` is `@system` if any of the
* `SumType`'s members contain pointers or references, since
* those members may be reachable through external references,
* and overwriting them could therefore lead to memory
* corruption.
* Assigning to a `SumType` is `@system` if any of the `SumType`'s
* $(I other) members contain pointers or references, since those
* members may be reachable through external references, and
* overwriting them could therefore lead to memory corruption.
*
* An individual assignment can be `@trusted` if the caller can
* guarantee that there are no outstanding references to $(I any)
* of the `SumType`'s members when the assignment occurs.
* guarantee that, when the assignment occurs, there are no
* outstanding references to any such members.
*/
ref SumType opAssign(T rhs)
{
import core.lifetime: forward;
import std.traits: hasIndirections, hasNested;
import std.meta: Or = templateOr;
import std.meta: AliasSeq, Or = templateOr;

enum mayContainPointers =
anySatisfy!(Or!(hasIndirections, hasNested), Types);
alias OtherTypes =
AliasSeq!(Types[0 .. tid], Types[tid + 1 .. $]);
enum unsafeToOverwrite =
anySatisfy!(Or!(hasIndirections, hasNested), OtherTypes);

static if (mayContainPointers) {
static if (unsafeToOverwrite) {
cast(void) () @system {}();
}

Expand Down Expand Up @@ -1388,6 +1389,15 @@ version (D_BetterC) {} else
assert(x.typeIndex == y.typeIndex);
}

// @safe assignment to the only pointer in a SumType
@safe unittest {
SumType!(string, int) sm = 123;

assert(__traits(compiles, () @safe {
sm = "this should be @safe";
}));
}

/// True if `T` is an instance of the `SumType` template, otherwise false.
private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);

Expand Down