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

cmd/go2go: unclear error message for type parameter #40047

Closed
crawshaw opened this issue Jul 5, 2020 · 5 comments
Closed

cmd/go2go: unclear error message for type parameter #40047

crawshaw opened this issue Jul 5, 2020 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@crawshaw
Copy link
Member

crawshaw commented Jul 5, 2020

package main

type X(type T) T

var m = make(map[string]X(int))

func main() {}

Fails to compile with:

type checking failed for main
prog.go2:5:25: cannot use generic type X(type T) without instantiation

Presumably there is an unresolvable ambiguity (though honestly I haven't figured out what it is yet). An extra pair of parentheses makes it work:

package main

type X(type T) T

var m = make(map[string](X(int)))

func main() {}

Assuming this is working as intended, a clearer error message would be nice.

@thepudds
Copy link
Contributor

thepudds commented Jul 5, 2020

Possibly related to #39670 (comment)

@thepudds
Copy link
Contributor

thepudds commented Jul 5, 2020

Taking Robert's type conversion example from that comment, here is a quick attempt to adapt his example to the situation in this issue:

https://play.golang.org/p/cxWiCJ1SskS

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 5, 2020
@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Jul 5, 2020
@griesemer
Copy link
Contributor

@crawshaw The problem here is that map[string]X(int) must be parsed as (map[string]X)(int) for backward-compatibility; i.e., is looks like a conversion. To make it work, we need extra parentheses, as in: map[string](X(int)).

Now, in "type context", we know that it cannot be a conversion and we can do the right thing. For instance, var _ map[string]X(int) doesn't require those extra parentheses.

Arguably, in the make call above, the map type is in "type context". But we don't know this until type-checking time: we cannot know that make actually refers to the built-in make function and not some user-defined version that may possibly be defined in another file of the same package. Thus, the parser cannot know better. The type-checker may be able to re-associate the AST but it's tricky (I haven't thought that through in detail). For the same reason it's not easily possible to provide a better error message: The AST is a call/conversion node, where the LHS is map[string]X and the argument is int - when we look at X we're very far removed from the respective context.

This, and many other problems would go away if our keyboards had one more style of easily accessible parentheses...

@crawshaw
Copy link
Member Author

crawshaw commented Jul 8, 2020

Thanks for the detailed explanation. That is indeed a sticky situation.

It seems unlikely I have any novel thoughts about syntax given the effort you have put into this, but I would point out that the Go spec has some unused characters that could be used to prefix type parentheses: X#(int) or X~(int), which could also remove the extra use of "type" in definitions: type X~(T) T, etc.

@griesemer
Copy link
Contributor

A type parameter on the RHS of a type definition is not permitted anymore. Closing.

@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants