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/compile: type inference should look inside type parameters #49575

Open
griesemer opened this issue Nov 13, 2021 · 4 comments
Open

cmd/compile: type inference should look inside type parameters #49575

griesemer opened this issue Nov 13, 2021 · 4 comments

Comments

@griesemer
Copy link
Contributor

@griesemer griesemer commented Nov 13, 2021

This is extracted from issue #49441.

For

package p

func f[T any, PT *T](x PT) {}

func _[T any, PT *T](x PT) {
        f(x)
}

we currently get an error (at the wrong line, see issue #45985 for that).

But the question arises, should we be able to infer the type arguments in this case?

@hanchaoqun has provided CL 362776 (thanks!) that addresses this and would make this code work.

Need to decide a) if we want this; and b) is the CL correct (are there unintended consequences).

cc @ianlancetaylor for thoughts on this.

@griesemer griesemer added this to the Go1.18 milestone Nov 13, 2021
@griesemer griesemer self-assigned this Nov 13, 2021
@hanchaoqun
Copy link
Contributor

@hanchaoqun hanchaoqun commented Nov 14, 2021

Thank you very much for raising this question.
There is another example inspired by Type Parameters Proposal#element-constraint-example
“a combination of function argument type inference and constraint type inference works.”

package p

type SC[E any] interface {
	[]E
}

func F[E any, SE SC[E]] (x SE) {
}

func WarpF[E any, SE SC[E]] (x SE) {
	F(x)
}

or

package p

func F[E any, SE []E] (x SE) {
}

func WarpF[E any, SE []E] (x SE) {
	F(x)
}

Loading

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Nov 16, 2021

I don't see anything in the current constraint type inference algorithm that would permit this kind of type inference.

This is easier to discuss if we don't use the same names for the different type parameters.

package p

func f[FT any, FPT *FT](x FPT) {}

func _[GT any, GPT *GT](x GPT) {
        f(x)
}

In the call f(x) we'll use function argument type inference to deduce that we are passing the type argument GPT for the type parameter FPT. The question is whether we can use constraint type inference to deduce the type argument for FT. The structural type for FPT is *FT. So we'll try to unify GPT with *FT. That unification will fail, so constraint type inference will fail to deduce any type arguments, so overall type inference will fail.

The suggestion in this issue is presumably something like: when unifying a type argument TA with a type parameter TP1 that has a structural constraint C1, if the unification fails, and if TA is itself a type parameter TP2, and if TP2 has a structural constraint C2, then we should attempt to unify C2 with C1. In this example if we did that we would attempt to unify *GT with *FT, which would permit us to deduce that the type argument for FT is GT.

I don't see any immediate problem with that. However, my personal feeling is that we should not add any more type inference rules for 1.18. Type inference is already very complex and subtle. Let's see where we are before we start making it more complicated. It is always possible to write

        f[GT, GPT](x)

That is very clear. Let's be very careful to make sure that we don't add further type inference rules at the cost of code reading clarity.

Loading

@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Nov 17, 2021

I agree with @ianlancetaylor that we should not make type inference more complex for 1.18, without gaining experience with it. I'm going to move this to 1.19; and even then, we will need to make a decision about this.

Loading

@mpx
Copy link
Contributor

@mpx mpx commented Nov 26, 2021

Can we please use this issue or #49800 to improve the error message for Go 1.18?

Currently the error message points to the callee instead the call location, and the message is non-obvious. Fixing code under the current inference rules should be fairly trivial with a good error message.

Loading

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