github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/types/testdata/fixedbugs/issue62157.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package p
     6  
     7  func f[T any](...T) T { var x T; return x }
     8  
     9  // Test case 1
    10  
    11  func _() {
    12  	var a chan string
    13  	var b <-chan string
    14  	f(a, b)
    15  	f(b, a)
    16  }
    17  
    18  // Test case 2
    19  
    20  type F[T any] func(T) bool
    21  
    22  func g[T any](T) F[<-chan T] { return nil }
    23  
    24  func f1[T any](T, F[T]) {}
    25  func f2[T any](F[T], T) {}
    26  
    27  func _() {
    28  	var ch chan string
    29  	f1(ch, g(""))
    30  	f2(g(""), ch)
    31  }
    32  
    33  // Test case 3: named and directional types combined
    34  
    35  func _() {
    36  	type namedA chan int
    37  	type namedB chan<- int
    38  
    39  	var a chan int
    40  	var A namedA
    41  	var b chan<- int
    42  	var B namedB
    43  
    44  	// Defined types win over channel types irrespective of channel direction.
    45  	f(A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
    46  	f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A)
    47  
    48  	f(a, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A)
    49  	f(a, A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
    50  	f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, A, a)
    51  	f(b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, a, A)
    52  	f(A, a, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */)
    53  	f(A, b /* ERROR "cannot use b (variable of type chan<- int) as namedA value in argument to f" */, a)
    54  
    55  	// Unnamed directed channels win over bidirectional channels.
    56  	b = f(a, b)
    57  	b = f(b, a)
    58  
    59  	// Defined directed channels win over defined bidirectional channels.
    60  	A = f(A, a)
    61  	A = f(a, A)
    62  	B = f(B, b)
    63  	B = f(b, B)
    64  
    65  	f(a, b, B)
    66  	f(a, B, b)
    67  	f(b, B, a)
    68  	f(b, a, B)
    69  	f(B, a, b)
    70  	f(B, b, a)
    71  
    72  	// Differently named channel types conflict irrespective of channel direction.
    73  	f(A, B /* ERROR "type namedB of B does not match inferred type namedA for T" */)
    74  	f(B, A /* ERROR "type namedA of A does not match inferred type namedB for T" */)
    75  
    76  	// Ensure that all combinations of directional and
    77  	// bidirectional channels with a named directional
    78  	// channel lead to the correct (named) directional
    79  	// channel.
    80  	B = f(a, b)
    81  	B = f(a, B)
    82  	B = f(b, a)
    83  	B = f(B, a)
    84  
    85  	B = f(a, b, B)
    86  	B = f(a, B, b)
    87  	B = f(b, B, a)
    88  	B = f(b, a, B)
    89  	B = f(B, a, b)
    90  	B = f(B, b, a)
    91  
    92  	// verify type error
    93  	A = f /* ERROR "cannot use f(B, b, a) (value of type namedB) as namedA value in assignment" */ (B, b, a)
    94  }
    95  
    96  // Test case 4: some more combinations
    97  
    98  func _() {
    99  	type A chan int
   100  	type B chan int
   101  	type C = chan int
   102  	type D = chan<- int
   103  
   104  	var a A
   105  	var b B
   106  	var c C
   107  	var d D
   108  
   109  	f(a, b /* ERROR "type B of b does not match inferred type A for T" */, c)
   110  	f(c, a, b /* ERROR "type B of b does not match inferred type A for T" */)
   111  	f(a, b /* ERROR "type B of b does not match inferred type A for T" */, d)
   112  	f(d, a, b /* ERROR "type B of b does not match inferred type A for T" */)
   113  }
   114  
   115  // Simplified test case from issue
   116  
   117  type Matcher[T any] func(T) bool
   118  
   119  func Produces[T any](T) Matcher[<-chan T] { return nil }
   120  
   121  func Assert1[T any](Matcher[T], T) {}
   122  func Assert2[T any](T, Matcher[T]) {}
   123  
   124  func _() {
   125  	var ch chan string
   126  	Assert1(Produces(""), ch)
   127  	Assert2(ch, Produces(""))
   128  }