go: types2, go/types: the scope of a type parameter identifier in a method of a generic type is too large

What version of Go are you using (go version)?

$ go version
go version go1.18rc1 linux/amd64

What did you do?

type T[T any] struct {} // okay

func (T[T]) Bar() {} // error: T is not a generic type

What did you expect to see?

Compiles okay.

What did you see instead?

Fails to compile.

Honestly, the behavior conforms to the tip spec:

The scope of an identifier denoting a type parameter of a generic function or declared by a method receiver is the function body and all parameter lists of the function.

However, I think , for a method of a generic type, the scope should begin after the name of the generic type in the receiver, instead of beginning the start of receiver part.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 18 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Hm. We’re treating the receiver declaration like any other parameter list (including type parameter lists) for simplicity. I suppose we could say:

The scope of an identifier denoting a type parameter of a generic function or declared by a method receiver starts after the function name and ends at the end of the function body.

This seems just as simple, perhaps even simpler. And it would avoid this arguably confusing error; even though I don’t recommend choosing identifiers like this. But traditionally we have been paying attention to the ergonomics of scopes, so I think this warrants some attention.

But it seems that we should be able to make this change later (1.19) as I can’t see how it would invalidate programs that are now possible.

(It’s not an easy change, implementation-wise though, due to the way methods are represented: a method declaration corresponds to an instantiation of the method with the type parameters declared by the receiver which currently requires that the type parameters by the receiver are in scope in the receiver. This allows us to re-use a lot of code; but has also caused trouble. We were planning to change that part of the implementation independently. In any case, I wouldn’t think this to be an impediment to making this spec change.)

@ianlancetaylor @findleyr thoughts?

@go101 The suggestion for the new scope rule I gave seems good enough: the scope of ordinary parameters (including the receiver) is the function body and type parameters are also declared in that block. The same block cannot have the same identifier twice.