From 7fb4d613afb95a97f19cfab995e3d2ba920d9f2e Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 22 Mar 2025 23:03:20 +0100 Subject: [PATCH] Use errorSupplemental for long errors with 2 sentences (#21060) --- compiler/src/dmd/dinterpret.d | 3 ++- compiler/src/dmd/initsem.d | 5 ++++- compiler/src/dmd/optimize.d | 3 ++- compiler/src/dmd/parse.d | 6 ++++-- compiler/src/dmd/semantic2.d | 16 +++++++++++++--- compiler/src/dmd/todt.d | 3 ++- compiler/src/dmd/toobj.d | 6 ++++-- compiler/test/fail_compilation/fail11714.d | 6 ++++-- compiler/test/fail_compilation/fail15361.d | 3 ++- compiler/test/fail_compilation/fail16.d | 5 +++-- compiler/test/fail_compilation/fail23439.d | 3 ++- compiler/test/fail_compilation/failcontracts.d | 17 +++++++++-------- compiler/test/fail_compilation/ice11153.d | 5 +++-- compiler/test/fail_compilation/test15989.d | 8 +++++--- compiler/test/fail_compilation/test19661.d | 3 ++- 15 files changed, 61 insertions(+), 31 deletions(-) diff --git a/compiler/src/dmd/dinterpret.d b/compiler/src/dmd/dinterpret.d index 641e8a0420..b223975f38 100644 --- a/compiler/src/dmd/dinterpret.d +++ b/compiler/src/dmd/dinterpret.d @@ -3183,7 +3183,8 @@ public: if (cmp == -1) { char dir = (e.op == EXP.greaterThan || e.op == EXP.greaterOrEqual) ? '<' : '>'; - error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars()); + error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE."); + errorSupplemental(e.loc, "to check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars()); result = CTFEExp.cantexp; return; } diff --git a/compiler/src/dmd/initsem.d b/compiler/src/dmd/initsem.d index d37c85ad46..8737e0f646 100644 --- a/compiler/src/dmd/initsem.d +++ b/compiler/src/dmd/initsem.d @@ -394,7 +394,10 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn if (needInterpret) i.exp = i.exp.ctfeInterpret(); if (i.exp.op == EXP.voidExpression) - error(i.loc, "variables cannot be initialized with an expression of type `void`. Use `void` initialization instead."); + { + error(i.loc, "variables cannot be initialized with an expression of type `void`"); + errorSupplemental(i.loc, "only `= void;` is allowed, which prevents default initialization"); + } } else { diff --git a/compiler/src/dmd/optimize.d b/compiler/src/dmd/optimize.d index 7f2b030e5b..2e40f1826c 100644 --- a/compiler/src/dmd/optimize.d +++ b/compiler/src/dmd/optimize.d @@ -1072,7 +1072,8 @@ Expression optimize(Expression e, int result, bool keepLvalue = false) // All negative integral powers are illegal. if (e.e1.type.isIntegral() && (e.e2.op == EXP.int64) && cast(sinteger_t)e.e2.toInteger() < 0) { - error(e.loc, "cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars()); + error(e.loc, "cannot raise `%s` to a negative integer power.", e.e1.type.toBasetype().toChars()); + errorSupplemental(e.loc, "did you mean `(cast(real)%s)^^%s` ?", e.e1.toChars(), e.e2.toChars()); return errorReturn(); } // If e2 *could* have been an integer, make it one. diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index 33f2a1e116..f031777238 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -4081,7 +4081,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer */ if (isParameters(&peekt)) { - error("function declaration without return type. (Note that constructors are always named `this`)"); + error("function declaration without return type"); + errorSupplemental("Note that constructors are always named `this`"); } else error("unexpected `(` in declarator"); @@ -8468,7 +8469,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); if (token.value == TOK.identifier && peekNext() == TOK.leftParenthesis) { - error(loc, "unexpected `(` after `%s`, inside `is` expression. Try enclosing the contents of `is` with a `typeof` expression", token.toChars()); + error(loc, "unexpected `(` after `%s`, inside `is` expression", token.toChars()); + errorSupplemental("try enclosing the contents of `is` with a `typeof` expression"); nextToken(); Token* tempTok = peekPastParen(&token); memcpy(&token, tempTok, Token.sizeof); diff --git a/compiler/src/dmd/semantic2.d b/compiler/src/dmd/semantic2.d index 4b410a17ca..a1bb7e895b 100644 --- a/compiler/src/dmd/semantic2.d +++ b/compiler/src/dmd/semantic2.d @@ -287,7 +287,10 @@ private extern(C++) final class Semantic2Visitor : Visitor } if (hasInvalidEnumInitializer(ei.exp)) - .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.", vd.kind, vd.toPrettyChars); + { + .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct", vd.kind, vd.toPrettyChars); + .errorSupplemental(vd.loc, "use static const variable instead"); + } } } else if (vd._init && vd.isThreadlocal()) @@ -298,13 +301,20 @@ private extern(C++) final class Semantic2Visitor : Visitor { ExpInitializer ei = vd._init.isExpInitializer(); if (ei && ei.exp.op == EXP.classReference) - .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars); + { + .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer", vd.kind, vd.toPrettyChars); + .errorSupplemental(vd.loc, "use `static this()` to initialize instead"); + } } else if (vd.type.ty == Tpointer && vd.type.nextOf().ty == Tstruct && vd.type.nextOf().isMutable() && !vd.type.nextOf().isShared()) { ExpInitializer ei = vd._init.isExpInitializer(); if (ei && ei.exp.op == EXP.address && (cast(AddrExp)ei.exp).e1.op == EXP.structLiteral) - .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars); + { + .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer", vd.kind, vd.toPrettyChars); + .errorSupplemental(vd.loc, "use `static this()` to initialize instead"); + } + } } vd.semanticRun = PASS.semantic2done; diff --git a/compiler/src/dmd/todt.d b/compiler/src/dmd/todt.d index beab5f4e92..94453eface 100644 --- a/compiler/src/dmd/todt.d +++ b/compiler/src/dmd/todt.d @@ -1152,8 +1152,9 @@ private extern (C++) class TypeInfoDtVisitor : Visitor printf("expected = x%x, %s.structsize = x%x\n", cast(uint)expected, typeclass.toChars(), cast(uint)typeclass.structsize); } - error(typeclass.loc, "`%s`: mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found. Check installation and import paths with -v compiler switch.", + error(typeclass.loc, "`%s`: mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found", typeclass.toChars(), cast(uint)expected, cast(uint)typeclass.structsize); + errorSupplemental(typeclass.loc, "check installation and import paths with `-v` compiler switch"); fatal(); } } diff --git a/compiler/src/dmd/toobj.d b/compiler/src/dmd/toobj.d index e27ce3ceda..943f3ed012 100644 --- a/compiler/src/dmd/toobj.d +++ b/compiler/src/dmd/toobj.d @@ -1217,8 +1217,9 @@ private void genClassInfoForClass(ClassDeclaration cd, Symbol* sinit) if (Type.typeinfoclass.structsize != target.classinfosize) { debug printf("target.classinfosize = x%x, Type.typeinfoclass.structsize = x%x\n", target.classinfosize, Type.typeinfoclass.structsize); - .error(cd.loc, "%s `%s` mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found. Check installation and import paths with -v compiler switch.", + .error(cd.loc, "%s `%s` mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found", cd.kind, cd.toPrettyChars, cast(uint)target.classinfosize, cast(uint)Type.typeinfoclass.structsize); + .errorSupplemental(cd.loc, "check installation and import paths with `-v` compiler switch"); fatal(); } } @@ -1554,8 +1555,9 @@ private void InterfaceInfoToDt(ref DtBuilder dtb, InterfaceDeclaration id) { if (Type.typeinfoclass.structsize != offset) { - .error(id.loc, "%s `%s` mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found. Check installation and import paths with -v compiler switch.", + .error(id.loc, "%s `%s` mismatch between compiler (%d bytes) and object.d or object.di (%d bytes) found", id.kind, id.toPrettyChars, cast(uint)offset, cast(uint)Type.typeinfoclass.structsize); + .errorSupplemental(id.loc, "check installation and import paths with `-v` compiler switch"); fatal(); } } diff --git a/compiler/test/fail_compilation/fail11714.d b/compiler/test/fail_compilation/fail11714.d index abc47087ff..f36f3e5831 100644 --- a/compiler/test/fail_compilation/fail11714.d +++ b/compiler/test/fail_compilation/fail11714.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/fail11714.d(14): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead. -fail_compilation/fail11714.d(21): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead. +fail_compilation/fail11714.d(16): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer +fail_compilation/fail11714.d(16): use `static this()` to initialize instead +fail_compilation/fail11714.d(23): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer +fail_compilation/fail11714.d(23): use `static this()` to initialize instead --- */ diff --git a/compiler/test/fail_compilation/fail15361.d b/compiler/test/fail_compilation/fail15361.d index 8e5f9800a8..aec716556a 100644 --- a/compiler/test/fail_compilation/fail15361.d +++ b/compiler/test/fail_compilation/fail15361.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail15361.d(8): Error: unexpected `(` after `errorize`, inside `is` expression. Try enclosing the contents of `is` with a `typeof` expression +fail_compilation/fail15361.d(9): Error: unexpected `(` after `errorize`, inside `is` expression +fail_compilation/fail15361.d(9): try enclosing the contents of `is` with a `typeof` expression --- */ diff --git a/compiler/test/fail_compilation/fail16.d b/compiler/test/fail_compilation/fail16.d index 4602d3de3b..ce021a95b8 100644 --- a/compiler/test/fail_compilation/fail16.d +++ b/compiler/test/fail_compilation/fail16.d @@ -2,8 +2,9 @@ /* TEST_OUTPUT: --- -fail_compilation/fail16.d(19): Error: function declaration without return type. (Note that constructors are always named `this`) -fail_compilation/fail16.d(19): Error: variable name expected after type `bar!(typeof(X))(X)`, not `;` +fail_compilation/fail16.d(20): Error: function declaration without return type +fail_compilation/fail16.d(20): Note that constructors are always named `this` +fail_compilation/fail16.d(20): Error: variable name expected after type `bar!(typeof(X))(X)`, not `;` --- */ diff --git a/compiler/test/fail_compilation/fail23439.d b/compiler/test/fail_compilation/fail23439.d index b070e581a4..6f16bc1343 100644 --- a/compiler/test/fail_compilation/fail23439.d +++ b/compiler/test/fail_compilation/fail23439.d @@ -2,7 +2,8 @@ // PERMUTE_ARGS: -lowmem /* TEST_OUTPUT: --- -fail_compilation/fail23439.d(13): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead. +fail_compilation/fail23439.d(14): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer +fail_compilation/fail23439.d(14): use `static this()` to initialize instead --- */ class C23439 diff --git a/compiler/test/fail_compilation/failcontracts.d b/compiler/test/fail_compilation/failcontracts.d index b6c3bc906a..749d98f9bd 100644 --- a/compiler/test/fail_compilation/failcontracts.d +++ b/compiler/test/fail_compilation/failcontracts.d @@ -1,14 +1,15 @@ /* TEST_OUTPUT: --- -fail_compilation/failcontracts.d(17): Error: missing `{ ... }` for function literal -fail_compilation/failcontracts.d(17): Error: semicolon expected following auto declaration, not `bode` -fail_compilation/failcontracts.d(18): Error: function declaration without return type. (Note that constructors are always named `this`) -fail_compilation/failcontracts.d(18): Error: variable name expected after type `test1()`, not `bode` -fail_compilation/failcontracts.d(18): Error: semicolon expected following function declaration, not `bode` +fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function literal +fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode` +fail_compilation/failcontracts.d(19): Error: function declaration without return type +fail_compilation/failcontracts.d(19): Note that constructors are always named `this` +fail_compilation/failcontracts.d(19): Error: variable name expected after type `test1()`, not `bode` fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode` -fail_compilation/failcontracts.d(21): Error: unexpected `(` in declarator -fail_compilation/failcontracts.d(21): Error: found `T` when expecting `)` -fail_compilation/failcontracts.d(21): Error: expected `{`, not `;` for enum declaration +fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode` +fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator +fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)` +fail_compilation/failcontracts.d(22): Error: expected `{`, not `;` for enum declaration --- */ diff --git a/compiler/test/fail_compilation/ice11153.d b/compiler/test/fail_compilation/ice11153.d index 826bd8cd7e..936d987c15 100644 --- a/compiler/test/fail_compilation/ice11153.d +++ b/compiler/test/fail_compilation/ice11153.d @@ -1,8 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11153.d(11): Error: function declaration without return type. (Note that constructors are always named `this`) -fail_compilation/ice11153.d(11): Error: variable name expected after type `foo()`, not `{` +fail_compilation/ice11153.d(12): Error: function declaration without return type +fail_compilation/ice11153.d(12): Note that constructors are always named `this` +fail_compilation/ice11153.d(12): Error: variable name expected after type `foo()`, not `{` --- */ diff --git a/compiler/test/fail_compilation/test15989.d b/compiler/test/fail_compilation/test15989.d index 38ca331267..85b74bfad5 100644 --- a/compiler/test/fail_compilation/test15989.d +++ b/compiler/test/fail_compilation/test15989.d @@ -1,9 +1,11 @@ /* TEST_OUTPUT: --- -fail_compilation/test15989.d(39): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct. Use static const variable instead. -fail_compilation/test15989.d(48): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct. Use static const variable instead. -fail_compilation/test15989.d(49): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)` +fail_compilation/test15989.d(41): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct +fail_compilation/test15989.d(41): use static const variable instead +fail_compilation/test15989.d(50): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct +fail_compilation/test15989.d(50): use static const variable instead +fail_compilation/test15989.d(51): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)` --- */ diff --git a/compiler/test/fail_compilation/test19661.d b/compiler/test/fail_compilation/test19661.d index 369c0a8624..712721487c 100644 --- a/compiler/test/fail_compilation/test19661.d +++ b/compiler/test/fail_compilation/test19661.d @@ -2,7 +2,8 @@ EXTRA_FILES: imports/imp19661.d TEST_OUTPUT: --- -fail_compilation/test19661.d(11): Error: variables cannot be initialized with an expression of type `void`. Use `void` initialization instead. +fail_compilation/test19661.d(12): Error: variables cannot be initialized with an expression of type `void` +fail_compilation/test19661.d(12): only `= void;` is allowed, which prevents default initialization --- */