-
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: backward incompatible change in Go 1.21 type inference with channels #62157
Comments
Thanks for reporting. Can you check if this is the same issue as #61903, which was recently resolved at tip, or not the same issue? |
Hi, I just tried with gotip and I still get an error though the formatting is slightly different (better):
To be honest, I am not sure which behavior is correct. In general Go does implicit casting from |
I have managed to simplify it to the following program: package main
type Matcher[T any] func(T) bool
func Produces[T comparable](expected T) Matcher[<-chan T] {
return func(ch <-chan T) bool {
value := <-ch
return value == expected
}
}
func Assert[T any](a T, b Matcher[T]) {
if !b(a) {
panic("assertion failed!")
}
}
func main() {
ch := make(chan string, 1)
ch <- "hello"
Assert(ch, Produces("hello"))
} This runs with Go 1.20 and does not compile with gotip or Go 1.21. |
CC @golang/compiler. |
This is a compiler bug somewhere, because there is an order dependency in type inference. This program, which swaps the order of the arguments to
Just swapping the argument order should not affect type inference, but for channel direction it apparently does. CC @griesemer |
Simpler reproducer: package p
func f[T any](T, T) {}
func _() {
var a chan string
var b <-chan string
f(a, b) // ERROR cannot use b (variable of type <-chan string) as chan string value in argument to f
f(b, a) // but this is ok
} Definitely an inference/unification bug. [Edit] This issue appears with both 1.20 and 1.21 so is a "pre-existing" error and slightly different from what was reported earlier. In any case, both of these should work. |
The following simplified reproducer works with Go 1.20, but not with Go 1.21. package p
type F[T any] func(T) bool
func g[T any](T) F[<-chan T] { return nil }
func f1[T any](T, F[T]) {}
func f2[T any](F[T], T) {}
func _() {
var ch chan string
f1(ch, g(""))
f2(g(""), ch)
} |
Change https://go.dev/cl/521500 mentions this issue: |
@gopherbot please consider this for backport to 1.21, this is partly a regression and partly a pre-existing bug. |
Backport issue(s) opened: #62205 (for 1.21). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I tried to compile my project (that used to compile successfully with Go 1.20) but I get an error.
The project (with commit ref) is the following:
https://github.com/mokiat/gotest
The following command should run:
NOTE: While the project is just a playground at this point in time to see if generic matchers for testing and mocking might be possible in Go and the tests don't pass at the moment, the project does compile with Go 1.20 and does not with Go 1.21.
What did you expect to see?
What did you see instead?
This can be fixed by casting the channel to a read-only channel.
needs to become
Nevertheless, this feels like a breaking change.
The text was updated successfully, but these errors were encountered: