diff --git a/changelog/dmd.error-messages.dd b/changelog/dmd.error-messages.dd index ddb3f6341f0..2d3ce440b10 100644 --- a/changelog/dmd.error-messages.dd +++ b/changelog/dmd.error-messages.dd @@ -53,7 +53,7 @@ app.d(1): perhaps define `auto opSlice(int lower, string upper) {}` for ` */ --- -When overloading binary operators, and `opBinary` or `opBinaryRight` is missing or doesn't match, +When overloading binary operators, and `opBinary`, `opBinaryRight` or `opOpAssign` is missing / fails to instantiate, the error message now points out the problem: --- diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 3b9743e2927..7e9c95b9a9f 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -3819,6 +3819,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // See tryAliasThisSemantic Type[2] aliasThisStop; + // (Optional) the expression this was lowered from, for better error messages + Expression parent; + this(Scope* sc) scope @safe { this.sc = sc; @@ -7583,15 +7586,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true); exp.type = exp.e1.type; - if (auto ad = isAggregate(exp.e1.type)) - { - if (const s = search_function(ad, Id.opOpAssign)) - { - error(exp.loc, "none of the `opOpAssign` overloads of `%s` are callable for `%s` of type `%s`", ad.toChars(), exp.e1.toChars(), exp.e1.type.toChars()); - return setError(); - } - } - if (exp.e1.checkScalar() || + if (exp.suggestOpOpAssign(sc, parent) || + exp.e1.checkScalar() || exp.e1.checkReadModifyWrite(exp.op, exp.e2) || exp.e1.checkSharedAccess(sc)) return setError(); @@ -10233,7 +10229,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e = new AddAssignExp(exp.loc, exp.e1, IntegerExp.literal!1); else e = new MinAssignExp(exp.loc, exp.e1, IntegerExp.literal!1); - result = e.expressionSemantic(sc); + result = e.expressionSemanticWithParent(sc, exp); } /* @@ -11745,7 +11741,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (exp.e1.checkReadModifyWrite(exp.op, exp.e2)) + if (exp.suggestOpOpAssign(sc, parent) || + exp.e1.checkReadModifyWrite(exp.op, exp.e2)) return setError(); assert(exp.e1.type && exp.e2.type); @@ -11824,6 +11821,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (exp.suggestOpOpAssign(sc, parent)) + return setError(); + if (SliceExp se = exp.e1.isSliceExp()) { if (se.e1.type.toBasetype().ty == Tsarray) @@ -13877,6 +13877,20 @@ private Expression expressionSemantic(Expression e, Scope* sc, Type[2] aliasThis return v.result; } +// ditto, but with `parent` parameter that represents the expression before rewriting. +// This way, when lowering an expression (e.g. i++ to i+=1), error messages can still +// refer to the original expression. +private Expression expressionSemanticWithParent(Expression e, Scope* sc, Expression parent) +{ + if (e.expressionSemanticDone) + return e; + + scope v = new ExpressionSemanticVisitor(sc); + v.parent = parent; + e.accept(v); + return v.result; +} + private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) { //printf("dotIdSemanticPropX() %s\n", toChars(exp)); diff --git a/compiler/src/dmd/opover.d b/compiler/src/dmd/opover.d index 01dffccdfcf..1b53a442c5b 100644 --- a/compiler/src/dmd/opover.d +++ b/compiler/src/dmd/opover.d @@ -94,58 +94,40 @@ private bool hasOpBinary(EXP op) pure @safe } } +/** + * Remove the = from op=, e.g. += becomes + + * + * Params: + * op = tag for a binary assign operator + * Returns: the corresponding binary operator, or `op` if it wasn't an assign operator +*/ +private EXP stripAssignOp(EXP op) +{ + switch (op) + { + case EXP.addAssign: return EXP.add; + case EXP.minAssign: return EXP.min; + case EXP.mulAssign: return EXP.mul; + case EXP.divAssign: return EXP.div; + case EXP.modAssign: return EXP.mod; + case EXP.andAssign: return EXP.and; + case EXP.orAssign: return EXP.or; + case EXP.xorAssign: return EXP.xor; + case EXP.leftShiftAssign: return EXP.leftShift; + case EXP.rightShiftAssign: return EXP.rightShift; + case EXP.unsignedRightShiftAssign: return EXP.unsignedRightShift; + case EXP.concatenateAssign: return EXP.concatenate; + case EXP.powAssign: return EXP.pow; + default: return op; + } +} + /******************************************* * Helper function to turn operator into template argument list */ Objects* opToArg(Scope* sc, EXP op) { - /* Remove the = from op= - */ - switch (op) - { - case EXP.addAssign: - op = EXP.add; - break; - case EXP.minAssign: - op = EXP.min; - break; - case EXP.mulAssign: - op = EXP.mul; - break; - case EXP.divAssign: - op = EXP.div; - break; - case EXP.modAssign: - op = EXP.mod; - break; - case EXP.andAssign: - op = EXP.and; - break; - case EXP.orAssign: - op = EXP.or; - break; - case EXP.xorAssign: - op = EXP.xor; - break; - case EXP.leftShiftAssign: - op = EXP.leftShift; - break; - case EXP.rightShiftAssign: - op = EXP.rightShift; - break; - case EXP.unsignedRightShiftAssign: - op = EXP.unsignedRightShift; - break; - case EXP.concatenateAssign: - op = EXP.concatenate; - break; - case EXP.powAssign: - op = EXP.pow; - break; - default: - break; - } - Expression e = new StringExp(Loc.initial, EXPtoString(op)); + Expression e = new StringExp(Loc.initial, EXPtoString(stripAssignOp(op))); e = e.expressionSemantic(sc); auto tiargs = new Objects(); tiargs.push(e); @@ -640,6 +622,45 @@ bool suggestBinaryOverloads(BinExp e, Scope* sc) return false; } +/** + * If applicable, print an error relating to implementing / fixing `opOpAssign` or `opUnary` functions. + * Params: + * exp = binary operation + * sc = scope to try `opOpAssign!""` semantic in for error messages + * parent = if `exp` was lowered from this `PreExp` or `PostExp`, mention `opUnary` as well + * Returns: `true` when an error related to `opOpAssign` was printed + */ +bool suggestOpOpAssign(BinAssignExp exp, Scope* sc, Expression parent) +{ + auto ad = isAggregate(exp.e1.type); + if (!ad) + return false; + + if (parent && (parent.isPreExp() || parent.isPostExp())) + { + error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(parent.op).ptr, exp.e1.toChars(), ad.toChars()); + errorSupplemental(ad.loc, + "perhaps implement `auto opUnary(string op : \"%s\")() {}`"~ + " or `auto opOpAssign(string op : \"%s\")(int) {}`", + EXPtoString(stripAssignOp(parent.op)).ptr, + EXPtoString(stripAssignOp(exp.op)).ptr + ); + return true; + } + + if (const s = search_function(ad, Id.opOpAssign)) + { + dotTemplateCall(exp.e1, Id.opOpAssign, opToArg(sc, exp.op), exp.e2).expressionSemantic(sc); + } + else + { + error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(exp.op).ptr, exp.e1.toChars(), ad.toChars()); + errorSupplemental(ad.loc, "perhaps implement `auto opOpAssign(string op : \"%s\")(%s) {}`", + EXPtoString(stripAssignOp(exp.op)).ptr, exp.e2.type.toChars()); + } + return true; +} + // Helper to construct e.id!tiargs(args), e.g. `lhs.opBinary!"+"(rhs)` private Expression dotTemplateCall(Expression e, Identifier id, Objects* tiargs, Expression[] args...) { diff --git a/compiler/test/fail_compilation/dep_d1_ops.d b/compiler/test/fail_compilation/dep_d1_ops.d index ec1a0f1c857..8d800b42a65 100644 --- a/compiler/test/fail_compilation/dep_d1_ops.d +++ b/compiler/test/fail_compilation/dep_d1_ops.d @@ -2,135 +2,163 @@ REQUIRED_ARGS: TEST_OUTPUT: --- -fail_compilation/dep_d1_ops.d(244): Error: operator `+` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}` -fail_compilation/dep_d1_ops.d(245): Error: operator `+` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}` -fail_compilation/dep_d1_ops.d(246): Error: operator `-` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}` -fail_compilation/dep_d1_ops.d(247): Error: operator `-` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}` -fail_compilation/dep_d1_ops.d(248): Error: operator `*` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}` -fail_compilation/dep_d1_ops.d(249): Error: operator `*` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}` -fail_compilation/dep_d1_ops.d(250): Error: operator `/` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}` -fail_compilation/dep_d1_ops.d(251): Error: operator `/` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}` -fail_compilation/dep_d1_ops.d(252): Error: operator `%` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}` -fail_compilation/dep_d1_ops.d(253): Error: operator `%` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}` -fail_compilation/dep_d1_ops.d(255): Error: operator `&` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}` -fail_compilation/dep_d1_ops.d(256): Error: operator `|` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}` -fail_compilation/dep_d1_ops.d(257): Error: operator `^` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}` -fail_compilation/dep_d1_ops.d(259): Error: operator `<<` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}` -fail_compilation/dep_d1_ops.d(260): Error: operator `<<` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}` -fail_compilation/dep_d1_ops.d(261): Error: operator `>>` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(262): Error: operator `>>` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(263): Error: operator `>>>` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(264): Error: operator `>>>` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(266): Error: operator `~` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}` -fail_compilation/dep_d1_ops.d(267): Error: operator `~` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}` -fail_compilation/dep_d1_ops.d(269): Error: operator `+` is not defined for `s` of type `S` -fail_compilation/dep_d1_ops.d(270): Error: operator `-` is not defined for `s` of type `S` -fail_compilation/dep_d1_ops.d(271): Error: `s` is not of integral type, it is a `S` -fail_compilation/dep_d1_ops.d(272): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(273): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(274): Error: can only `*` a pointer, not a `S` -fail_compilation/dep_d1_ops.d(276): Error: operator `in` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}` -fail_compilation/dep_d1_ops.d(277): Error: operator `in` is not defined for type `S` -fail_compilation/dep_d1_ops.d(137): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}` -fail_compilation/dep_d1_ops.d(279): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(280): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(281): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(282): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(283): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(284): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(285): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(286): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(287): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(288): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(289): Error: `s` is not a scalar, it is a `S` -fail_compilation/dep_d1_ops.d(290): Error: cannot append type `int` to type `S` -fail_compilation/dep_d1_ops.d(294): Error: operator `+` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}` -fail_compilation/dep_d1_ops.d(295): Error: operator `+` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}` -fail_compilation/dep_d1_ops.d(296): Error: operator `-` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}` -fail_compilation/dep_d1_ops.d(297): Error: operator `-` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}` -fail_compilation/dep_d1_ops.d(298): Error: operator `*` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}` -fail_compilation/dep_d1_ops.d(299): Error: operator `*` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}` -fail_compilation/dep_d1_ops.d(300): Error: operator `/` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}` -fail_compilation/dep_d1_ops.d(301): Error: operator `/` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}` -fail_compilation/dep_d1_ops.d(302): Error: operator `%` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}` -fail_compilation/dep_d1_ops.d(303): Error: operator `%` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}` -fail_compilation/dep_d1_ops.d(305): Error: operator `&` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}` -fail_compilation/dep_d1_ops.d(306): Error: operator `|` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}` -fail_compilation/dep_d1_ops.d(307): Error: operator `^` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}` -fail_compilation/dep_d1_ops.d(309): Error: operator `<<` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}` -fail_compilation/dep_d1_ops.d(310): Error: operator `<<` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}` -fail_compilation/dep_d1_ops.d(311): Error: operator `>>` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(312): Error: operator `>>` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(313): Error: operator `>>>` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(314): Error: operator `>>>` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}` -fail_compilation/dep_d1_ops.d(316): Error: operator `~` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}` -fail_compilation/dep_d1_ops.d(317): Error: operator `~` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}` -fail_compilation/dep_d1_ops.d(319): Error: operator `+` is not defined for `c` of type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(320): Error: operator `-` is not defined for `c` of type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(321): Error: `c` is not of integral type, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(322): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(323): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(324): Error: can only `*` a pointer, not a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(326): Error: operator `in` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}` -fail_compilation/dep_d1_ops.d(327): Error: operator `in` is not defined for type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(188): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}` -fail_compilation/dep_d1_ops.d(329): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(330): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(331): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(332): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(333): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(334): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(335): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(336): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(337): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(338): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(339): Error: `c` is not a scalar, it is a `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(340): Error: cannot append type `int` to type `dep_d1_ops.C` -fail_compilation/dep_d1_ops.d(349): Error: `nd` is not of integral type, it is a `dep_d1_ops.NoDeprecation` +fail_compilation/dep_d1_ops.d(272): Error: operator `+` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}` +fail_compilation/dep_d1_ops.d(273): Error: operator `+` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}` +fail_compilation/dep_d1_ops.d(274): Error: operator `-` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}` +fail_compilation/dep_d1_ops.d(275): Error: operator `-` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}` +fail_compilation/dep_d1_ops.d(276): Error: operator `*` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}` +fail_compilation/dep_d1_ops.d(277): Error: operator `*` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}` +fail_compilation/dep_d1_ops.d(278): Error: operator `/` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}` +fail_compilation/dep_d1_ops.d(279): Error: operator `/` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}` +fail_compilation/dep_d1_ops.d(280): Error: operator `%` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}` +fail_compilation/dep_d1_ops.d(281): Error: operator `%` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}` +fail_compilation/dep_d1_ops.d(283): Error: operator `&` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}` +fail_compilation/dep_d1_ops.d(284): Error: operator `|` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}` +fail_compilation/dep_d1_ops.d(285): Error: operator `^` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}` +fail_compilation/dep_d1_ops.d(287): Error: operator `<<` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}` +fail_compilation/dep_d1_ops.d(288): Error: operator `<<` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}` +fail_compilation/dep_d1_ops.d(289): Error: operator `>>` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(290): Error: operator `>>` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(291): Error: operator `>>>` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(292): Error: operator `>>>` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(294): Error: operator `~` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}` +fail_compilation/dep_d1_ops.d(295): Error: operator `~` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}` +fail_compilation/dep_d1_ops.d(297): Error: operator `+` is not defined for `s` of type `S` +fail_compilation/dep_d1_ops.d(298): Error: operator `-` is not defined for `s` of type `S` +fail_compilation/dep_d1_ops.d(299): Error: `s` is not of integral type, it is a `S` +fail_compilation/dep_d1_ops.d(300): Error: operator `++` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}` +fail_compilation/dep_d1_ops.d(301): Error: operator `--` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}` +fail_compilation/dep_d1_ops.d(302): Error: can only `*` a pointer, not a `S` +fail_compilation/dep_d1_ops.d(304): Error: operator `in` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}` +fail_compilation/dep_d1_ops.d(305): Error: operator `in` is not defined for type `S` +fail_compilation/dep_d1_ops.d(165): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}` +fail_compilation/dep_d1_ops.d(307): Error: operator `+=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "+")(int) {}` +fail_compilation/dep_d1_ops.d(308): Error: operator `-=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "-")(int) {}` +fail_compilation/dep_d1_ops.d(309): Error: operator `*=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "*")(int) {}` +fail_compilation/dep_d1_ops.d(310): Error: operator `/=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "/")(int) {}` +fail_compilation/dep_d1_ops.d(311): Error: operator `%=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "%")(int) {}` +fail_compilation/dep_d1_ops.d(312): Error: operator `&=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "&")(int) {}` +fail_compilation/dep_d1_ops.d(313): Error: operator `|=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "|")(int) {}` +fail_compilation/dep_d1_ops.d(314): Error: operator `^=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "^")(int) {}` +fail_compilation/dep_d1_ops.d(315): Error: operator `<<=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "<<")(int) {}` +fail_compilation/dep_d1_ops.d(316): Error: operator `>>=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : ">>")(int) {}` +fail_compilation/dep_d1_ops.d(317): Error: operator `>>>=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}` +fail_compilation/dep_d1_ops.d(318): Error: operator `~=` not supported for `s` of type `S` +fail_compilation/dep_d1_ops.d(165): perhaps implement `auto opOpAssign(string op : "~")(int) {}` +fail_compilation/dep_d1_ops.d(322): Error: operator `+` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}` +fail_compilation/dep_d1_ops.d(323): Error: operator `+` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}` +fail_compilation/dep_d1_ops.d(324): Error: operator `-` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}` +fail_compilation/dep_d1_ops.d(325): Error: operator `-` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}` +fail_compilation/dep_d1_ops.d(326): Error: operator `*` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}` +fail_compilation/dep_d1_ops.d(327): Error: operator `*` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}` +fail_compilation/dep_d1_ops.d(328): Error: operator `/` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}` +fail_compilation/dep_d1_ops.d(329): Error: operator `/` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}` +fail_compilation/dep_d1_ops.d(330): Error: operator `%` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}` +fail_compilation/dep_d1_ops.d(331): Error: operator `%` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}` +fail_compilation/dep_d1_ops.d(333): Error: operator `&` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}` +fail_compilation/dep_d1_ops.d(334): Error: operator `|` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}` +fail_compilation/dep_d1_ops.d(335): Error: operator `^` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}` +fail_compilation/dep_d1_ops.d(337): Error: operator `<<` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}` +fail_compilation/dep_d1_ops.d(338): Error: operator `<<` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}` +fail_compilation/dep_d1_ops.d(339): Error: operator `>>` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(340): Error: operator `>>` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(341): Error: operator `>>>` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(342): Error: operator `>>>` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}` +fail_compilation/dep_d1_ops.d(344): Error: operator `~` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}` +fail_compilation/dep_d1_ops.d(345): Error: operator `~` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}` +fail_compilation/dep_d1_ops.d(347): Error: operator `+` is not defined for `c` of type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(348): Error: operator `-` is not defined for `c` of type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(349): Error: `c` is not of integral type, it is a `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(350): Error: operator `++` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}` +fail_compilation/dep_d1_ops.d(351): Error: operator `--` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}` +fail_compilation/dep_d1_ops.d(352): Error: can only `*` a pointer, not a `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(354): Error: operator `in` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}` +fail_compilation/dep_d1_ops.d(355): Error: operator `in` is not defined for type `dep_d1_ops.C` +fail_compilation/dep_d1_ops.d(216): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}` +fail_compilation/dep_d1_ops.d(357): Error: operator `+=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "+")(int) {}` +fail_compilation/dep_d1_ops.d(358): Error: operator `-=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "-")(int) {}` +fail_compilation/dep_d1_ops.d(359): Error: operator `*=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "*")(int) {}` +fail_compilation/dep_d1_ops.d(360): Error: operator `/=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "/")(int) {}` +fail_compilation/dep_d1_ops.d(361): Error: operator `%=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "%")(int) {}` +fail_compilation/dep_d1_ops.d(362): Error: operator `&=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "&")(int) {}` +fail_compilation/dep_d1_ops.d(363): Error: operator `|=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "|")(int) {}` +fail_compilation/dep_d1_ops.d(364): Error: operator `^=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "^")(int) {}` +fail_compilation/dep_d1_ops.d(365): Error: operator `<<=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "<<")(int) {}` +fail_compilation/dep_d1_ops.d(366): Error: operator `>>=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : ">>")(int) {}` +fail_compilation/dep_d1_ops.d(367): Error: operator `>>>=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}` +fail_compilation/dep_d1_ops.d(368): Error: operator `~=` not supported for `c` of type `C` +fail_compilation/dep_d1_ops.d(216): perhaps implement `auto opOpAssign(string op : "~")(int) {}` +fail_compilation/dep_d1_ops.d(377): Error: `nd` is not of integral type, it is a `dep_d1_ops.NoDeprecation` --- */ diff --git a/compiler/test/fail_compilation/diag13320.d b/compiler/test/fail_compilation/diag13320.d index 2808606bdca..40b99ab39d0 100644 --- a/compiler/test/fail_compilation/diag13320.d +++ b/compiler/test/fail_compilation/diag13320.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/diag13320.d(13): Error: `f` is not a scalar, it is a `Foo` +fail_compilation/diag13320.d(14): Error: operator `++` not supported for `f` of type `Foo` +fail_compilation/diag13320.d(9): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}` --- */ diff --git a/compiler/test/fail_compilation/fail18985.d b/compiler/test/fail_compilation/fail18985.d index 830a6792ad2..f2899bdb337 100644 --- a/compiler/test/fail_compilation/fail18985.d +++ b/compiler/test/fail_compilation/fail18985.d @@ -1,15 +1,19 @@ /* TEST_OUTPUT: --- -fail_compilation/fail18985.d(16): Error: `foo` is not a scalar, it is a `object.Object` -fail_compilation/fail18985.d(17): Error: `bar` is not a scalar, it is a `shared(Object)` +fail_compilation/fail18985.d(20): Error: operator `+=` not supported for `foo` of type `C` +fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}` +fail_compilation/fail18985.d(21): Error: operator `+=` not supported for `bar` of type `C` +fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}` --- */ // https://issues.dlang.org/show_bug.cgi?id=18985 -Object foo; -shared Object bar; +class C {} + +C foo; +shared C bar; void main() { diff --git a/compiler/test/fail_compilation/fail3672.d b/compiler/test/fail_compilation/fail3672.d index 2f9bdf742b7..0062798f312 100644 --- a/compiler/test/fail_compilation/fail3672.d +++ b/compiler/test/fail_compilation/fail3672.d @@ -1,9 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/fail3672.d(28): Error: read-modify-write operations are not allowed for `shared` variables -fail_compilation/fail3672.d(28): Use `core.atomic.atomicOp!"+="(*p, 1)` instead -fail_compilation/fail3672.d(32): Error: none of the `opOpAssign` overloads of `SF` are callable for `*sfp` of type `shared(SF)` +fail_compilation/fail3672.d(29): Error: read-modify-write operations are not allowed for `shared` variables +fail_compilation/fail3672.d(29): Use `core.atomic.atomicOp!"+="(*p, 1)` instead +fail_compilation/fail3672.d(33): Error: template `opOpAssign` is not callable using argument types `!("+")(int) shared` +fail_compilation/fail3672.d(13): Candidate is: `opOpAssign(string op, T)(T rhs)` --- */