From 011c27165edf655e8f9c2ba54064b509eefd84b5 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 18 Apr 2025 13:29:13 +0100 Subject: [PATCH] Fix wrong 'not an lvalue' error when assigning to sequence (#21260) Fixes #21259. --- compiler/src/dmd/expressionsem.d | 8 +++- compiler/test/fail_compilation/seq_assign.d | 43 +++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 compiler/test/fail_compilation/seq_assign.d diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 8ea9262998..a638985464 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -10579,7 +10579,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { TupleDeclaration td = isAliasThisTuple(e2x); if (!td) - goto Lnomatch; + { + Lnomatch: + error(exp.loc, "cannot assign `%s` to expression sequence `%s`", + exp.e2.type.toChars(), exp.e1.type.toChars()); + return setError(); + } assert(exp.e1.type.ty == Ttuple); TypeTuple tt = cast(TypeTuple)exp.e1.type; @@ -10621,7 +10626,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // Do not need to overwrite this.e2 goto Ltupleassign; } - Lnomatch: } /* Inside constructor, if this is the first assignment of object field, diff --git a/compiler/test/fail_compilation/seq_assign.d b/compiler/test/fail_compilation/seq_assign.d new file mode 100644 index 0000000000..560bc34424 --- /dev/null +++ b/compiler/test/fail_compilation/seq_assign.d @@ -0,0 +1,43 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/seq_assign.d(28): Error: cannot assign `int` to expression sequence `(int)` +fail_compilation/seq_assign.d(29): Error: cannot implicitly convert expression `s` of type `string` to `int` +fail_compilation/seq_assign.d(30): Error: cannot modify constant `2` +fail_compilation/seq_assign.d(31): Error: mismatched sequence lengths, 1 and 2 +fail_compilation/seq_assign.d(35): Error: mismatched sequence lengths, 1 and 2 +fail_compilation/seq_assign.d(36): Error: cannot implicitly convert expression `__t_field_0` of type `string` to `int` +fail_compilation/seq_assign.d(40): Error: cannot assign `IntString` to expression sequence `(string, int)` +fail_compilation/seq_assign.d(42): Error: cannot implicitly convert expression `AliasSeq!(b, c)` of type `(int, int)` to `IntString` +--- +*/ + +alias Seq(A...) = A; + +struct IntString +{ + Seq!(int, string) expand; + alias this = expand; +} + +void main() +{ + int b, c; + string s; + + Seq!(b,) = 1; // RHS not seq + Seq!(b,) = Seq!(s,); // b type error + Seq!(2,) = Seq!(1,); // not lvalue + Seq!(b,) = Seq!(1, 2); // too many + + auto t = Seq!("two", 3); + Seq!(s, b) = t; // OK + Seq!(b,) = t; // too many + Seq!(b, c) = t; // b type error + + IntString t2; + Seq!(b, s) = t2; // OK + t = t2; // type mismatch + t2 = Seq!(b, s); // OK + t2 = Seq!(b, c); // c wrong type +}