Use errorSupplemental for long errors with 2 sentences (#21060)

This commit is contained in:
Dennis 2025-03-22 23:03:20 +01:00 committed by GitHub
parent 31bfe613b0
commit 7fb4d613af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 61 additions and 31 deletions

View file

@ -3183,7 +3183,8 @@ public:
if (cmp == -1) if (cmp == -1)
{ {
char dir = (e.op == EXP.greaterThan || e.op == EXP.greaterOrEqual) ? '<' : '>'; 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; result = CTFEExp.cantexp;
return; return;
} }

View file

@ -394,7 +394,10 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
if (needInterpret) if (needInterpret)
i.exp = i.exp.ctfeInterpret(); i.exp = i.exp.ctfeInterpret();
if (i.exp.op == EXP.voidExpression) 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 else
{ {

View file

@ -1072,7 +1072,8 @@ Expression optimize(Expression e, int result, bool keepLvalue = false)
// All negative integral powers are illegal. // All negative integral powers are illegal.
if (e.e1.type.isIntegral() && (e.e2.op == EXP.int64) && cast(sinteger_t)e.e2.toInteger() < 0) 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(); return errorReturn();
} }
// If e2 *could* have been an integer, make it one. // If e2 *could* have been an integer, make it one.

View file

@ -4081,7 +4081,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
*/ */
if (isParameters(&peekt)) 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 else
error("unexpected `(` in declarator"); error("unexpected `(` in declarator");
@ -8468,7 +8469,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
nextToken(); nextToken();
if (token.value == TOK.identifier && peekNext() == TOK.leftParenthesis) 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(); nextToken();
Token* tempTok = peekPastParen(&token); Token* tempTok = peekPastParen(&token);
memcpy(&token, tempTok, Token.sizeof); memcpy(&token, tempTok, Token.sizeof);

View file

@ -287,7 +287,10 @@ private extern(C++) final class Semantic2Visitor : Visitor
} }
if (hasInvalidEnumInitializer(ei.exp)) 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()) else if (vd._init && vd.isThreadlocal())
@ -298,13 +301,20 @@ private extern(C++) final class Semantic2Visitor : Visitor
{ {
ExpInitializer ei = vd._init.isExpInitializer(); ExpInitializer ei = vd._init.isExpInitializer();
if (ei && ei.exp.op == EXP.classReference) 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()) else if (vd.type.ty == Tpointer && vd.type.nextOf().ty == Tstruct && vd.type.nextOf().isMutable() && !vd.type.nextOf().isShared())
{ {
ExpInitializer ei = vd._init.isExpInitializer(); ExpInitializer ei = vd._init.isExpInitializer();
if (ei && ei.exp.op == EXP.address && (cast(AddrExp)ei.exp).e1.op == EXP.structLiteral) 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; vd.semanticRun = PASS.semantic2done;

View file

@ -1152,8 +1152,9 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
printf("expected = x%x, %s.structsize = x%x\n", cast(uint)expected, printf("expected = x%x, %s.structsize = x%x\n", cast(uint)expected,
typeclass.toChars(), cast(uint)typeclass.structsize); 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); typeclass.toChars(), cast(uint)expected, cast(uint)typeclass.structsize);
errorSupplemental(typeclass.loc, "check installation and import paths with `-v` compiler switch");
fatal(); fatal();
} }
} }

View file

@ -1217,8 +1217,9 @@ private void genClassInfoForClass(ClassDeclaration cd, Symbol* sinit)
if (Type.typeinfoclass.structsize != target.classinfosize) if (Type.typeinfoclass.structsize != target.classinfosize)
{ {
debug printf("target.classinfosize = x%x, Type.typeinfoclass.structsize = x%x\n", target.classinfosize, Type.typeinfoclass.structsize); 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); 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(); fatal();
} }
} }
@ -1554,8 +1555,9 @@ private void InterfaceInfoToDt(ref DtBuilder dtb, InterfaceDeclaration id)
{ {
if (Type.typeinfoclass.structsize != offset) 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); 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(); fatal();
} }
} }

View file

@ -1,8 +1,10 @@
/* /*
TEST_OUTPUT: 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(16): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer
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): 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
--- ---
*/ */

View file

@ -1,7 +1,8 @@
/* /*
TEST_OUTPUT: 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
--- ---
*/ */

View file

@ -2,8 +2,9 @@
/* /*
TEST_OUTPUT: TEST_OUTPUT:
--- ---
fail_compilation/fail16.d(19): Error: function declaration without return type. (Note that constructors are always named `this`) fail_compilation/fail16.d(20): Error: function declaration without return type
fail_compilation/fail16.d(19): Error: variable name expected after type `bar!(typeof(X))(X)`, not `;` 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 `;`
--- ---
*/ */

View file

@ -2,7 +2,8 @@
// PERMUTE_ARGS: -lowmem // PERMUTE_ARGS: -lowmem
/* TEST_OUTPUT: /* 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 class C23439

View file

@ -1,14 +1,15 @@
/* TEST_OUTPUT: /* TEST_OUTPUT:
--- ---
fail_compilation/failcontracts.d(17): Error: missing `{ ... }` for function literal fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function literal
fail_compilation/failcontracts.d(17): Error: semicolon expected following auto declaration, not `bode` fail_compilation/failcontracts.d(18): 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(19): Error: function declaration without return type
fail_compilation/failcontracts.d(18): Error: variable name expected after type `test1()`, not `bode` fail_compilation/failcontracts.d(19): Note that constructors are always named `this`
fail_compilation/failcontracts.d(18): Error: semicolon expected following function declaration, not `bode` 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(19): Error: semicolon expected following function declaration, not `bode`
fail_compilation/failcontracts.d(21): Error: unexpected `(` in declarator fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode`
fail_compilation/failcontracts.d(21): Error: found `T` when expecting `)` fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator
fail_compilation/failcontracts.d(21): Error: expected `{`, not `;` for enum declaration fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)`
fail_compilation/failcontracts.d(22): Error: expected `{`, not `;` for enum declaration
--- ---
*/ */

View file

@ -1,8 +1,9 @@
/* /*
TEST_OUTPUT: TEST_OUTPUT:
--- ---
fail_compilation/ice11153.d(11): Error: function declaration without return type. (Note that constructors are always named `this`) fail_compilation/ice11153.d(12): Error: function declaration without return type
fail_compilation/ice11153.d(11): Error: variable name expected after type `foo()`, not `{` 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 `{`
--- ---
*/ */

View file

@ -1,9 +1,11 @@
/* /*
TEST_OUTPUT: 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(41): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct
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(41): 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(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)`
--- ---
*/ */

View file

@ -2,7 +2,8 @@
EXTRA_FILES: imports/imp19661.d EXTRA_FILES: imports/imp19661.d
TEST_OUTPUT: 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
--- ---
*/ */