go/types, types2: better error if there's a field with the name of a missing method

Fixes #51025.

Change-Id: I469a705e7da059e7ac0b12b05beb9ed5d3617396
Reviewed-on: https://go-review.googlesource.com/c/go/+/438856
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2022-10-04 18:40:38 -07:00 committed by Gopher Robot
parent 19095e109d
commit 79d0d330a9
3 changed files with 48 additions and 0 deletions

View File

@ -395,6 +395,11 @@ func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
return "(" + check.interfacePtrError(T) + ")"
}
obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
if fld, _ := obj.(*Var); fld != nil {
return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
}
return check.sprintf("(missing %s)", mname)
}

View File

@ -395,6 +395,11 @@ func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
return "(" + check.interfacePtrError(T) + ")"
}
obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
if fld, _ := obj.(*Var); fld != nil {
return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
}
return check.sprintf("(missing %s)", mname)
}

View File

@ -0,0 +1,38 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
var _ interface{ m() } = struct /* ERROR m is a field, not a method */ {
m func()
}{}
var _ interface{ m() } = & /* ERROR m is a field, not a method */ struct {
m func()
}{}
var _ interface{ M() } = struct /* ERROR missing method M */ {
m func()
}{}
var _ interface{ M() } = & /* ERROR missing method M */ struct {
m func()
}{}
// test case from issue
type I interface{ m() }
type T struct{ m func() }
type M struct{}
func (M) m() {}
func _() {
var t T
var m M
var i I
i = m
i = t // ERROR m is a field, not a method
_ = i
}