cmd/internal/gc: improve "type *X has no field or method M" message · golang/go@d4bb72b (original) (raw)

`@@ -915,11 +915,26 @@ OpSwitch:

`

915

915

`return

`

916

916

` }

`

917

917

``

918

``

`-

if !lookdot(n, t, 0) {

`

919

``

`-

if lookdot(n, t, 1) {

`

``

918

`+

if lookdot(n, t, 0) == nil {

`

``

919

`+

// Legitimate field or method lookup failed, try to explain the error

`

``

920

`+

switch {

`

``

921

`+

case isnilinter(t):

`

``

922

`+

Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)

`

``

923

+

``

924

`+

case Isptr[t.Etype] && Isinter(t.Type):

`

``

925

`+

// Pointer to interface is almost always a mistake.

`

``

926

`+

Yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)

`

``

927

+

``

928

`+

case lookdot(n, t, 1) != nil:

`

``

929

`+

// Field or method matches by name, but it is not exported.

`

920

930

`Yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Right.Sym)

`

921

``

`-

} else {

`

922

``

`-

Yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Right.Sym)

`

``

931

+

``

932

`+

default:

`

``

933

`+

if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.

`

``

934

`+

Yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Right.Sym, mt.Sym)

`

``

935

`+

} else {

`

``

936

`+

Yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Right.Sym)

`

``

937

`+

}

`

923

938

` }

`

924

939

`n.Type = nil

`

925

940

`return

`

`@@ -2391,6 +2406,9 @@ func lookdot1(errnode *Node, s *Sym, t *Type, f *Type, dostrcmp int) *Type {

`

2391

2406

`if dostrcmp != 0 && f.Sym.Name == s.Name {

`

2392

2407

`return f

`

2393

2408

` }

`

``

2409

`+

if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {

`

``

2410

`+

return f

`

``

2411

`+

}

`

2394

2412

`if f.Sym != s {

`

2395

2413

`continue

`

2396

2414

` }

`

`@@ -2461,7 +2479,7 @@ func derefall(t *Type) *Type {

`

2461

2479

`return t

`

2462

2480

`}

`

2463

2481

``

2464

``

`-

func lookdot(n *Node, t *Type, dostrcmp int) bool {

`

``

2482

`+

func lookdot(n *Node, t *Type, dostrcmp int) *Type {

`

2465

2483

`s := n.Right.Sym

`

2466

2484

``

2467

2485

`dowidth(t)

`

`@@ -2481,6 +2499,10 @@ func lookdot(n *Node, t *Type, dostrcmp int) bool {

`

2481

2499

` }

`

2482

2500

``

2483

2501

`if f1 != nil {

`

``

2502

`+

if dostrcmp > 1 {

`

``

2503

`+

// Already in the process of diagnosing an error.

`

``

2504

`+

return f1

`

``

2505

`+

}

`

2484

2506

`if f2 != nil {

`

2485

2507

`Yyerror("%v is both field and method", n.Right.Sym)

`

2486

2508

` }

`

`@@ -2500,10 +2522,14 @@ func lookdot(n *Node, t *Type, dostrcmp int) bool {

`

2500

2522

`n.Op = ODOTINTER

`

2501

2523

` }

`

2502

2524

``

2503

``

`-

return true

`

``

2525

`+

return f1

`

2504

2526

` }

`

2505

2527

``

2506

2528

`if f2 != nil {

`

``

2529

`+

if dostrcmp > 1 {

`

``

2530

`+

// Already in the process of diagnosing an error.

`

``

2531

`+

return f2

`

``

2532

`+

}

`

2507

2533

`tt := n.Left.Type

`

2508

2534

`dowidth(tt)

`

2509

2535

`rcvr := getthisx(f2.Type).Type.Type

`

`@@ -2543,7 +2569,7 @@ func lookdot(n *Node, t *Type, dostrcmp int) bool {

`

2543

2569

`// It is invalid to automatically dereference a named pointer type when selecting a method.

`

2544

2570

`// Make n->left == ll to clarify error message.

`

2545

2571

`n.Left = ll

`

2546

``

`-

return false

`

``

2572

`+

return nil

`

2547

2573

` }

`

2548

2574

` }

`

2549

2575

``

`@@ -2554,10 +2580,10 @@ func lookdot(n *Node, t *Type, dostrcmp int) bool {

`

2554

2580

`// print("lookdot found [%p] %T\n", f2->type, f2->type);

`

2555

2581

`n.Op = ODOTMETH

`

2556

2582

``

2557

``

`-

return true

`

``

2583

`+

return f2

`

2558

2584

` }

`

2559

2585

``

2560

``

`-

return false

`

``

2586

`+

return nil

`

2561

2587

`}

`

2562

2588

``

2563

2589

`func nokeys(l *NodeList) bool {

`