// 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 // The type parameter P is not used in interface T1. // T1 is a defined parameterized interface type which // can be assigned to any other interface with the same // methods. We cannot infer a type argument in this case // because any type would do. type T1[P any] interface{ m() } func g[P any](T1[P]) {} func _() { var x T1[int] g /* ERROR "cannot infer P" */ (x) g[int](x) // int is ok for P g[string](x) // string is also ok for P! } // This is analogous to the above example, // but uses two interface types of the same structure. type T2[P any] interface{ m() } func _() { var x T2[int] g /* ERROR "cannot infer P" */ (x) g[int](x) // int is ok for P g[string](x) // string is also ok for P! } // Analogous to the T2 example but using an unparameterized interface T3. type T3 interface{ m() } func _() { var x T3 g /* ERROR "cannot infer P" */ (x) g[int](x) // int is ok for P g[string](x) // string is also ok for P! } // The type parameter P is not used in struct S. // S is a defined parameterized (non-interface) type which can only // be assigned to another type S with the same type argument. // Therefore we can infer a type argument in this case. type S[P any] struct{} func g4[P any](S[P]) {} func _() { var x S[int] g4(x) // we can infer int for P g4[int](x) // int is the correct type argument g4[string](x /* ERROR "cannot use x (variable of type S[int]) as S[string] value in argument to g4[string]" */) } // This is similar to the first example but here T1 is a component // of a func type. In this case types must match exactly: P must // match int. func g5[P any](func(T1[P])) {} func _() { var f func(T1[int]) g5(f) g5[int](f) g5[string](f /* ERROR "cannot use f (variable of type func(T1[int])) as func(T1[string]) value in argument to g5[string]" */) } // This example would fail if we were to infer the type argument int for P // exactly because any type argument would be ok for the first argument. // Choosing the wrong type would cause the second argument to not match. type T[P any] interface{} func g6[P any](T[P], P) {} func _() { var x T[int] g6(x, 1.2) g6(x, "") }