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

Open
crawshaw opened this issue Jul 5, 2020 · 4 comments
Open

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

crawshaw opened this issue Jul 5, 2020 · 4 comments
Assignees
Milestone

Comments

@crawshaw
Copy link
Contributor

@crawshaw 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

@thepudds thepudds commented Jul 5, 2020

Possibly related to #39670 (comment)

@thepudds
Copy link

@thepudds 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

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jul 7, 2020

@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
Contributor Author

@crawshaw 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.

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
You can’t perform that action at this time.