-
Notifications
You must be signed in to change notification settings - Fork 18k
go/types: accepts invalid type T = interface{ f(T) }
#23139
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
Comments
If that is valid, then it seems like mutually-recursive aliases should be valid too. Mutually-recursive aliases would address the problem I described in #8082 (comment). |
If this were valid, would it makes sense for
to be valid as well? |
@jimmyfrasche Indeed. It appears that go/types correctly types this unnamed linked list type, but there's an issue with interfaces. |
gccgo also rejects this:
The type alias proposal at https://github.com/golang/proposal/blob/master/design/18130-type-alias.md seems fairly clear that this is invalid. |
Specifically https://github.com/golang/proposal/blob/master/design/18130-type-alias.md#type-cycles Of those 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. |
That one isn't obviously wrong either. The analogous declaration works with defined types: https://play.golang.org/p/ID9xg3BBtT |
@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!" :). |
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. |
type T = interface{ f(T) }
type T = interface{ f(T) }
Change https://golang.org/cl/115455 mentions this issue: |
cmd/compile rejects it as an invalid recursive type declaration; go/types accepts it (but T is an invalid type). Should it be valid?
The text was updated successfully, but these errors were encountered: