Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types: self-reference within type parameter constraints #46461

Open
mdempsky opened this issue May 30, 2021 · 3 comments
Open

go/types: self-reference within type parameter constraints #46461

mdempsky opened this issue May 30, 2021 · 3 comments
Assignees
Milestone

Comments

@mdempsky
Copy link
Member

@mdempsky mdempsky commented May 30, 2021

This test case sends go/types into an infinite recursion: https://go2goplay.golang.org/p/fpWup_pjUzi

type T[U interface{ M() T }] int

type X int
func (X) M() T[X] { return 0 }

Two questions:

  1. Are recursive type parameters like this supposed to work? If so, this has implications on extending the go/types API and export data format to support type parameters (e.g., see also #46449 (comment)).

  2. Also if so, shouldn't interface{ M() T } actually be interface{ M() T[U] }? However, go/types explicitly rejects the latter.

/cc @griesemer @ianlancetaylor @findleyr @bcmills

@mdempsky mdempsky added this to the Go1.18 milestone May 30, 2021
@mdempsky mdempsky changed the title go/types: self-reference within type parameters go/types: self-reference within type parameter constraints May 30, 2021
@findleyr
Copy link
Contributor

@findleyr findleyr commented May 31, 2021

See also #45550, which is similar but manifests differently (stack overflow vs timeout).

My attempt to answer your questions:

  1. I'm not sure, but recursive constraints are sufficiently mind-bending that perhaps they should be explicitly disallowed.
  2. Yes, the use of the generic type T in a result parameter should be rejected. I suspect we never get to that point when type checking.
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 31, 2021

Certainly type T[U interface{ M() T }] int is incorrect.

It seems to me that type T[U interface{ M() T[U] }] int should be accepted. A constraint should be able to refer to the type being defined at least in cases where a type can refer to itself. I also think it's OK if we give an error for this for now.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jun 2, 2021

types2 accepts

type T[U interface{ M() T[U] }] int

type X int
func (X) M() T[X] { return 0 }

which I believe is correct code and (eventually) should be accepted. Currently we have an endless recursion.

@griesemer griesemer self-assigned this Jun 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants