diff --git a/src/dmd/expression.d b/src/dmd/expression.d index e65fe5c950fc..6db688935911 100644 --- a/src/dmd/expression.d +++ b/src/dmd/expression.d @@ -5197,19 +5197,6 @@ extern (C++) final class CastExp : UnaExp return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy()) : new CastExp(loc, e1.syntaxCopy(), mod); } - override bool isLvalue() - { - //printf("e1.type = %s, to.type = %s\n", e1.type.toChars(), to.toChars()); - return e1.isLvalue() && e1.type.mutableOf().unSharedOf().equals(to.mutableOf().unSharedOf()); - } - - override Expression toLvalue(Scope* sc, Expression e) - { - if (isLvalue()) - return this; - return Expression.toLvalue(sc, e); - } - override Expression addDtorHook(Scope* sc) { if (to.toBasetype().ty == Tvoid) // look past the cast(void) diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index 4ee70761c235..57319dcc086f 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -8748,17 +8748,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // Try to do a decent error message with the expression // before it got constant folded - // https://issues.dlang.org/show_bug.cgi?id=19754 - // first see if the unoptimized expression is modifiable + if (e1x.op != TOK.variable) + e1x = e1x.optimize(WANTvalue); + if (exp.op == TOK.assign) e1x = e1x.modifiableLvalue(sc, e1old); if (checkIfIsStructLiteralDotExpr(e1x)) return setError(); - if (e1x.op != TOK.variable) - e1x = e1x.optimize(WANTvalue); - if (e1x.op == TOK.error) { result = e1x; diff --git a/src/dmd/semantic3.d b/src/dmd/semantic3.d index e5cc55c28d57..07421d8f3b80 100644 --- a/src/dmd/semantic3.d +++ b/src/dmd/semantic3.d @@ -841,13 +841,7 @@ private extern(C++) final class Semantic3Visitor : Visitor const hasCopyCtor = exp.type.ty == Tstruct && (cast(TypeStruct)exp.type).sym.hasCopyCtor; // if a copy constructor is present, the return type conversion will be handled by it if (!hasCopyCtor) - { - if (f.isref && !MODimplicitConv(exp.type.mod, tret.mod) && !tret.isTypeSArray()) - error(exp.loc, "expression `%s` of type `%s` is not implicitly convertible to return type `ref %s`", - exp.toChars(), exp.type.toChars(), tret.toChars()); - else - exp = exp.implicitCastTo(sc2, tret); - } + exp = exp.implicitCastTo(sc2, tret); if (f.isref) { diff --git a/src/dmd/typesem.d b/src/dmd/typesem.d index 6221f1173885..02c0eeb56390 100644 --- a/src/dmd/typesem.d +++ b/src/dmd/typesem.d @@ -1377,13 +1377,6 @@ extern(C++) Type typeSemantic(Type t, Loc loc, Scope* sc) e = new AddrExp(e.loc, e); e = e.expressionSemantic(argsc); } - if (isRefOrOut && (!isAuto || e.isLvalue()) - && !MODimplicitConv(e.type.mod, fparam.type.mod)) - { - const(char)* errTxt = fparam.storageClass & STC.ref_ ? "ref" : "out"; - .error(e.loc, "expression `%s` of type `%s` is not implicitly convertible to type `%s %s` of parameter `%s`", - e.toChars(), e.type.toChars(), errTxt, fparam.type.toChars(), fparam.toChars()); - } e = e.implicitCastTo(argsc, fparam.type); // default arg must be an lvalue diff --git a/test/compilable/test19754.d b/test/compilable/test19754.d deleted file mode 100644 index 3661406bed8d..000000000000 --- a/test/compilable/test19754.d +++ /dev/null @@ -1,11 +0,0 @@ -void main() -{ - shared int x; - (cast() x) = 5; - - const int x1; - (cast() x1) = 5; - - immutable int x2; - (cast() x2) = 5; -} diff --git a/test/fail_compilation/b20011.d b/test/fail_compilation/b20011.d index 800b577be699..fc9d4e3033a7 100644 --- a/test/fail_compilation/b20011.d +++ b/test/fail_compilation/b20011.d @@ -1,8 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/b20011.d(22): Error: cannot modify constant expression `S1(cast(ubyte)0u).member` -fail_compilation/b20011.d(25): Error: cannot modify constant expression `S2(null).member` +fail_compilation/b20011.d(22): Error: cannot modify constant `S1(cast(ubyte)0u).member` +fail_compilation/b20011.d(24): Error: `S2(null).member` is not an lvalue and cannot be modified fail_compilation/b20011.d(26): Error: cannot modify constant expression `S2(null).member` fail_compilation/b20011.d(27): Error: cannot modify constant expression `S2(null).member` fail_compilation/b20011.d(30): Error: cannot modify constant expression `U1(cast(ubyte)0u, ).m2` diff --git a/test/fail_compilation/diag4596.d b/test/fail_compilation/diag4596.d index c9e4771cb721..0d9350f3c86d 100644 --- a/test/fail_compilation/diag4596.d +++ b/test/fail_compilation/diag4596.d @@ -1,12 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/diag4596.d(17): Error: `this` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(18): Error: `this` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(18): Error: `this` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(20): Error: `super` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(21): Error: `super` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(21): Error: `super` is not an lvalue and cannot be modified +fail_compilation/diag4596.d(15): Error: `this` is not an lvalue and cannot be modified +fail_compilation/diag4596.d(16): Error: `1 ? this : this` is not an lvalue and cannot be modified +fail_compilation/diag4596.d(18): Error: `super` is not an lvalue and cannot be modified +fail_compilation/diag4596.d(19): Error: `1 ? super : super` is not an lvalue and cannot be modified --- */ diff --git a/test/fail_compilation/fail106.d b/test/fail_compilation/fail106.d index ba9f7dd69cde..602423ef53f2 100644 --- a/test/fail_compilation/fail106.d +++ b/test/fail_compilation/fail106.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail106.d(12): Error: cannot modify `immutable` expression `"ABC"[2]` +fail_compilation/fail106.d(12): Error: cannot modify `immutable` expression `'C'` --- */ diff --git a/test/fail_compilation/fail17491.d b/test/fail_compilation/fail17491.d index 87950c87c738..3a103058825f 100644 --- a/test/fail_compilation/fail17491.d +++ b/test/fail_compilation/fail17491.d @@ -1,11 +1,13 @@ /* TEST_OUTPUT: --- -fail_compilation/fail17491.d(20): Error: `(S17491).init` is not an lvalue and cannot be modified -fail_compilation/fail17491.d(21): Error: `S17491(0)` is not an lvalue and cannot be modified -fail_compilation/fail17491.d(23): Error: cannot modify constant expression `S17491(0).field` -fail_compilation/fail17491.d(29): Error: `S17491(0)` is not an lvalue and cannot be modified -fail_compilation/fail17491.d(30): Error: `S17491(0)` is not an lvalue and cannot be modified -fail_compilation/fail17491.d(32): Error: cannot modify constant expression `S17491(0).field` +fail_compilation/fail17491.d(22): Error: `(S17491).init` is not an lvalue and cannot be modified +fail_compilation/fail17491.d(23): Error: `S17491(0)` is not an lvalue and cannot be modified +fail_compilation/fail17491.d(25): Error: cannot modify constant `S17491(0).field` +fail_compilation/fail17491.d(26): Error: cannot modify constant `*&S17491(0).field` +fail_compilation/fail17491.d(31): Error: `S17491(0)` is not an lvalue and cannot be modified +fail_compilation/fail17491.d(32): Error: `S17491(0)` is not an lvalue and cannot be modified +fail_compilation/fail17491.d(34): Error: cannot modify constant `S17491(0).field` +fail_compilation/fail17491.d(35): Error: cannot modify constant `*&S17491(0).field` --- */ // https://issues.dlang.org/show_bug.cgi?id=17491 diff --git a/test/fail_compilation/fail351.d b/test/fail_compilation/fail351.d index b11d15f0380a..770f20659f94 100644 --- a/test/fail_compilation/fail351.d +++ b/test/fail_compilation/fail351.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail351.d(14): Error: expression `this.num[index]` of type `immutable(uint)` is not implicitly convertible to return type `ref uint` +fail_compilation/fail351.d(14): Error: `cast(uint)this.num[index]` is not an lvalue and cannot be modified --- */ diff --git a/test/fail_compilation/fail9891.d b/test/fail_compilation/fail9891.d index 791e734349f4..d9fc487e1151 100644 --- a/test/fail_compilation/fail9891.d +++ b/test/fail_compilation/fail9891.d @@ -1,8 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail9891.d(13): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `ref int` of parameter `n` -fail_compilation/fail9891.d(18): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `out int` of parameter `n` +fail_compilation/fail9891.d(13): Error: `cast(int)i` is not an lvalue and cannot be modified +fail_compilation/fail9891.d(18): Error: `cast(int)i` is not an lvalue and cannot be modified fail_compilation/fail9891.d(23): Error: `prop()` is not an lvalue and cannot be modified --- */ diff --git a/test/compilable/test14929.d b/test/fail_compilation/ice14929.d similarity index 68% rename from test/compilable/test14929.d rename to test/fail_compilation/ice14929.d index 1b794a66248e..349e328095e8 100644 --- a/test/compilable/test14929.d +++ b/test/fail_compilation/ice14929.d @@ -1,3 +1,14 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/ice14929.d(45): Error: `cast(Node)(*this.current).items[this.index]` is not an lvalue and cannot be modified +fail_compilation/ice14929.d(88): Error: template instance `ice14929.HashMap!(ulong, int).HashMap.opBinaryRight!"in"` error instantiating +fail_compilation/ice14929.d(92): instantiated from here: `HashmapComponentStorage!int` +fail_compilation/ice14929.d(92): Error: template instance `ice14929.isComponentStorage!(HashmapComponentStorage!int, int)` error instantiating +fail_compilation/ice14929.d(92): while evaluating: `static assert(isComponentStorage!(HashmapComponentStorage!int, int))` +--- +*/ + struct HashMap(K, V) { V* opBinaryRight(string op)(K key) const if (op == "in") diff --git a/test/fail_compilation/test12385.d b/test/fail_compilation/test12385.d index cbba723fe749..9660c39f11f3 100644 --- a/test/fail_compilation/test12385.d +++ b/test/fail_compilation/test12385.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/test12385.d(29): Error: cannot modify `immutable` expression `unbundled.x` +fail_compilation/test12385.d(29): Error: cannot modify `immutable` expression `BundledState("bla", 3).x` --- */