diff --git a/src/core/atomic.d b/src/core/atomic.d index 512cf6563a..60f5601d66 100644 --- a/src/core/atomic.d +++ b/src/core/atomic.d @@ -110,13 +110,23 @@ TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref shared const T * newval = The value to store. */ void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val, V newval) pure nothrow @nogc @trusted - if (!is(T == shared) && !is(V == shared)) + if (!is(T == shared) && !is(V == shared) && is(T : V)) { import core.internal.traits : hasElaborateCopyConstructor; static assert (!hasElaborateCopyConstructor!T, "`T` may not have an elaborate copy: atomic operations override regular copying semantics."); // resolve implicit conversions - T arg = newval; + import core.internal.traits : Unqual; + static if (is(Unqual!T == Unqual!V)) + { + alias arg = newval; + } + else + { + // don't construct directly from `newval`, assign instead (`alias this` etc.) + T arg; + arg = newval; + } static if (__traits(isFloating, T)) { @@ -1194,4 +1204,16 @@ version (CoreUnittest) shared NoIndirections n; static assert(is(typeof(atomicLoad(n)) == NoIndirections)); } + + unittest + { + static struct S + { + int a; + alias a this; + } + + S s; + atomicStore(s, 123); + } }