Bug 18594 – X is not an lvalue should have a better error message
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-03-11T21:59:25Z
Last change time
2023-05-09T15:05:51Z
Assigned to
No Owner
Creator
Seb
Comments
Comment #0 by greensunny12 — 2018-03-11T21:59:25Z
---
void main() {
assert(1 = 2);
}
---
currently errors with "foo.d(2): Error: constant 1 is not an lvalue".
The error message should be better: (1) not mention lvalue and (2) suggesting `==`.
Comment #1 by greensunny12 — 2018-03-11T21:59:43Z
(PR incoming)
Comment #2 by greensunny12 — 2018-03-12T06:00:57Z
Hmm, just modifying the error message isn't enough. We should probably look up in the tree to check whether we are in if expression, assert, ...
diff --git a/src/dmd/expression.d b/src/dmd/expression.d
index d93c1ffda..997423b85 100644
--- a/src/dmd/expression.d
+++ b/src/dmd/expression.d
@@ -1855,7 +1855,7 @@ extern (C++) abstract class Expression : RootObject
}
}
}
- error("cannot modify `%s` expression `%s`. Did you mean `==`?", MODtoChars(type.mod), toChars());
+ error("cannot modify `%s` expression `%s`", MODtoChars(type.mod), toChars());
return new ErrorExp();
}
else if (!type.isAssignable())
@@ -2604,7 +2604,7 @@ extern (C++) final class IntegerExp : Expression
e = this;
else if (!loc.isValid())
loc = e.loc;
- e.error("constant `%s` is not an lvalue. Did you mean `==`?", e.toChars());
+ e.error("constant `%s` is not an lvalue", e.toChars());
return new ErrorExp();
}
diff --git a/test/fail_compilation/test18594.d b/test/fail_compilation/test18594.d
deleted file mode 100644
index 631df3033..000000000
--- a/test/fail_compilation/test18594.d
+++ /dev/null
@@ -1,11 +0,0 @@
-/*TEST_OUTPUT:
----
-fail_compilation/test18594.d(8): Error: constant `1` is not an lvalue. Did you mean `==`?
-fail_compilation/test18594.d(10): Error: cannot modify `const` expression `a`. Did you mean `==`?
----
-*/
-void main() {
- assert(1 = 2);
- const a = 1;
- assert(a = 2);
-}
---
struct Test(T) {
@property ref T get() inout { return member; }
private:
T member;
}
int main(string[] args)
{
Test!int t;
t.get = 12;
return t.get;
}
---
This code has an very similar issue:
> test.d(3): Error: cast(int)this.member is not an lvalue and cannot be modified
The correct definition is:
---
struct Test(T) {
@property ref inout(T) get() inout { return member; }
private:
T member;
}
---
but the error message gives no hint in that direction. It confused me quite a bit, since IMO member is a fine lvalue that happens to be const/inout.
https://run.dlang.io/is/IJKZ80
Comment #6 by duser — 2022-02-22T18:14:48Z
the same error message is given when taking the address of a non-lvalue, but "cannot be modified" doesn't necessarily apply there (and can be confusing)
// Error: `a[0..2]` is not an lvalue and cannot be modified
ubyte[2] a;
const void* p1 = &a[0..2];
// Error: cannot modify constant `1`
const void* p2 = &1;
for these, the message should rather say something like "cannot have its address taken"
Comment #7 by razvan.nitu1305 — 2023-05-09T15:05:51Z