Source file src/internal/types/testdata/spec/methods.go

     1  // Copyright 2026 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  // Non-interface methods may declare type parameters.
     8  
     9  type T struct{}
    10  
    11  func (T) m[P any](x P) P { return x }
    12  
    13  func _() {
    14  	// A generic method must be instantiated before it is called.
    15  	var x T
    16  	var _ int = x.m[int](1) // explicit instantiation
    17  	var _ int = x.m(2)      // instantiation via type inference
    18  	var _ int = x /* ERROR "cannot use x.m(3.14) (value of type float64)" */ .m(3.14)
    19  
    20  	// Receivers of generic method calls may be complex expressions:
    21  	// Instantiation must work not just on simple operands.
    22  	var a [10]T
    23  	_ = a[0].m[int]  // explicit instantiation
    24  	_ = a[1].m(2.72) // instantiation via type inference
    25  
    26  	var m map[string][]struct{ T }
    27  	_ = m["foo"][0].T.m[float32]
    28  	_ = m["foo"][0].T.m(2.72)
    29  
    30  	_ = m["foo"][0].m[float32] // method promotion with explicit instantiation
    31  	_ = m["foo"][0].m(2.72)    // method promotion with instantiation via type inference
    32  
    33  	// A generic method expression may be assigned to a function after instantiation.
    34  	var _ func(T, int) int = T.m[int] // explicit instantiation
    35  	var _ func(T, int) int = T.m      // instantiation via type inference
    36  
    37  	// A generic method value may be assigned to a function after instantiation.
    38  	var _ func(int) int = x.m[int] // explicit instantiation
    39  	var _ func(int) int = x.m      // instantiation via type inference
    40  }
    41  
    42  // Generic methods may be added to generic types.
    43  type G[F any] struct {
    44  	f F
    45  }
    46  
    47  // The constraint for the method parameter may refer to the receiver type parameter.
    48  func (g G[F]) m[H interface{ convert(F) H }]() (r H) {
    49  	return r.convert(g.f)
    50  }
    51  
    52  // But the usual restrictions for type terms still apply.
    53  func (G[F]) m2[P F /* ERROR "cannot use a type parameter as constraint" */ ]() {}
    54  func (G[F]) m3[P *F](P) {} // this is ok
    55  
    56  // When the receiver is instantiated, the receiver type argument must be
    57  // substituted into the constraint of any method type parameter.
    58  func _() {
    59  	var i int
    60  	G[int]{}.m3(&i)
    61  	G[int]{}.m3[*int](&i)
    62  	_ = G[int].m3[*int]
    63  	_ = G[int]{}.m3[* /* ERROR "*string does not satisfy *int (*string missing in *int)" */ string]
    64  }
    65  
    66  // This includes calls from a sibling method, where the receiver type
    67  // parameters are distinct objects with the same names.
    68  func (g G[F]) m4() {
    69  	var f F
    70  	g.m3(&f)
    71  }
    72  
    73  // And calls from a generic function.
    74  func _[A any](g G[A]) {
    75  	var a A
    76  	g.m3(&a)
    77  }
    78  
    79  // Generic methods don't satisfy interfaces.
    80  type I[P any] interface {
    81  	m(P) P
    82  }
    83  
    84  var _ I[int] = T /* ERROR "(wrong type for method m)\n\t\thave m[P any](P) P\n\t\twant m(int) int" */ {}
    85  
    86  // A method declaring type parameters is generic even if it doesn't use the type parameters in its signature.
    87  type U struct {}
    88  
    89  func (U) m[_ any](x int) int { return x }
    90  
    91  var _ I[int] = U /* ERROR "wrong type for method m)\n\t\thave m[_ any](int) int\n\t\twant m(int) int" */ {}
    92  
    93  type J interface {
    94  	m()
    95  }
    96  
    97  type V struct {}
    98  
    99  func (V) m[_ any]() {}
   100  
   101  var _ J = V /* ERROR "wrong type for method m)\n\t\thave m[_ any]()\n\t\twant m()" */ {}
   102  
   103  // In particular, interface inference must not unify a generic method's
   104  // own type parameter into an inference variable.
   105  func need[X any](I[X]) {}
   106  
   107  func _() {
   108  	need(T /* ERROR "type T of T{} does not match I[X] (cannot infer X)" */ {})
   109  }
   110  
   111  // Test case from parser smoke test.
   112  
   113  type List[E any] []E
   114  
   115  func (l List[E]) Map[F any](m func(E) F) (r List[F]) {
   116  	for _, x := range l {
   117  		r = append(r, m(x))
   118  	}
   119  	return
   120  }
   121  
   122  func _() {
   123  	l := List[string]{"foo", "foobar", "42"}
   124  	r := l.Map(func(s string) int { return len(s)})
   125  	_ = r
   126  }
   127  
   128  func _[E, F any](l List[E]) List[F] {
   129  	var f func(List[E], func(E) F) List[F] = List[E].Map  // method expression & type inference
   130  	return f(l, func(E) F { var f F; return f })
   131  }
   132  
   133  func _[E, F any](l List[E]) List[F] {
   134  	var f func(func(E) F) List[F] = l.Map  // method value & type inference
   135  	return f(func(E) F { var f F; return f })
   136  }
   137  

View as plain text