Print function bodies instead of __lambda in error messages

This commit is contained in:
Dennis Korpel 2025-02-13 12:42:18 +01:00 committed by The Dlang Bot
parent 0bb48e277c
commit efd10b140c
53 changed files with 289 additions and 204 deletions

View file

@ -150,7 +150,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
//printf("type %s t %s\n", type.deco, t.deco);
auto ts = toAutoQualChars(e.type, t);
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
e.toChars(), ts[0], ts[1]);
e.toErrMsg(), ts[0], ts[1]);
}
}
return ErrorExp.get();

View file

@ -3884,7 +3884,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (n_instantiations <= max_shown)
{
for (TemplateInstance cur = this; cur; cur = cur.tinst)
printFn(cur.loc, format, cur.toChars());
printFn(cur.loc, format, cur.toErrMsg());
}
else if (n_instantiations - n_totalrecursions <= max_shown)
{
@ -6265,6 +6265,9 @@ void write(ref OutBuffer buf, RootObject obj)
{
if (obj)
{
buf.writestring(obj.toChars());
if (auto e = isExpression(obj))
buf.writestring(e.toErrMsg());
else
buf.writestring(obj.toChars());
}
}

View file

@ -383,8 +383,7 @@ extern (C++) abstract class Expression : ASTNode
final override const(char)* toChars() const
{
// FIXME: Test suite relies on lambda's being printed as __lambdaXXX in errors and .stringof
// Printing a (truncated) lambda body is more user friendly
// FIXME: mangling (see runnable/mangle.d) relies on toChars outputting __lambdaXXX here
if (auto fe = isFuncExp())
return fe.fd.toChars();

View file

@ -362,11 +362,11 @@ private Expression incompatibleTypes(UnaExp e)
if (e.e1.op == EXP.type)
{
error(e.loc, "incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(e.op).ptr, e.e1.toChars(), EXPtoString(e.op).ptr);
error(e.loc, "incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(e.op).ptr, e.e1.toErrMsg(), EXPtoString(e.op).ptr);
}
else
{
error(e.loc, "incompatible type for `%s(%s)`: `%s`", EXPtoString(e.op).ptr, e.e1.toChars(), e.e1.type.toChars());
error(e.loc, "incompatible type for `%s(%s)`: `%s`", EXPtoString(e.op).ptr, e.e1.toErrMsg(), e.e1.type.toChars());
}
return ErrorExp.get();
}
@ -393,18 +393,18 @@ extern (D) Expression incompatibleTypes(BinExp e, Scope* sc = null)
if (e.e1.op == EXP.type || e.e2.op == EXP.type)
{
error(e.loc, "incompatible types for `(%s) %s (%s)`: cannot use `%s` with types",
e.e1.toChars(), thisOp, e.e2.toChars(), EXPtoString(e.op).ptr);
e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), EXPtoString(e.op).ptr);
}
else if (e.e1.type.equals(e.e2.type))
{
error(e.loc, "incompatible types for `(%s) %s (%s)`: both operands are of type `%s`",
e.e1.toChars(), thisOp, e.e2.toChars(), e.e1.type.toChars());
e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), e.e1.type.toChars());
}
else
{
auto ts = toAutoQualChars(e.e1.type, e.e2.type);
error(e.loc, "incompatible types for `(%s) %s (%s)`: `%s` and `%s`",
e.e1.toChars(), thisOp, e.e2.toChars(), ts[0], ts[1]);
e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), ts[0], ts[1]);
}
return ErrorExp.get();
}
@ -731,7 +731,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, out Expression pe0)
if (!e.type)
{
error(ae.loc, "`%s` has no value", e.toChars());
error(ae.loc, "`%s` has no value", e.toErrMsg());
e = ErrorExp.get();
}
if (e.op == EXP.error)
@ -768,7 +768,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, ref Expressio
e = resolveProperties(sc, e);
if (!e.type)
{
error(ae.loc, "`%s` has no value", e.toChars());
error(ae.loc, "`%s` has no value", e.toErrMsg());
errors = true;
}
return e;
@ -2109,7 +2109,7 @@ public void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool
{
if (maxDepth > 0)
{
errorFunc(s.loc, "which calls `%s`", s.fd.toPrettyChars());
errorFunc(s.loc, "which calls `%s`", s.fd.toErrMsg());
errorSupplementalInferredAttr(s.fd, maxDepth - 1, deprecation, stc, eSink);
}
}
@ -2477,7 +2477,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
auto tf = fd.type.isTypeFunction();
if (!tf.isRef && e2)
{
error(loc, "%s is not an lvalue", e1.toChars());
error(loc, "%s is not an lvalue", e1.toErrMsg());
return ErrorExp.get();
}
}
@ -2645,13 +2645,13 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (!e1.type)
{
error(loc, "cannot resolve type for %s", e1.toChars());
error(loc, "cannot resolve type for %s", e1.toErrMsg());
e1 = ErrorExp.get();
}
return e1;
Leprop:
error(loc, "not a property %s", e1.toChars());
error(loc, "not a property %s", e1.toErrMsg());
return ErrorExp.get();
}
@ -2715,7 +2715,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
e = resolveProperties(sc, e);
if (!e.type)
{
error(e.loc, "`%s` has no value", e.toChars());
error(e.loc, "`%s` has no value", e.toErrMsg());
t0 = Type.terror;
continue;
}
@ -2912,7 +2912,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, ErrorSi
{
if (eSink)
{
eSink.error(arg.loc, "cannot pass type `%s` as a function argument", arg.toChars());
eSink.error(arg.loc, "cannot pass type `%s` as a function argument", arg.toErrMsg());
arg = ErrorExp.get();
}
err = true;
@ -2922,7 +2922,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, ErrorSi
{
if (eSink)
{
eSink.error(arg.loc, "cannot pass function `%s` as a function argument", arg.toChars());
eSink.error(arg.loc, "cannot pass function `%s` as a function argument", arg.toErrMsg());
arg = ErrorExp.get();
}
err = true;
@ -3515,7 +3515,7 @@ private bool functionParameters(Loc loc, Scope* sc,
{
if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique())
{
error(arg.loc, "function `%s` is overloaded", arg.toChars());
error(arg.loc, "function `%s` is overloaded", arg.toErrMsg());
err = true;
}
}
@ -4159,7 +4159,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (!s)
{
error(e.loc, "`%s` is not in a class or struct scope", e.toChars());
error(e.loc, "`%s` is not in a class or struct scope", e.toErrMsg());
return setError();
}
ClassDeclaration cd = s.isClassDeclaration();
@ -4225,7 +4225,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (!s)
{
error(e.loc, "`%s` is not in a class scope", e.toChars());
error(e.loc, "`%s` is not in a class scope", e.toErrMsg());
return setError();
}
cd = s.isClassDeclaration();
@ -4489,7 +4489,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
e = e.expressionSemantic(sc);
if (!e.type)
{
error(exp.loc, "`%s` has no value", e.toChars());
error(exp.loc, "`%s` has no value", e.toErrMsg());
err = true;
}
else if (e.op == EXP.error)
@ -4540,7 +4540,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
if (e.elements.length > 0 && t0.ty == Tvoid)
{
error(e.loc, "`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
error(e.loc, "`%s` of type `%s` has no value", e.toErrMsg(), e.type.toChars());
return setError();
}
@ -5359,9 +5359,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!global.params.useGC && sc.needsCodegen())
{
version(IN_GCC)
error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-fno-rtti`", exp.toChars());
error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-fno-rtti`", exp.toErrMsg());
else
error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-betterC`", exp.toChars());
error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-betterC`", exp.toErrMsg());
return setError();
}
@ -5832,8 +5832,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
OutBuffer buf;
foreach (idx, ref arg; *arguments)
buf.printf("%s%s", (idx ? ", ".ptr : "".ptr), arg.type.toChars());
error(exp.loc, "function literal `%s%s` is not callable using argument types `(%s)`",
exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
error(exp.loc, "`%s` is not callable using argument types `(%s)`",
exp.fd.toErrMsg(), // parametersTypeToChars(tfl.parameterList),
buf.peekChars());
errorSupplemental(exp.loc, "too %s arguments, expected %d, got %d",
arguments.length < dim ? "few".ptr : "many".ptr,
@ -6038,7 +6038,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
__gshared int nest;
if (++nest > global.recursionLimit)
{
error(exp.loc, "recursive evaluation of `%s`", exp.toChars());
error(exp.loc, "recursive evaluation of `%s`", exp.toErrMsg());
--nest;
return setError();
}
@ -6331,7 +6331,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return null;
if (f)
return f;
.error(loc, "no overload matches for `%s`", exp.toChars());
.error(loc, "no overload matches for `%s`", exp.toErrMsg());
errorSupplemental(loc, "Candidates are:");
foreach (s; os.a)
{
@ -6591,7 +6591,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else if (!t1)
{
error(exp.loc, "function expected before `()`, not `%s`", exp.e1.toChars());
error(exp.loc, "function expected before `()`, not `%s`", exp.e1.toErrMsg());
return setError();
}
else if (t1.ty == Terror)
@ -6674,7 +6674,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
error(exp.loc, "function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars());
error(exp.loc, "function expected before `()`, not `%s` of type `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars());
return setError();
}
@ -6688,8 +6688,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
tthis.modToBuffer(buf);
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
.error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
p, exp.e1.toChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
p, exp.e1.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental(exp.loc, "%s", failMessage);
}
@ -6712,20 +6712,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!tf.purity && sc.func.setImpure(exp.loc, "calling impure `%s`", exp.e1))
{
error(exp.loc, "`pure` %s `%s` cannot call impure %s `%s`",
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (!tf.isNogc && sc.func.setGC(exp.loc, "calling non-@nogc `%s`", exp.e1))
{
error(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (tf.trust <= TRUST.system && sc.setUnsafe(true, exp.loc,
"calling `@system` `%s`", exp.e1))
{
error(exp.loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (err)
@ -6770,7 +6770,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
exp.f.kind(), exp.f.toChars(), buf.peekChars());
exp.f.kind(), exp.f.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental(exp.loc, "%s", failMessage);
.errorSupplemental(exp.f.loc, "`%s%s` declared here", exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList));
@ -6846,7 +6846,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
exp.e1 = e1org; // https://issues.dlang.org/show_bug.cgi?id=10922
// avoid recursive expression printing
error(exp.loc, "forward reference to inferred return type of function call `%s`", exp.toChars());
error(exp.loc, "forward reference to inferred return type of function call `%s`", exp.toErrMsg());
return setError();
}
@ -7126,7 +7126,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!ta)
{
//printf("ta %p ea %p sa %p\n", ta, ea, sa);
error(exp.loc, "no type for `typeid(%s)`", ea ? ea.toChars() : (sa ? sa.toChars() : ""));
error(exp.loc, "no type for `typeid(%s)`", ea ? ea.toErrMsg() : (sa ? sa.toChars() : ""));
return setError();
}
@ -7798,7 +7798,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// deprecated in 2.107
deprecation(e.loc, "assert condition cannot be a string literal");
deprecationSupplemental(e.loc, "If intentional, use `%s !is null` instead to preserve behaviour",
e.toChars());
e.toErrMsg());
}
const generateMsg = !exp.msg &&
@ -8430,7 +8430,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
MODMatchToBuffer(&thisBuf, e.e1.type.mod, tf.mod);
MODMatchToBuffer(&funcBuf, tf.mod, e.e1.type.mod);
error(e.loc, "%smethod `%s` is not callable using a %s`%s`",
funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toChars());
funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toErrMsg());
return setError();
}
}
@ -8614,7 +8614,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!exp.e1.type)
{
error(exp.loc, "cannot take address of `%s`", exp.e1.toChars());
error(exp.loc, "cannot take address of `%s`", exp.e1.toErrMsg());
return setError();
}
if (!checkAddressable(exp, sc))
@ -8638,7 +8638,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
error(exp.loc, "forward reference to %s `%s`", d.kind(), d.toChars());
}
else
error(exp.loc, "forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toChars());
error(exp.loc, "forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toErrMsg());
return setError();
}
}
@ -8801,7 +8801,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
case Tarray:
if (isNonAssignmentArrayOp(exp.e1))
goto default;
error(exp.loc, "using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toChars());
error(exp.loc, "using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toErrMsg());
exp.type = (cast(TypeArray)tb).next;
exp.e1 = exp.e1.castTo(sc, exp.type.pointerTo());
break;
@ -9111,7 +9111,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!exp.e1.type)
{
error(exp.loc, "cannot cast `%s`", exp.e1.toChars());
error(exp.loc, "cannot cast `%s`", exp.e1.toErrMsg());
return setError();
}
@ -9149,7 +9149,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.to.ty == Ttuple)
{
error(exp.loc, "cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars());
error(exp.loc, "cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars(), exp.to.toChars());
return setError();
}
@ -9333,7 +9333,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (elem.isConst() == 1)
return false;
error(exp.loc, "constant expression expected, not `%s`", elem.toChars());
error(exp.loc, "constant expression expected, not `%s`", elem.toErrMsg());
return true;
}
@ -9393,7 +9393,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (exp.lwr || exp.upr)
{
error(exp.loc, "cannot slice type `%s`", exp.e1.toChars());
error(exp.loc, "cannot slice type `%s`", exp.e1.toErrMsg());
return setError();
}
Expression e = new TypeExp(exp.loc, exp.e1.type.arrayOf());
@ -9445,7 +9445,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (t1b.isPtrToFunction())
{
error(exp.loc, "cannot slice function pointer `%s`", exp.e1.toChars());
error(exp.loc, "cannot slice function pointer `%s`", exp.e1.toErrMsg());
return setError();
}
if (!exp.lwr || !exp.upr)
@ -9462,9 +9462,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
errorSupplemental(exp.loc,
"pointer `%s` points to an aggregate that defines an `%s`, perhaps you meant `(*%s)[]`",
exp.e1.toChars(),
exp.e1.toErrMsg(),
s.ident.toChars(),
exp.e1.toChars()
exp.e1.toErrMsg()
);
}
@ -9505,7 +9505,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
error(exp.loc, "`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars());
error(exp.loc, "`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toErrMsg() : t1b.toChars());
return setError();
}
@ -9981,7 +9981,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
case Tpointer:
if (t1b.isPtrToFunction())
{
error(exp.loc, "cannot index function pointer `%s`", exp.e1.toChars());
error(exp.loc, "cannot index function pointer `%s`", exp.e1.toErrMsg());
return setError();
}
exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
@ -10078,7 +10078,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
default:
error(exp.loc, "`%s` must be an array or pointer type, not `%s`", exp.e1.toChars(), exp.e1.type.toChars());
error(exp.loc, "`%s` must be an array or pointer type, not `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars());
return setError();
}
@ -10156,7 +10156,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.e1.op == EXP.slice)
{
const(char)* s = exp.op == EXP.plusPlus ? "increment" : "decrement";
error(exp.loc, "cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toChars(), s);
error(exp.loc, "cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toErrMsg(), s);
return setError();
}
@ -10909,7 +10909,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (newExp.newtype && newExp.newtype == t1)
{
error(exp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
newExp.toChars(), newExp.type.toChars(), t1.toChars());
newExp.toErrMsg(), newExp.type.toChars(), t1.toChars());
errorSupplemental(exp.loc, "Perhaps remove the `new` keyword?");
return setError();
}
@ -11282,7 +11282,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.op == EXP.assign && !tn.baseElemOf().isAssignable())
{
error(exp.loc, "slice `%s` is not mutable, struct `%s` has immutable members",
exp.e1.toChars(), tn.baseElemOf().toChars());
exp.e1.toErrMsg(), tn.baseElemOf().toChars());
result = ErrorExp.get();
return;
}
@ -11305,7 +11305,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (tn && !tn.baseElemOf().isAssignable())
{
error(exp.loc, "array `%s` is not mutable, struct `%s` has immutable members",
exp.e1.toChars(), tn.baseElemOf().toChars());
exp.e1.toErrMsg(), tn.baseElemOf().toChars());
result = ErrorExp.get();
return;
}
@ -11375,7 +11375,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
uinteger_t dim2 = tsa2.dim.toInteger();
if (dim1 != dim2)
{
error(exp.loc, "mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars());
error(exp.loc, "mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toErrMsg());
return setError();
}
}
@ -11451,7 +11451,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// offer more information about the cause of the problem
errorSupplemental(exp.loc,
"`%s` is the first assignment of `%s` therefore it represents its initialization",
exp.toChars(), exp.e1.toChars());
exp.toErrMsg(), exp.e1.toErrMsg());
errorSupplemental(exp.loc,
"`opAssign` methods are not used for initialization, but for subsequent assignments");
}
@ -12796,7 +12796,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Module mmath = Module.loadStdMath();
if (!mmath)
{
error(e.loc, "`%s` requires `std.math` for `^^` operators", e.toChars());
error(e.loc, "`%s` requires `std.math` for `^^` operators", e.toErrMsg());
return setError();
}
e = new ScopeExp(exp.loc, mmath);
@ -12970,7 +12970,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (e2x.op == EXP.type || e2x.op == EXP.scope_)
{
error(exp.loc, "`%s` is not an expression", exp.e2.toChars());
error(exp.loc, "`%s` is not an expression", exp.e2.toErrMsg());
return setError();
}
if (e1x.op == EXP.error || e1x.type.ty == Tnoreturn)
@ -13152,7 +13152,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
errorSupplemental(exp.loc, "`in` is only allowed on associative arrays");
const(char)* slice = (t2b.ty == Tsarray) ? "[]" : "";
errorSupplemental(exp.loc, "perhaps use `std.algorithm.find(%s, %s%s)` instead",
exp.e1.toChars(), exp.e2.toChars(), slice);
exp.e1.toErrMsg(), exp.e2.toErrMsg(), slice);
return;
default:
@ -13998,12 +13998,12 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
// Template has no built-in properties except for 'stringof'.
if ((exp.e1.isDotTemplateExp() || exp.e1.isTemplateExp()) && exp.ident != Id.stringof)
{
error(exp.loc, "template `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
error(exp.loc, "template `%s` does not have property `%s`", exp.e1.toErrMsg(), exp.ident.toChars());
return ErrorExp.get();
}
if (!exp.e1.type)
{
error(exp.loc, "expression `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
error(exp.loc, "expression `%s` does not have property `%s`", exp.e1.toErrMsg(), exp.ident.toChars());
return ErrorExp.get();
}
@ -14405,7 +14405,7 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool g
Expression notTemplate()
{
error(exp.loc, "`%s` isn't a template", e.toChars());
error(exp.loc, "`%s` isn't a template", e.toErrMsg());
return errorExp();
}
@ -14720,7 +14720,7 @@ MATCH matchType(FuncExp funcExp, Type to, Scope* sc, FuncExp* presult, ErrorSink
{
auto ts = toAutoQualChars(tx, to);
eSink.error(loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
funcExp.toChars(), ts[0], ts[1]);
funcExp.toErrMsg(), ts[0], ts[1]);
}
return m;
}
@ -14733,7 +14733,7 @@ private bool checkScalar(Expression e)
return true;
if (!e.type.isScalar())
{
error(e.loc, "`%s` is not a scalar, it is a `%s`", e.toChars(), e.type.toChars());
error(e.loc, "`%s` is not a scalar, it is a `%s`", e.toErrMsg(), e.type.toChars());
return true;
}
return e.checkValue();
@ -14747,7 +14747,7 @@ private bool checkNoBool(Expression e)
return true;
if (e.type.toBasetype().ty == Tbool)
{
error(e.loc, "operation not allowed on `bool` `%s`", e.toChars());
error(e.loc, "operation not allowed on `bool` `%s`", e.toErrMsg());
return true;
}
return false;
@ -14761,7 +14761,7 @@ private bool checkIntegral(Expression e)
return true;
if (!e.type.isIntegral())
{
error(e.loc, "`%s` is not of integral type, it is a `%s`", e.toChars(), e.type.toChars());
error(e.loc, "`%s` is not of integral type, it is a `%s`", e.toErrMsg(), e.type.toChars());
return true;
}
return e.checkValue();
@ -14779,7 +14779,7 @@ private bool checkArithmetic(Expression e, EXP op)
const char* msg = e.type.isAggregate() ?
"operator `%s` is not defined for `%s` of type `%s`" :
"illegal operator `%s` for `%s` of type `%s`";
error(e.loc, msg, EXPtoString(op).ptr, e.toChars(), e.type.toChars());
error(e.loc, msg, EXPtoString(op).ptr, e.toErrMsg(), e.type.toChars());
return true;
}
@ -14862,7 +14862,7 @@ bool checkValue(Expression e)
{
if (auto te = e.isTypeExp())
{
error(e.loc, "type `%s` has no value", e.toChars());
error(e.loc, "type `%s` has no value", e.toErrMsg());
if (!e.type.isOpaqueType)
errorSupplemental(e.loc, "perhaps use `%s.init`", e.toChars());
return true;
@ -14874,7 +14874,7 @@ bool checkValue(Expression e)
dtie.ti.semantictiargsdone &&
dtie.ti.semanticRun == PASS.initial)
error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toChars());
error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toErrMsg());
else
error(e.loc, "%s `%s` has no value", dtie.ti.kind(), dtie.ti.toChars());
return true;
@ -14904,13 +14904,13 @@ bool checkValue(Expression e)
if (auto dte = e.isDotTemplateExp())
{
error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toChars());
error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toErrMsg());
return true;
}
if (e.type && e.type.toBasetype().ty == Tvoid)
{
error(e.loc, "expression `%s` is `void` and has no value", e.toChars());
error(e.loc, "expression `%s` is `void` and has no value", e.toErrMsg());
//print(); assert(0);
if (!global.gag)
e.type = Type.terror;
@ -14970,7 +14970,7 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
bool sharedError(Expression e)
{
// https://dlang.org/phobos/core_atomic.html
error(e.loc, "direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars());
error(e.loc, "direct access to shared `%s` is not allowed, see `core.atomic`", e.toErrMsg());
return true;
}
@ -15494,9 +15494,9 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
if (e.op == EXP.type)
error(_this.loc, "cannot %s type `%s`", action, e.type.toChars());
else if (e.op == EXP.template_)
error(_this.loc, "cannot %s template `%s`, perhaps instantiate it first", action, e.toChars());
error(_this.loc, "cannot %s template `%s`, perhaps instantiate it first", action, e.toErrMsg());
else
error(_this.loc, "cannot %s expression `%s` because it is not an lvalue", action, e.toChars());
error(_this.loc, "cannot %s expression `%s` because it is not an lvalue", action, e.toErrMsg());
return ErrorExp.get();
}
@ -15505,7 +15505,7 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
{
if (!_this.loc.isValid())
_this.loc = e.loc;
error(e.loc, "cannot %s constant `%s`", action, e.toChars());
error(e.loc, "cannot %s constant `%s`", action, e.toErrMsg());
return ErrorExp.get();
}
@ -15930,12 +15930,12 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
break;
if (!ff.type.isMutable)
{
error(exp.loc, "cannot modify `%s` in `%s` function", exp.toChars(), MODtoChars(type.mod));
error(exp.loc, "cannot modify `%s` in `%s` function", exp.toErrMsg(), MODtoChars(type.mod));
return ErrorExp.get();
}
}
}
error(exp.loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), exp.toChars());
error(exp.loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), exp.toErrMsg());
return ErrorExp.get();
}
else if (!type.isAssignable())
@ -15950,7 +15950,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
Expression visitString(StringExp exp)
{
error(exp.loc, "cannot modify string literal `%s`", exp.toChars());
error(exp.loc, "cannot modify string literal `%s`", exp.toErrMsg());
return ErrorExp.get();
}
@ -15959,7 +15959,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
//printf("VarExp::modifiableLvalue('%s')\n", exp.var.toChars());
if (exp.var.storage_class & STC.manifest)
{
error(exp.loc, "cannot modify manifest constant `%s`", exp.toChars());
error(exp.loc, "cannot modify manifest constant `%s`", exp.toErrMsg());
return ErrorExp.get();
}
// See if this expression is a modifiable lvalue (i.e. not const)
@ -15988,7 +15988,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
Expression visitSlice(SliceExp exp)
{
error(exp.loc, "slice expression `%s` is not a modifiable lvalue", exp.toChars());
error(exp.loc, "slice expression `%s` is not a modifiable lvalue", exp.toErrMsg());
return exp;
}
@ -16030,7 +16030,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
{
if (!exp.e1.isLvalue() && !exp.e2.isLvalue())
{
error(exp.loc, "conditional expression `%s` is not a modifiable lvalue", exp.toChars());
error(exp.loc, "conditional expression `%s` is not a modifiable lvalue", exp.toErrMsg());
return ErrorExp.get();
}
exp.e1 = exp.e1.modifiableLvalue(sc);
@ -16071,7 +16071,7 @@ private bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
if (!v.canTakeAddressOf())
{
error(exp.loc, "cannot take address of `%s`", exp.toChars());
error(exp.loc, "cannot take address of `%s`", exp.toErrMsg());
return false;
}
if (sc.func && !sc.intypeof && !v.isDataseg())
@ -16133,9 +16133,9 @@ bool checkAddressable(Expression e, Scope* sc)
if (ex.isVarExp().var.storage_class & STC.register)
{
if (e.isIndexExp())
error(e.loc, "cannot index through register variable `%s`", ex.toChars());
error(e.loc, "cannot index through register variable `%s`", ex.toErrMsg());
else
error(e.loc, "cannot take address of register variable `%s`", ex.toChars());
error(e.loc, "cannot take address of register variable `%s`", ex.toErrMsg());
return false;
}
}
@ -16629,7 +16629,7 @@ bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool
if (opt.isEmpty())
{
if (!e.type.isTypeError())
error(e.loc, "expression `%s` is not constant", e.toChars());
error(e.loc, "expression `%s` is not constant", e.toErrMsg());
errors = true;
return false;
}

View file

@ -4071,6 +4071,7 @@ struct HdrGenState final
bool vcg_ast;
bool skipConstraints;
bool showOneMember;
bool errorMsg;
bool fullQual;
int32_t tpltMember;
int32_t autoMember;
@ -4088,6 +4089,7 @@ struct HdrGenState final
vcg_ast(),
skipConstraints(),
showOneMember(true),
errorMsg(),
fullQual(),
tpltMember(),
autoMember(),
@ -4098,7 +4100,7 @@ struct HdrGenState final
inEnumDecl()
{
}
HdrGenState(bool hdrgen, bool ddoc = false, bool fullDump = false, bool importcHdr = false, bool doFuncBodies = false, bool vcg_ast = false, bool skipConstraints = false, bool showOneMember = true, bool fullQual = false, int32_t tpltMember = 0, int32_t autoMember = 0, int32_t forStmtInit = 0, int32_t insideFuncBody = 0, int32_t insideAggregate = 0, bool declstring = false, EnumDeclaration* inEnumDecl = nullptr) :
HdrGenState(bool hdrgen, bool ddoc = false, bool fullDump = false, bool importcHdr = false, bool doFuncBodies = false, bool vcg_ast = false, bool skipConstraints = false, bool showOneMember = true, bool errorMsg = false, bool fullQual = false, int32_t tpltMember = 0, int32_t autoMember = 0, int32_t forStmtInit = 0, int32_t insideFuncBody = 0, int32_t insideAggregate = 0, bool declstring = false, EnumDeclaration* inEnumDecl = nullptr) :
hdrgen(hdrgen),
ddoc(ddoc),
fullDump(fullDump),
@ -4107,6 +4109,7 @@ struct HdrGenState final
vcg_ast(vcg_ast),
skipConstraints(skipConstraints),
showOneMember(showOneMember),
errorMsg(errorMsg),
fullQual(fullQual),
tpltMember(tpltMember),
autoMember(autoMember),

View file

@ -63,6 +63,7 @@ struct HdrGenState
bool vcg_ast; /// write out codegen-ast
bool skipConstraints; // skip constraints when doing templates
bool showOneMember = true;
bool errorMsg; /// true if formatting for inside an error message
bool fullQual; /// fully qualify types when printing
int tpltMember;
@ -96,6 +97,71 @@ void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf)
toCBuffer(m, buf, hgs);
}
/**
* Convert `e` to a string for error messages.
* Params:
* e = expression to convert
* Returns: string representation of `e`
*/
const(char)* toErrMsg(const Expression e)
{
HdrGenState hgs;
hgs.errorMsg = true;
OutBuffer buf;
toCBuffer(e, buf, hgs);
truncateForError(buf, 60);
return buf.extractChars();
}
/// ditto
const(char)* toErrMsg(const Dsymbol d)
{
if (d.isFuncDeclaration() || d.isTemplateInstance())
{
if (d.ident && d.ident.toString.startsWith("__"))
{
HdrGenState hgs;
hgs.errorMsg = true;
OutBuffer buf;
toCBuffer(cast() d, buf, hgs);
truncateForError(buf, 80);
return buf.extractChars();
}
}
return d.toChars();
}
/**
* Make the content of `buf` fit inline for an error message.
* Params:
* buf = buffer with text to modify
* maxLength = truncate text when it exceeds this length
*/
private void truncateForError(ref OutBuffer buf, size_t maxLength)
{
// Remove newlines
for (size_t i = 0; i < buf.length; i++)
{
if (buf[i] == '\r')
buf.remove(i, 1);
if (buf[i] == '\n')
buf.peekSlice[i] = ' ';
}
// Strip trailing whitespace
while (buf.length && buf[$-1] == ' ')
buf.setsize(buf.length - 1);
// Truncate
if (buf.length > maxLength)
{
buf.setsize(maxLength - 3);
buf.writestring("...");
}
}
/***************************************
* Turn a Statement into a string suitable for printf.
* Leaks memory.
@ -1772,7 +1838,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring("__error");
return;
}
if (f.tok != TOK.reserved)
if (f.tok != TOK.reserved && !hgs.errorMsg)
{
buf.writestring(f.kind());
buf.writeByte(' ');
@ -1789,8 +1855,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writeByte(' ');
buf.writestring(str);
}
tf.attributesApply(&printAttribute);
if (!hgs.errorMsg)
tf.attributesApply(&printAttribute);
CompoundStatement cs = f.fbody.isCompoundStatement();
Statement s1;

View file

@ -585,7 +585,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
const errors = global.startGagging();
i.exp = i.exp.implicitCastTo(sc, t);
if (global.endGagging(errors))
error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars());
error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toErrMsg(), et.toChars(), t.toChars());
}
}
L1:

View file

@ -380,7 +380,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (!sc.intypeof)
{
if (fld.tok == TOK.delegate_)
.error(funcdecl.loc, "%s `%s` cannot be %s members", funcdecl.kind, funcdecl.toPrettyChars, ad.kind());
.error(funcdecl.loc, "%s `%s` cannot be %s members", funcdecl.kind, funcdecl.toErrMsg, ad.kind());
else
fld.tok = TOK.function_;
}
@ -1375,7 +1375,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
}
if (isCppNonMappableType(f.next.toBasetype()))
{
.error(funcdecl.loc, "%s `%s` cannot return type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, f.next.toChars());
.error(funcdecl.loc, "%s `%s` cannot return type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toErrMsg(), f.next.toChars());
if (f.next.isTypeDArray())
errorSupplemental(funcdecl.loc, "slices are specific to D and do not have a counterpart representation in C++", f.next.toChars());
funcdecl.errors = true;
@ -1384,7 +1384,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
{
if (isCppNonMappableType(param.type.toBasetype(), param))
{
.error(funcdecl.loc, "%s `%s` cannot have parameter of type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, param.type.toChars());
.error(funcdecl.loc, "%s `%s` cannot have parameter of type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toErrMsg(), param.type.toChars());
if (param.type.toBasetype().isTypeSArray())
errorSupplemental(funcdecl.loc, "perhaps use a `%s*` type instead",
param.type.nextOf().mutableOf().unSharedOf().toChars());
@ -1741,7 +1741,7 @@ extern (D) bool checkClosure(FuncDeclaration fd)
}
a.push(f);
.errorSupplemental(f.loc, "%s `%s` closes over variable `%s`",
f.kind, f.toPrettyChars(), v.toChars());
f.kind, f.toErrMsg(), v.toChars());
if (v.ident != Id.This)
.errorSupplemental(v.loc, "`%s` declared here", v.toChars());

View file

@ -20,6 +20,7 @@ import dmd.expressionsem;
import dmd.func;
import dmd.funcsem;
import dmd.globals;
import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.init;
@ -346,12 +347,12 @@ bool discardValue(Expression e)
BinExp tmp = e.isBinExp();
assert(tmp);
error(e.loc, "the result of the equality expression `%s` is discarded", e.toChars());
error(e.loc, "the result of the equality expression `%s` is discarded", e.toErrMsg());
bool seenSideEffect = false;
foreach(expr; [tmp.e1, tmp.e2])
{
if (hasSideEffect(expr)) {
errorSupplemental(expr.loc, "note that `%s` may have a side effect", expr.toChars());
errorSupplemental(expr.loc, "note that `%s` may have a side effect", expr.toErrMsg());
seenSideEffect |= true;
}
}
@ -359,7 +360,7 @@ bool discardValue(Expression e)
default:
break;
}
error(e.loc, "`%s` has no effect", e.toChars());
error(e.loc, "`%s` has no effect", e.toErrMsg());
return true;
}

View file

@ -664,7 +664,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
const olderrors = global.startGagging();
discardValue(fs.increment);
if (global.endGagging(olderrors))
deprecation(fs.increment.loc, "`%s` has no effect", fs.increment.toChars());
deprecation(fs.increment.loc, "`%s` has no effect", fs.increment.toErrMsg());
if (checkNonAssignmentArrayOp(fs.increment))
fs.increment = ErrorExp.get();
fs.increment = fs.increment.optimize(WANTvalue);
@ -2604,7 +2604,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
//errors = true;
}
if (global.endGagging(olderrors))
deprecation(rs.exp.loc, "`%s` has no effect", rs.exp.toChars());
deprecation(rs.exp.loc, "`%s` has no effect", rs.exp.toErrMsg());
/* Replace:
* return exp;

View file

@ -1187,7 +1187,7 @@ private const(char)* getParamError(TypeFunction tf, Expression arg, Parameter pa
// only mention rvalue if it's relevant
const rv = !arg.isLvalue() && par.isReference();
buf.printf("cannot pass %sargument `%s` of type `%s` to parameter `%s`",
rv ? "rvalue ".ptr : "".ptr, arg.toChars(), at,
rv ? "rvalue ".ptr : "".ptr, arg.toErrMsg(), at,
parameterToChars(par, tf, qual));
return buf.extractChars();
}
@ -2329,7 +2329,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
{
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.toErrMsg(), e.type.toChars(), errTxt, fparam.type.toChars(), fparam.toChars());
}
e = e.implicitCastTo(sc, fparam.type);
@ -4738,7 +4738,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
{
if (e.op == EXP.type)
{
error(e.loc, "`%s` is not an expression", e.toChars());
error(e.loc, "`%s` is not an expression", e.toErrMsg());
return ErrorExp.get();
}
else if (mt.dim.toUInteger() < 1 && checkUnsafeDotExp(sc, e, ident, flag))
@ -4787,7 +4787,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
}
if (e.op == EXP.type && (ident == Id.length || ident == Id.ptr))
{
error(e.loc, "`%s` is not an expression", e.toChars());
error(e.loc, "`%s` is not an expression", e.toErrMsg());
return ErrorExp.get();
}
if (ident == Id.length)
@ -5214,7 +5214,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
Declaration d = s.isDeclaration();
if (!d)
{
error(e.loc, "`%s.%s` is not a declaration", e.toChars(), ident.toChars());
error(e.loc, "`%s.%s` is not a declaration", e.toErrMsg(), ident.toChars());
return ErrorExp.get();
}
@ -5647,7 +5647,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
Declaration d = s.isDeclaration();
if (!d)
{
error(e.loc, "`%s.%s` is not a declaration", e.toChars(), ident.toChars());
error(e.loc, "`%s.%s` is not a declaration", e.toErrMsg(), ident.toChars());
return ErrorExp.get();
}