-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: incorrect type set intersection computation #57486
Comments
There is no type that both implement |
Note that in 1.20 It's not clear to me why this compiles with 1.18 and 1.19. CC @griesemer . |
@ianlancetaylor
|
But why doesn't the type set of C2 contain I looks the calculated type set of C2 in the following code is indeed package main
func main() {
var x struct{x any}
var y [2]any
G2(x) // okay
G2(y) // okay
var z int
G2(z) // okay
}
type C2 interface {
comparable
[2]any | int | struct{x any}
}
func G2[T C2](t T) {
// 1.20rc1 error message
_ = t == t // invalid operation: t == t (incomparable types in type set)
} |
@go101 the semantic for go1.20 was changed, see Ian's comment above. |
I read the new semantic changes several times. Maybe I still haven't got it. And per @ianlancetaylor 's
My understanding is that C2 is only satisfied by |
You can see
|
I don't think the interpretation is right, if the compilation behavior is right for the following program. package main
func main() {
var x int
G2(x) // okay
var y []byte
G2(y) // error: []byte does not implement C2 ([]byte missing in ~int)
}
type C2 interface {
comparable
~int | ~[]byte
}
func G2[T C2](t T) {
_ = t == t // okay
} |
@go101
According to my current reading of the spec at tip, strictly comparable does not matter here because The compiler is correct. |
Okay, now the only I don't understand is why the |
@go101 you're right. I was wrong that the type set is empty, it's actually contain
|
@go101 In that case, Embedding the C2 is just not the canonical form of the expressed constraint. Passing a type inferred variable of type []byte to G2 doesn't compile (it's not comparable). It's normal. :) |
@atdiar type C2 interface {
comparable
[2]any | int | struct{x any}
}
func G2[T C2](t T) {
// 1.20rc1 error message
_ = t == t // invalid operation: t == t (incomparable types in type set)
} |
@go101 ah yes, you're right, I actually don't know. Looks like a bug to me as well. |
Re-read the relevant sections in tip spec:
So it is expected that the line The weirdness still comes from the calculation of the type set of C2. It looks gc treats the following C2 and C3 as equivalent: type C2 interface {
comparable
[2]any | int
}
type C3 interface {
[2]any | int
} What is the semantics of embedding |
Tip spec says:
So I think this is a bug of gc. Because the type set of C2 should be the intersection of the type sets of |
Re-read 1.19 spec. It looks it is an expected behavior to view C2 and C3 as equivalent by 1.19 spec.
So by 1.19 spec, the |
The 1.20 compiler currently violates the language spec. https://go.dev/play/p/bqahFnk1xbV?v=gotip |
I got confused earlier and missed the fact that we are instantiating I agree that |
@rittneje The code (your example) https://go.dev/play/p/bqahFnk1xbV?v=gotip package main
func foo[T comparable](t T) {}
func main() {
_ = foo[struct{ f any }]
_ = foo[any]
_ = foo[[0]any]
} compiles w/o errors when running locally with the latest version (go version devel go1.20-9123221ccf Wed Dec 28 15:34:23 2022 +0000 darwin/arm64). Not sure why the playground at tip behaves differently. |
In the first example, it is correct that func F1[V [2]any](v V) {
_ = G1[V] // error: V does not implement comparable
}
I think the handling of |
The type set of The intersection computation is using the wrong "comparable" predicate (not strictly comparable but "spec-comparable"). Fix forthcoming, later today. |
Change https://go.dev/cl/459816 mentions this issue: |
This is now fixed (but not yet submitted). As @ianlancetaylor correctly noted, this should not have worked with Go 1.18 or Go 1.19. @gopherbot please consider this for backport to 1.18 and 1.19. This is a compiler bug. |
Backport issue(s) opened: #57498 (for 1.18), #57499 (for 1.19). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Change https://go.dev/cl/460015 mentions this issue: |
Change https://go.dev/cl/460016 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes, also for tip.
What did you do?
What did you expect to see?
Both F1 and F2 fail to compile.
What did you see instead?
F2 compiles okay.
My understanding is that the type set of C2 only contains
int
, because[2]any
is not strictly comparable, though my understanding might be wrong.The text was updated successfully, but these errors were encountered: