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
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@griesemer
Copy link
Contributor

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 the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 14, 2017
@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

cc @jimmyfrasche

@bcmills
Copy link
Contributor

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

@jimmyfrasche
Copy link
Member

@griesemer

If this were valid, would it makes sense for

type LL = struct {
  next *LL
}

to be valid as well?

@griesemer
Copy link
Contributor Author

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

@ianlancetaylor
Copy link
Contributor

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.

@jimmyfrasche
Copy link
Member

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.

@bcmills
Copy link
Contributor

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

@jimmyfrasche
Copy link
Member

@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!" :).

@bcmills
Copy link
Contributor

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.

@griesemer griesemer added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jan 11, 2018
@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

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

@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.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants