mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Improve 'no property' error suggestions for pointers (#21087)
This commit is contained in:
parent
c26b03fba2
commit
3142290b6f
8 changed files with 46 additions and 46 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue