Fix Bugzilla 15315 - can break immutable with std.algorithm.move (#9032)

This commit is contained in:
Nick Treleaven 2024-07-28 23:49:54 +01:00 committed by GitHub
parent 7a14c896dd
commit 9ffe71fea3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 10 deletions

View file

@ -1071,10 +1071,20 @@ Params:
copy is performed. copy is performed.
*/ */
void move(T)(ref T source, ref T target) void move(T)(ref T source, ref T target)
if (__traits(compiles, target = T.init))
{ {
moveImpl(target, source); 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`: /// For non-struct types, `move` just performs `target = source`:
@safe unittest @safe unittest
{ {
@ -1184,6 +1194,19 @@ pure nothrow @safe @nogc unittest
assert(s53 is s51); 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 /// Ditto
T move(T)(return scope ref T source) T move(T)(return scope ref T source)
{ {

View file

@ -10928,6 +10928,8 @@ struct RefCounted(T, RefCountedAutoInitialize autoInit =
swap(_refCounted._store, rhs._refCounted._store); swap(_refCounted._store, rhs._refCounted._store);
} }
static if (__traits(compiles, lvalueOf!T = T.init))
{
void opAssign(T rhs) void opAssign(T rhs)
{ {
import std.algorithm.mutation : move; import std.algorithm.mutation : move;
@ -10942,6 +10944,7 @@ struct RefCounted(T, RefCountedAutoInitialize autoInit =
} }
move(rhs, _refCounted._store._payload); move(rhs, _refCounted._store._payload);
} }
}
static if (autoInit == RefCountedAutoInitialize.yes) static if (autoInit == RefCountedAutoInitialize.yes)
{ {