// Copyright 2026 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 // Non-interface methods may declare type parameters. type T struct{} func (T) m[P any](x P) P { return x } func _() { // A generic method must be instantiated before it is called. var x T var _ int = x.m[int](1) // explicit instantiation var _ int = x.m(2) // instantiation via type inference var _ int = x /* ERROR "cannot use x.m(3.14) (value of type float64)" */ .m(3.14) // Receivers of generic method calls may be complex expressions: // Instantiation must work not just on simple operands. var a [10]T _ = a[0].m[int] // explicit instantiation _ = a[1].m(2.72) // instantiation via type inference var m map[string][]struct{ T } _ = m["foo"][0].T.m[float32] _ = m["foo"][0].T.m(2.72) _ = m["foo"][0].m[float32] // method promotion with explicit instantiation _ = m["foo"][0].m(2.72) // method promotion with instantiation via type inference // A generic method expression may be assigned to a function after instantiation. var _ func(T, int) int = T.m[int] // explicit instantiation var _ func(T, int) int = T.m // instantiation via type inference // A generic method value may be assigned to a function after instantiation. var _ func(int) int = x.m[int] // explicit instantiation var _ func(int) int = x.m // instantiation via type inference } // Generic methods may be added to generic types. type G[F any] struct { f F } // The constraint for the method parameter may refer to the receiver type parameter. func (g G[F]) m[H interface{ convert(F) H }]() (r H) { return r.convert(g.f) } // But the usual restrictions for type terms still apply. func (G[F]) m2[P F /* ERROR "cannot use a type parameter as constraint" */ ]() {} func (G[F]) m3[P *F](P) {} // this is ok // When the receiver is instantiated, the receiver type argument must be // substituted into the constraint of any method type parameter. func _() { var i int G[int]{}.m3(&i) G[int]{}.m3[*int](&i) _ = G[int].m3[*int] _ = G[int]{}.m3[* /* ERROR "*string does not satisfy *int (*string missing in *int)" */ string] } // This includes calls from a sibling method, where the receiver type // parameters are distinct objects with the same names. func (g G[F]) m4() { var f F g.m3(&f) } // And calls from a generic function. func _[A any](g G[A]) { var a A g.m3(&a) } // Generic methods don't satisfy interfaces. type I[P any] interface { m(P) P } var _ I[int] = T /* ERROR "(wrong type for method m)\n\t\thave m[P any](P) P\n\t\twant m(int) int" */ {} // A method declaring type parameters is generic even if it doesn't use the type parameters in its signature. type U struct {} func (U) m[_ any](x int) int { return x } var _ I[int] = U /* ERROR "wrong type for method m)\n\t\thave m[_ any](int) int\n\t\twant m(int) int" */ {} type J interface { m() } type V struct {} func (V) m[_ any]() {} var _ J = V /* ERROR "wrong type for method m)\n\t\thave m[_ any]()\n\t\twant m()" */ {} // In particular, interface inference must not unify a generic method's // own type parameter into an inference variable. func need[X any](I[X]) {} func _() { need(T /* ERROR "type T of T{} does not match I[X] (cannot infer X)" */ {}) } // Test case from parser smoke test. type List[E any] []E func (l List[E]) Map[F any](m func(E) F) (r List[F]) { for _, x := range l { r = append(r, m(x)) } return } func _() { l := List[string]{"foo", "foobar", "42"} r := l.Map(func(s string) int { return len(s)}) _ = r } func _[E, F any](l List[E]) List[F] { var f func(List[E], func(E) F) List[F] = List[E].Map // method expression & type inference return f(l, func(E) F { var f F; return f }) } func _[E, F any](l List[E]) List[F] { var f func(func(E) F) List[F] = l.Map // method value & type inference return f(func(E) F { var f F; return f }) }