-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: type inference: M does not match map[K]V #50755
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
Comments
That error doesn't look right to me. Or, if it is right, I don't think the error message is very clear. Here is a standalone version with type parameters renamed to avoid confusion. package main
import (
"fmt"
)
func Copy[MC ~map[KC]VC, KC comparable, VC any](dst, src MC) {
for k, v := range src {
dst[k] = v
}
}
func Merge[MM ~map[KM]VM, KM comparable, VM any](ms ...MM) MM {
result := MM{}
for _, m := range ms {
Copy(result, m)
}
return result
}
func main() {
m1 := map[int]bool{1: false}
m2 := map[int]bool{1: true}
fmt.Println(Merge(m1, m2))
} The error I get is
Function argument type inference should infer that the type argument for |
Change https://golang.org/cl/380375 mentions this issue: |
Our unification algorithm did not unify the structural type of "external" type parameters (meaning, from another type parameter list), so constraint type inference just sees the opaque https://golang.org/cl/380375 naively adds logic to unify with the structural type of external type parameters, if available. All tests pass, including this example, but I'm not sure if my mental model is correct. At the very least we should improve the error message here. How important do we think it is to support this type of inference for 1.18? |
Thanks, @findleyr for picking this up so quickly. I should have time to look at this tomorrow. |
As far as I'm concerned we don't have to support this kind of type inference for 1.18, but I'd like to make sure that we understand it. Let me ask this: is that error message coming from type inference, or is it coming when checking whether the type arguments implement the type parameter constraints? Because type inference shouldn't produce that kind of error (and if it does it should ideally say something like "failed to infer types because..."). But I don't understand why constraint checking would produce that error either. If I understand your comment correctly, I think you are suggesting that we use function argument type argument to infer that the argument for |
This error is coming from constraint type inference, when the interred type argument @ianlancetaylor, I think we're suggesting the same thing? You said:
That second step (constraint type inference) only works if we can look inside |
Two small remarks. Firstly: this doesn't seem to be about type-inference per-se, because presumably the inferred type in this case would be Secondly: it is, in this case possible to work around the issue in at least two ways, either by converting the arguments to |
@rogpeppe passing This is about constraint type inference, which is the step that would infer |
Simplified reproducers: func f[M map[K]int, K comparable](m M) {
f(m)
} This version is a reduced reproducer of the original problem: func f[M map[K]int, K comparable](m M) {}
func _[M map[K]int, K comparable](m M) {
f(m)
} |
Change https://go.dev/cl/385354 mentions this issue: |
Change https://go.dev/cl/385376 mentions this issue: |
…ation This change adds tests that use a type parameter's core type during function argument type inference, not just during constraint type inference. Also, fix a typo in a comment. For #50755. Change-Id: I0c3196bdce5338341e0b6dfd7c63efb2e43ace25 Reviewed-on: https://go-review.googlesource.com/c/go/+/385376 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Findley <[email protected]>
What version of Go are you using (
go version
)?devel go1.18-d15481b8c7 Fri Jan 21 01:14:28 2022 +0000
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?Go playground (gotip mode)
What did you do?
https://go.dev/play/p/q50y-S0xAVm?v=gotip
What did you expect to see?
What did you see instead?
Since M is
~map[K]V
by definition, this is confusing me. If I explicitly instantiatemaps.Copy
tomap[K]V
, it works:https://go.dev/play/p/SL4LNhpR3jB?v=gotip
It also works as expected if I define
Merge
this way:But I noticed that the functions in
maps
have a more elegant signature:And indeed I can use this, until I try to call a generic function with some M.
Shouldn't the compiler be able to infer the instantiating type here? I'm not sure if this is related to #50484 or #50319, but this is neither an interface nor a function type.
The text was updated successfully, but these errors were encountered: