Skip to content

Commit

Permalink
Fix Bugzilla 15315 - can break immutable with std.algorithm.move (#9032)
Browse files Browse the repository at this point in the history
  • Loading branch information
ntrel authored Jul 28, 2024
1 parent 7a14c89 commit 9ffe71f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
23 changes: 23 additions & 0 deletions std/algorithm/mutation.d
Original file line number Diff line number Diff line change
Expand Up @@ -1071,10 +1071,20 @@ Params:
copy is performed.
*/
void move(T)(ref T source, ref T target)
if (__traits(compiles, target = T.init))
{
moveImpl(target, source);
}

/// ditto
template move(T)
if (!__traits(compiles, imported!"std.traits".lvalueOf!T = T.init))
{
///
deprecated("Can't move into `target` as `" ~ T.stringof ~ "` can't be assigned")
void move(ref T source, ref T target) => moveImpl(target, source);
}

/// For non-struct types, `move` just performs `target = source`:
@safe unittest
{
Expand Down Expand Up @@ -1184,6 +1194,19 @@ pure nothrow @safe @nogc unittest
assert(s53 is s51);
}

@system unittest
{
static struct S
{
immutable int i;
~this() @safe {}
}
alias ol = __traits(getOverloads, std.algorithm.mutation, "move", true)[1];
static assert(__traits(isDeprecated, ol!S));
// uncomment after deprecation
//static assert(!__traits(compiles, { S a, b; move(a, b); }));
}

/// Ditto
T move(T)(return scope ref T source)
{
Expand Down
23 changes: 13 additions & 10 deletions std/typecons.d
Original file line number Diff line number Diff line change
Expand Up @@ -10928,19 +10928,22 @@ struct RefCounted(T, RefCountedAutoInitialize autoInit =
swap(_refCounted._store, rhs._refCounted._store);
}

void opAssign(T rhs)
static if (__traits(compiles, lvalueOf!T = T.init))
{
import std.algorithm.mutation : move;

static if (autoInit == RefCountedAutoInitialize.yes)
{
_refCounted.ensureInitialized();
}
else
void opAssign(T rhs)
{
assert(_refCounted.isInitialized);
import std.algorithm.mutation : move;

static if (autoInit == RefCountedAutoInitialize.yes)
{
_refCounted.ensureInitialized();
}
else
{
assert(_refCounted.isInitialized);
}
move(rhs, _refCounted._store._payload);
}
move(rhs, _refCounted._store._payload);
}

static if (autoInit == RefCountedAutoInitialize.yes)
Expand Down

0 comments on commit 9ffe71f

Please sign in to comment.