blob: c44f921f44bf45c9f4c6faf4f25fc2b425385cf1 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
func f[T any](...T) T { var x T; return x }
// Test case 1
func _() {
var a chan string
var b <-chan string
f(a, b)
f(b, a)
}
// Test case 2
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)
}
// Test case 3: named and directional types combined
func _() {
type namedA chan int
type namedB chan<- int
var a chan int
var A namedA
var b chan<- int
var B namedB
// Defined types win over channel types irrespective of channel direction.
f(A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A)
f(a, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A)
f(a, A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A, a)
f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, a, A)
f(A, a, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
f(A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, a)
// Unnamed directed channels win over bidirectional channels.
b = f(a, b)
b = f(b, a)
// Defined directed channels win over defined bidirectional channels.
A = f(A, a)
A = f(a, A)
B = f(B, b)
B = f(b, B)
f(a, b, B)
f(a, B, b)
f(b, B, a)
f(b, a, B)
f(B, a, b)
f(B, b, a)
// Differently named channel types conflict irrespective of channel direction.
f(A, B /* ERROR "type namedB of B does not match inferred type namedA for T" */)
f(B, A /* ERROR "type namedA of A does not match inferred type namedB for T" */)
// Ensure that all combinations of directional and
// bidirectional channels with a named directional
// channel lead to the correct (named) directional
// channel.
B = f(a, b)
B = f(a, B)
B = f(b, a)
B = f(B, a)
B = f(a, b, B)
B = f(a, B, b)
B = f(b, B, a)
B = f(b, a, B)
B = f(B, a, b)
B = f(B, b, a)
// verify type error
A = f /* ERROR "cannot use f(B, b, a) (value of type namedB) as namedA value in assignment" */ (B, b, a)
}
// Test case 4: some more combinations
func _() {
type A chan int
type B chan int
type C = chan int
type D = chan<- int
var a A
var b B
var c C
var d D
f(a, b /* ERROR "type B of b does not match inferred type A for T" */, c)
f(c, a, b /* ERROR "type B of b does not match inferred type A for T" */)
f(a, b /* ERROR "type B of b does not match inferred type A for T" */, d)
f(d, a, b /* ERROR "type B of b does not match inferred type A for T" */)
}
// Simplified test case from issue
type Matcher[T any] func(T) bool
func Produces[T any](T) Matcher[<-chan T] { return nil }
func Assert1[T any](Matcher[T], T) {}
func Assert2[T any](T, Matcher[T]) {}
func _() {
var ch chan string
Assert1(Produces(""), ch)
Assert2(ch, Produces(""))
}