From 4d01cacfb428001ea17942b23fcddd40b0c264b8 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Sat, 29 Aug 2020 00:50:38 +0900 Subject: [PATCH] Fix 21210: std.traits : isAssignable false positive on disabled copy struct `isAssignable` would previously return `true` for non-copyable types, even though code that tried to use an lvalue would not compile. This behavior was originally found when implementing `-preview=in`. With the new -preview=in check, the const-folding seemed to be a bit too aggressive when an rvalue is passed, meaning that the check might fail (probably due to the code that initialize the temporary). --- std/traits.d | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/std/traits.d b/std/traits.d index 11e160ce75a..3a1594d8dd1 100644 --- a/std/traits.d +++ b/std/traits.d @@ -5180,10 +5180,10 @@ enum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) && isLvalueAss } // ditto -private enum isRvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs); +private enum isRvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = rvalueOf!Rhs; }); // ditto -private enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs); +private enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = lvalueOf!Rhs; }); @safe unittest { @@ -5224,6 +5224,9 @@ private enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, lvalueOf!Lh static assert(!isRvalueAssignable!(S6, S5)); static assert( isLvalueAssignable!(S6, S5)); static assert( isLvalueAssignable!(S6, immutable S5)); + + // https://issues.dlang.org/show_bug.cgi?id=21210 + static assert(!isAssignable!S5); }