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

     1  // Copyright 2022 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  // Constraint type inference should be independent of the
     8  // ordering of the type parameter declarations. Try all
     9  // permutations in the test case below.
    10  // Permutations produced by https://go.dev/play/p/PHcZNGJTEBZ.
    11  
    12  func f00[S1 ~[]E1, S2 ~[]E2, E1 ~byte, E2 ~byte](S1, S2) {}
    13  func f01[S2 ~[]E2, S1 ~[]E1, E1 ~byte, E2 ~byte](S1, S2) {}
    14  func f02[E1 ~byte, S1 ~[]E1, S2 ~[]E2, E2 ~byte](S1, S2) {}
    15  func f03[S1 ~[]E1, E1 ~byte, S2 ~[]E2, E2 ~byte](S1, S2) {}
    16  func f04[S2 ~[]E2, E1 ~byte, S1 ~[]E1, E2 ~byte](S1, S2) {}
    17  func f05[E1 ~byte, S2 ~[]E2, S1 ~[]E1, E2 ~byte](S1, S2) {}
    18  func f06[E2 ~byte, S2 ~[]E2, S1 ~[]E1, E1 ~byte](S1, S2) {}
    19  func f07[S2 ~[]E2, E2 ~byte, S1 ~[]E1, E1 ~byte](S1, S2) {}
    20  func f08[S1 ~[]E1, E2 ~byte, S2 ~[]E2, E1 ~byte](S1, S2) {}
    21  func f09[E2 ~byte, S1 ~[]E1, S2 ~[]E2, E1 ~byte](S1, S2) {}
    22  func f10[S2 ~[]E2, S1 ~[]E1, E2 ~byte, E1 ~byte](S1, S2) {}
    23  func f11[S1 ~[]E1, S2 ~[]E2, E2 ~byte, E1 ~byte](S1, S2) {}
    24  func f12[S1 ~[]E1, E1 ~byte, E2 ~byte, S2 ~[]E2](S1, S2) {}
    25  func f13[E1 ~byte, S1 ~[]E1, E2 ~byte, S2 ~[]E2](S1, S2) {}
    26  func f14[E2 ~byte, S1 ~[]E1, E1 ~byte, S2 ~[]E2](S1, S2) {}
    27  func f15[S1 ~[]E1, E2 ~byte, E1 ~byte, S2 ~[]E2](S1, S2) {}
    28  func f16[E1 ~byte, E2 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {}
    29  func f17[E2 ~byte, E1 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {}
    30  func f18[E2 ~byte, E1 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {}
    31  func f19[E1 ~byte, E2 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {}
    32  func f20[S2 ~[]E2, E2 ~byte, E1 ~byte, S1 ~[]E1](S1, S2) {}
    33  func f21[E2 ~byte, S2 ~[]E2, E1 ~byte, S1 ~[]E1](S1, S2) {}
    34  func f22[E1 ~byte, S2 ~[]E2, E2 ~byte, S1 ~[]E1](S1, S2) {}
    35  func f23[S2 ~[]E2, E1 ~byte, E2 ~byte, S1 ~[]E1](S1, S2) {}
    36  
    37  type myByte byte
    38  
    39  func _(a []byte, b []myByte) {
    40  	f00(a, b)
    41  	f01(a, b)
    42  	f02(a, b)
    43  	f03(a, b)
    44  	f04(a, b)
    45  	f05(a, b)
    46  	f06(a, b)
    47  	f07(a, b)
    48  	f08(a, b)
    49  	f09(a, b)
    50  	f10(a, b)
    51  	f11(a, b)
    52  	f12(a, b)
    53  	f13(a, b)
    54  	f14(a, b)
    55  	f15(a, b)
    56  	f16(a, b)
    57  	f17(a, b)
    58  	f18(a, b)
    59  	f19(a, b)
    60  	f20(a, b)
    61  	f21(a, b)
    62  	f22(a, b)
    63  	f23(a, b)
    64  }
    65  
    66  // Constraint type inference may have to iterate.
    67  // Again, the order of the type parameters shouldn't matter.
    68  
    69  func g0[S ~[]E, M ~map[string]S, E any](m M) {}
    70  func g1[M ~map[string]S, S ~[]E, E any](m M) {}
    71  func g2[E any, S ~[]E, M ~map[string]S](m M) {}
    72  func g3[S ~[]E, E any, M ~map[string]S](m M) {}
    73  func g4[M ~map[string]S, E any, S ~[]E](m M) {}
    74  func g5[E any, M ~map[string]S, S ~[]E](m M) {}
    75  
    76  func _(m map[string][]byte) {
    77  	g0(m)
    78  	g1(m)
    79  	g2(m)
    80  	g3(m)
    81  	g4(m)
    82  	g5(m)
    83  }
    84  
    85  // Worst-case scenario.
    86  // There are 10 unknown type parameters. In each iteration of
    87  // constraint type inference we infer one more, from right to left.
    88  // Each iteration looks repeatedly at all 11 type parameters,
    89  // requiring a total of 10*11 = 110 iterations with the current
    90  // implementation. Pathological case.
    91  
    92  func h[K any, J ~*K, I ~*J, H ~*I, G ~*H, F ~*G, E ~*F, D ~*E, C ~*D, B ~*C, A ~*B](x A) {}
    93  
    94  func _(x **********int) {
    95  	h(x)
    96  }
    97  
    98  // Examples with channel constraints and tilde.
    99  
   100  func ch1[P chan<- int]() (_ P)           { return } // core(P) == chan<- int   (single type, no tilde)
   101  func ch2[P ~chan int]()                  { return } // core(P) == ~chan<- int  (tilde)
   102  func ch3[P chan E, E any](E)             { return } // core(P) == chan<- E     (single type, no tilde)
   103  func ch4[P chan E | ~chan<- E, E any](E) { return } // core(P) == ~chan<- E    (tilde)
   104  func ch5[P chan int | chan<- int]()      { return } // core(P) == chan<- int   (not a single type)
   105  
   106  func _() {
   107  	// P can be inferred as there's a single specific type and no tilde.
   108  	var _ chan int = ch1 /* ERRORx `cannot use ch1.*value of type chan<- int` */ ()
   109  	var _ chan<- int = ch1()
   110  
   111  	// P cannot be inferred as there's a tilde.
   112  	ch2 /* ERROR "cannot infer P" */ ()
   113  	type myChan chan int
   114  	ch2[myChan]()
   115  
   116  	// P can be inferred as there's a single specific type and no tilde.
   117  	var e int
   118  	ch3(e)
   119  
   120  	// P cannot be inferred as there's more than one specific type and a tilde.
   121  	ch4 /* ERROR "cannot infer P" */ (e)
   122  	_ = ch4[chan int]
   123  
   124  	// P cannot be inferred as there's more than one specific type.
   125  	ch5 /* ERROR "cannot infer P" */ ()
   126  	ch5[chan<- int]()
   127  }
   128  
   129  // test case from issue
   130  
   131  func equal[M1 ~map[K1]V1, M2 ~map[K2]V2, K1, K2 ~uint32, V1, V2 ~string](m1 M1, m2 M2) bool {
   132  	if len(m1) != len(m2) {
   133  		return false
   134  	}
   135  	for k, v1 := range m1 {
   136  		if v2, ok := m2[K2(k)]; !ok || V2(v1) != v2 {
   137  			return false
   138  		}
   139  	}
   140  	return true
   141  }
   142  
   143  func equalFixed[K1, K2 ~uint32, V1, V2 ~string](m1 map[K1]V1, m2 map[K2]V2) bool {
   144  	if len(m1) != len(m2) {
   145  		return false
   146  	}
   147  	for k, v1 := range m1 {
   148  		if v2, ok := m2[K2(k)]; !ok || v1 != V1(v2) {
   149  			return false
   150  		}
   151  	}
   152  	return true
   153  }
   154  
   155  type (
   156  	someNumericID uint32
   157  	someStringID  string
   158  )
   159  
   160  func _() {
   161  	foo := map[uint32]string{10: "bar"}
   162  	bar := map[someNumericID]someStringID{10: "bar"}
   163  	equal(foo, bar)
   164  }