Skip to content

cmd/compile: suggest clearer error regarding when a non-pointer type cannot be used as type parameter #51515

@changkun

Description

@changkun

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

No one assigned

    Labels

    NeedsInvestigationSomeone 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.

    Type

    No type

    Projects

    Status

    Triage Backlog

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions