-
Notifications
You must be signed in to change notification settings - Fork 18k
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 fails using constraint with approximate map element #51229
Comments
@griesemer @ianlancetaylor |
@randall77 interestingly, it works if you list all type params; even providing
|
Simpler reproducer resulting in the same error: package p
func f[S1 ~[]E1, S2 ~[]E2, E1, E2 ~byte](S1, S2) {}
type myByte byte
func _() {
f([]byte{}, []myByte{})
} This looks like a bug in type inference: when comparing the inferred type of This may be trivial to fix. If so, we should fix this for 1.18. Otherwise, we may want to 1.19. Here's the inference trace:
|
Change https://go.dev/cl/387774 mentions this issue: |
This was closed by virtue of an unfortunately phrased commit message. Reopening. |
Change https://go.dev/cl/387977 mentions this issue: |
Change https://go.dev/cl/390015 mentions this issue: |
…) in constraint type inference When doing constraint type inference, we must consider whether the constraint's core type is precise (no tilde) or imprecise (tilde, or not a single specific type). In the latter case, we cannot infer an unknown type argument from the (imprecise) core type because there are infinitely many possible types. For instance, given [E ~byte] if we don't know E, we cannot infer that E must be byte (it could be myByte, etc.). On the other hand, if we do know the type argument, say for S in this example: [S ~[]E, E any] we must consider the underlying type of S when matching against ~[]E because we have a tilde. Because constraint type inference may infer type arguments that were not eligible initially (because they were unknown and the core type is imprecise), we must iterate the process until nothing changes any- more. For instance, given [S ~[]E, M ~map[string]S, E any] where we initially only know the type argument for M, we must ignore S (and E) at first. After one iteration of constraint type inference, S is known at which point we can infer E as well. The change is large-ish but the actual functional changes are small: - There's a new method "unknowns" to determine the number of as of yet unknown type arguments. - The adjCoreType function has been adjusted to also return tilde and single-type information. This is now conveniently returned as (*term, bool), and the function has been renamed to coreTerm. - The original constraint type inference loop has been adjusted to consider tilde information. - This adjusted original constraint type inference loop has been nested in another loop for iteration, together with some minimal logic to control termination. The remaining changes are modifications to tests: - There's a substantial new test for this issue. - Several existing test cases were adjusted to accomodate the fact that they inferred incorrect types: tildes have been removed throughout. Most of these tests are for pathological cases. - A couple of tests were adjusted where there was a difference between the go/types and types2 version. Fixes #51229. Change-Id: If0bf5fb70ec22913b5a2da89adbf8a27fbc921d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/387977 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> (cherry picked from commit 0807986) Reviewed-on: https://go-review.googlesource.com/c/go/+/390015 Trust: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
It's unfortunate that this no longer works:
|
@dominikh That was just wrong before: we can't possibly know the type of T. It must have an underlying type But I'm not sure that's a worthwhile complication. |
Probably not :( |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes. It reproduces with
go1.18beta2
and on the tip playground withgo1.18-293ecd87c1
.What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I came across this stack overflow question:
https://stackoverflow.com/questions/71131665/generics-pass-map-with-derived-types
I attempted to answer the question with the following function:
I thought it was possible to infer
K1
andK2
fromM1
andM2
respectively. The approximate constraints were used to allow conversion in the function body. It doesn't compile with error:Instead this works, even though the type parameters
K1
andK2
are defined the same way:Go tip playground to demonstrate the issue: https://gotipplay.golang.org/p/NPpau1G0Hqp
What did you expect to see?
I expected the program to compile. Based on the Go 1.18 draft specs I expected he parameters
K1
andK2
to be inferred separately from the approx elements inM1
andM2
constraints.What did you see instead?
Compilation error "K2 does not match uint32"
The text was updated successfully, but these errors were encountered: