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: accepts invalid type T = interface{ f(T) } #23139

Closed
griesemer opened this issue Dec 14, 2017 · 10 comments
Closed

go/types: accepts invalid type T = interface{ f(T) } #23139

griesemer opened this issue Dec 14, 2017 · 10 comments
Assignees
Milestone

Comments

@griesemer
Copy link
Contributor

@griesemer griesemer commented Dec 14, 2017

cmd/compile rejects it as an invalid recursive type declaration; go/types accepts it (but T is an invalid type). Should it be valid?

@griesemer griesemer added this to the Go1.11 milestone Dec 14, 2017
@griesemer griesemer self-assigned this Dec 14, 2017
@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Dec 14, 2017

Loading

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 14, 2017

If that is valid, then it seems like mutually-recursive aliases should be valid too.
(Consider https://play.golang.org/p/osIdGepuAc vs. https://play.golang.org/p/vs5gMnTe7P.)

Mutually-recursive aliases would address the problem I described in #8082 (comment).

Loading

@jimmyfrasche
Copy link
Member

@jimmyfrasche jimmyfrasche commented Dec 14, 2017

@griesemer

If this were valid, would it makes sense for

type LL = struct {
  next *LL
}

to be valid as well?

Loading

@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Dec 14, 2017

@jimmyfrasche Indeed. It appears that go/types correctly types this unnamed linked list type, but there's an issue with interfaces.

Loading

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Dec 15, 2017

gccgo also rejects this:

foo.go:3:6: error: invalid recursive alias ‘T’
 type T = interface{ f(T) }
      ^

The type alias proposal at https://github.com/golang/proposal/blob/master/design/18130-type-alias.md seems fairly clear that this is invalid.

Loading

@jimmyfrasche
Copy link
Member

@jimmyfrasche jimmyfrasche commented Dec 15, 2017

Specifically https://github.com/golang/proposal/blob/master/design/18130-type-alias.md#type-cycles

Of those type T = *T is the only one that is objectively wrong.

The examples here could be given sensible meaning, though it wouldn't be possible to write out the equivalent literal type because infinity.

This came up in the context of #8082 which would require similar machinery to support self-referential interface definitions.

Loading

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 15, 2017

Of those type T = *T is the only one that is objectively wrong.

That one isn't obviously wrong either. The analogous declaration works with defined types: https://play.golang.org/p/ID9xg3BBtT

Loading

@jimmyfrasche
Copy link
Member

@jimmyfrasche jimmyfrasche commented Dec 15, 2017

@bcmills it feels different than the case for defined types in some fundamental way but attempting to articulate why fails me in a way that makes me suspect that you're right. However, if later someone proves it wrong I reserve the right to say, "Aha!" :).

Loading

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 15, 2017

The justification given in the alias doc for prohibiting recursive aliases is that ‘aliases must be possible to “expand out”’.

Allowing recursive interfaces would mean that there exist type aliases for which there is no equivalent, finite non-alias type literal. I'm ok with that, but it's certainly not a trivial property: it would mean, for example, that a function that prints out a Go type by traversing it recursively would have to break that recursion somehow.

Loading

@griesemer griesemer changed the title go/types: investigate type T = interface{ f(T) } go/types: accepts invalid type T = interface{ f(T) } Jan 11, 2018
@gopherbot
Copy link

@gopherbot gopherbot commented May 31, 2018

Change https://golang.org/cl/115455 mentions this issue: go/types: use color-marking based cycle detection at package level

Loading

@gopherbot gopherbot closed this in 462c182 May 31, 2018
@golang golang locked and limited conversation to collaborators May 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants