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: cannot infer generic interface types #41176

Open
rogpeppe opened this issue Sep 2, 2020 · 8 comments
Open

cmd/go2go: cannot infer generic interface types #41176

rogpeppe opened this issue Sep 2, 2020 · 8 comments

Comments

@rogpeppe
Copy link
Contributor

@rogpeppe rogpeppe commented Sep 2, 2020

commit 8ea0120

The type inference algorithm does not work when the actual parameter is a concrete type and the formal parameter is a generic interface type. It looks like the type inference description in the proposal doesn't cover interfaces, but I suspect it should.

https://go2goplay.golang.org/p/C53vOfwA9vq

package main

type S struct {}

func (S) M() byte {
	return 0
}

type I[T any] interface {
	M() T
}

func F[T any](x I[T]) {
	x.M()
}

func main() {
	F(S{})
}

This fails with the error:

prog.go2:18:4: type S of (S literal) does not match I[T] (cannot infer T)

FWIW type interfence doesn't work when the interface argument is a type parameter either, but I can't work out if that's covered by the proposal or not: https://go2goplay.golang.org/p/pAouk3xkmOX

func F[X I[T], T any](x X) {
	x.M()
}
@dmitshur
Copy link
Member

@dmitshur dmitshur commented Sep 2, 2020

@dmitshur dmitshur added this to the Unreleased milestone Sep 2, 2020
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 2, 2020

I agree that the current inference algorithm doesn't permit this inference. I'm not at all sure that it should. It requires that we go beyond looking at the type of the argument, to looking at the method set of the argument. And as far as I can see it would only be useful to infer the type parameter of a parameterized interface type. There is a pretty long step from argument method set to type argument for interface type. Our goal for type inference is not all possible type inference, it's straightforward and easily understood type inference. At least at first glance, I don't think this meets that goal.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Sep 2, 2020

Marked as FeatureRequest as this is not a bug in the prototype.

@dmitshur
Copy link
Member

@dmitshur dmitshur commented Sep 3, 2020

@griesemer An issue should have one of NeedsInvestigation, NeedsDecision, or NeedsFix labels after being triaged (per https://golang.org/wiki/HandlingIssues#issue-states). I'll re-add NeedsInvestigation, but please feel to change it if another Needs label is more appropriate.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Sep 3, 2020

@dmitshur ACK. Thanks for the reminder.

@rogpeppe
Copy link
Contributor Author

@rogpeppe rogpeppe commented Sep 3, 2020

FWIW I ran across this when experimenting with making the io package generic. When dealing with generic interfaces I suspect it will be very common to pass a concrete implementation to a function that accepts the generic interface as an argument, just as in current Go it's common to pass a concrete type to an interface parameter.

This issue will tend to arise when using any generic iterator interface AFAICS, so I think it would be worth addressing. It certainly seemed like it should work when I was adapting the code - I was surprised that it didn't.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 5, 2020

One of the common requests for the design draft is support for methods that have their own generic type parameters. We don't currently know how to implement that (https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#no-parameterized-methods). But if ever do figure out how to implement it, there is going to be some sort of relationship to parameterized interface types. I at least don't fully understand how this should all work together, so I'm wary of adding type inference into the mix.

@rogpeppe
Copy link
Contributor Author

@rogpeppe rogpeppe commented Sep 7, 2020

But if ever do figure out how to implement it, there is going to be some sort of relationship to parameterized interface types.

I'm sure there will be, but won't there also be some sort of relationship to concrete types too, and also to non-parameterized interface types? AFAICS adding methods with their own type parameters will largely be orthogonal to type inference in general, because the method type parameters are free and thus unrelated to the outer level type parameters.

As I see it, type inference on interfaces is not that far off from type inference on constants, which has good treatment in the proposal.

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.