-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
Consider this example:
package main
type C interface {
Foo()
Bar()
}
type A struct{}
func (a A) Foo() {}
func (a A) Bar() {}
type B struct{}
func (b B) Foo() {}
func (b *B) Bar() {}
func Want[T C]() (x T) { return }
func main() {
Want[A]() // OK
Want[B]() // ERROR
}We may consider A and B both implements C. But the code produces error:
B does not implement C (Bar method has pointer receiver)
After parse the spec (precise but complex):
According to the spec (https://tip.golang.org/ref/spec#Implementing_an_interface) regarding the definition of a type `T` implements interface `I`:
A type T implements an interface I if
T is not an interface and is an element of the type set of I; or...
Type set describes:
... an interface specifies a (possibly empty) list of methods.
The type set defined by such an interface is the set of types which
implement all of those methods, and the corresponding [method set](https://tip.golang.org/ref/spec#Method_sets) consists exactly of
the methods specified by the interface.
Method set describes:
The method set of a pointer to a defined type T (where T is neither
a pointer nor an interface) is the set of all methods declared with
receiver *T or T.
The preceived understanding is:
Let T be a struct type. A pointer (*T) to a defined type T. Since T contains a set of methods (I) declared with receiver *T or T, hence I is a type set, and *T is an element of the type set I.
It is clear that only a pointer type is an element of a type set C (which is a method set with receiver *T or T), but this observation is much less intuitive to be aware in the beginning.
Maybe a more clear error message might be:
B does not implement C because B has a pointer receiver method (*B).Bar(),
and only *B can be used as a type parameter of C.
Previously related #44201
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Type
Projects
Status
Triage Backlog