Improve 'no property' error suggestions for pointers (#21087)

This commit is contained in:
Dennis 2025-03-26 08:43:36 +01:00 committed by GitHub
parent c26b03fba2
commit 3142290b6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 46 additions and 46 deletions

View file

@ -3418,8 +3418,10 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
}
Dsymbol s = null;
if (mt.ty == Tstruct || mt.ty == Tclass || mt.ty == Tenum)
s = mt.toDsymbol(null);
auto derefType = mt.isTypePointer() ? mt.nextOf() : mt;
if (derefType.isTypeStruct() || derefType.isTypeClass() || derefType.isTypeEnum())
s = derefType.toDsymbol(null);
if (s)
s = s.search_correct(ident);
if (s && !symbolIsVisible(scope_, s))
@ -3429,18 +3431,21 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
return ErrorExp.get();
if (s)
error(loc, "no property `%s` for type `%s`, did you mean `%s`?", ident.toChars(), mt.toChars(), s.toPrettyChars());
{
error(loc, "no property `%s` for type `%s`", ident.toErrMsg(), mt.toErrMsg());
errorSupplemental(s.loc, "did you mean `%s`?", ident == s.ident ? s.toPrettyChars() : s.toErrMsg());
}
else if (ident == Id.opCall && mt.ty == Tclass)
error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toChars(), mt.toChars(), mt.toPrettyChars());
error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toErrMsg(), mt.toErrMsg(), mt.toPrettyChars());
else if (const n = importHint(ident.toString()))
error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toChars(), mt.toChars(), cast(int)n.length, n.ptr);
error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toErrMsg(), mt.toErrMsg(), cast(int)n.length, n.ptr);
else
{
if (src)
{
error(loc, "no property `%s` for `%s` of type `%s`",
ident.toChars(), src.toChars(), mt.toPrettyChars(true));
ident.toErrMsg(), src.toErrMsg(), mt.toPrettyChars(true));
auto s2 = scope_.search_correct(ident);
// UFCS
if (s2 && s2.isFuncDeclaration)
@ -3448,30 +3453,17 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
if (s2.ident == ident)
{
errorSupplemental(s2.loc, "cannot call %s `%s` with UFCS because it is not declared at module scope",
s2.kind(), s2.toChars());
s2.kind(), s2.toErrMsg());
}
else
errorSupplemental(s2.loc, "did you mean %s `%s`?",
s2.kind(), s2.toChars());
}
else if (src.type.ty == Tpointer)
{
// structPtr.field
auto tn = (cast(TypeNext) src.type).nextOf();
if (auto as = tn.isAggregate())
{
if (auto s3 = as.search_correct(ident))
{
errorSupplemental(s3.loc, "did you mean %s `%s`?",
s3.kind(), s3.toChars());
}
}
s2.kind(), s2.toErrMsg());
}
}
else
error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
error(loc, "no property `%s` for type `%s`", ident.toErrMsg(), mt.toPrettyChars(true));
if (auto dsym = mt.toDsymbol(scope_))
if (auto dsym = derefType.toDsymbol(scope_))
{
if (auto sym = dsym.isAggregateDeclaration())
{
@ -3497,7 +3489,7 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
}
}
errorSupplemental(dsym.loc, "%s `%s` defined here",
dsym.kind, dsym.toChars());
dsym.kind, dsym.toErrMsg());
}
}

View file

@ -2,10 +2,12 @@
/*
TEST_OUTPUT:
---
fail_compilation/checkimports2.d(25): Error: no property `X` for type `checkimports2.B`, did you mean `imports.imp2.X`?
fail_compilation/checkimports2.d(25): while evaluating: `static assert((B).X == 0)`
fail_compilation/checkimports2.d(26): Error: no property `Y` for type `checkimports2.B`, did you mean `imports.imp2.Y`?
fail_compilation/checkimports2.d(26): while evaluating: `static assert((B).Y == 2)`
fail_compilation/checkimports2.d(27): Error: no property `X` for type `checkimports2.B`
fail_compilation/imports/imp2.d(3): did you mean `imports.imp2.X`?
fail_compilation/checkimports2.d(27): while evaluating: `static assert((B).X == 0)`
fail_compilation/checkimports2.d(28): Error: no property `Y` for type `checkimports2.B`
fail_compilation/imports/imp2.d(4): did you mean `imports.imp2.Y`?
fail_compilation/checkimports2.d(28): while evaluating: `static assert((B).Y == 2)`
---
*/

View file

@ -3,11 +3,14 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail18219.d(17): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
fail_compilation/fail18219.d(18): Error: no property `Bar` for type `a18219.AST`
fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`
fail_compilation/imports/b18219.d(3): did you mean `b18219.Foobar`?
fail_compilation/fail18219.d(21): Error: no property `Bar` for type `a18219.AST`
fail_compilation/imports/a18219.d(3): struct `AST` defined here
fail_compilation/fail18219.d(19): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
fail_compilation/fail18219.d(22): Error: no property `fun` for type `AST`
fail_compilation/imports/b18219.d(15): did you mean `b18219.fun`?
fail_compilation/fail18219.d(23): Error: no property `Foobar` for type `AST`
fail_compilation/imports/b18219.d(3): did you mean `b18219.Foobar`?
---
*/
import imports.a18219;

View file

@ -5,10 +5,10 @@ fail_compilation/fail19103.d(14): Error: no property `puts` for `new C` of type
fail_compilation/fail19103.d(26): class `C` defined here
fail_compilation/fail19103.d(16): Error: no property `puts` for `s1` of type `fail19103.S1`
fail_compilation/fail19103.d(30): struct `S1` defined here
fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`
$p:druntime/import/core/stdc/stdio.d$($n$): did you mean `core.stdc.stdio.puts`?
---
*/
void main()
{
(new C).puts("OK."); // Error: no property puts for type test.C, did you mean core.stdc.stdio.puts(T...)(T args)?

View file

@ -3,16 +3,16 @@ EXTRA_FILES: imports/fail347a.d
TEST_OUTPUT:
---
fail_compilation/fail347.d(26): Error: undefined identifier `bbr`, did you mean variable `bar`?
fail_compilation/fail347.d(27): Error: no property `ofo` for type `S`, did you mean `fail347.S.foo`?
fail_compilation/fail347.d(29): Error: no property `fool` for `sp` of type `fail347.S*`
fail_compilation/fail347.d(20): did you mean variable `foo`?
fail_compilation/fail347.d(27): Error: no property `ofo` for type `S`
fail_compilation/fail347.d(20): did you mean `foo`?
fail_compilation/fail347.d(29): Error: no property `fool` for type `S*`
fail_compilation/fail347.d(20): did you mean `foo`?
fail_compilation/fail347.d(30): Error: undefined identifier `strlenx`, did you mean function `strlen`?
fail_compilation/fail347.d(31): Error: no property `strlenx` for `"hello"` of type `string`
fail_compilation/imports/fail347a.d(3): did you mean function `strlen`?
---
*/
//import core.stdc.string;
import imports.fail347a;
struct S

View file

@ -1,7 +1,8 @@
/* TEST_OUTPUT:
---
fail_compilation/ice19755.d(11): Error: no property `x` for `self` of type `ice19755.Thunk!int*`
fail_compilation/ice19755.d(16): Error: template instance `ice19755.Thunk!int` error instantiating
fail_compilation/ice19755.d(12): Error: no property `x` for `self` of type `ice19755.Thunk!int*`
fail_compilation/ice19755.d(8): struct `Thunk` defined here
fail_compilation/ice19755.d(17): Error: template instance `ice19755.Thunk!int` error instantiating
---
*/
struct Thunk(Dummy) {

View file

@ -2,10 +2,12 @@
EXTRA_FILES: imports/imp1.d imports/imp2.d
TEST_OUTPUT:
---
fail_compilation/lookup.d(24): Error: no property `X` for type `lookup.B`, did you mean `imports.imp2.X`?
fail_compilation/lookup.d(24): while evaluating: `static assert((B).X == 0)`
fail_compilation/lookup.d(25): Error: no property `Y` for type `lookup.B`, did you mean `imports.imp2.Y`?
fail_compilation/lookup.d(25): while evaluating: `static assert((B).Y == 2)`
fail_compilation/lookup.d(26): Error: no property `X` for type `lookup.B`
fail_compilation/imports/imp2.d(3): did you mean `imports.imp2.X`?
fail_compilation/lookup.d(26): while evaluating: `static assert((B).X == 0)`
fail_compilation/lookup.d(27): Error: no property `Y` for type `lookup.B`
fail_compilation/imports/imp2.d(4): did you mean `imports.imp2.Y`?
fail_compilation/lookup.d(27): while evaluating: `static assert((B).Y == 2)`
---
*/

View file

@ -1,9 +1,9 @@
/* TEST_OUTPUT:
---
fail_compilation/mixinprop.d(12): Error: no property `x` for `mixin Foo!() F;
` of type `void`
fail_compilation/mixinprop.d(12): Error: no property `x` for `mixin Foo!() F;` of type `void`
---
*/
mixin template Foo() { }
void main()