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

     1  // -lang=go1.20
     2  
     3  // Copyright 2021 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // This file shows some examples of type inference.
     8  
     9  package p
    10  
    11  type Ordered interface {
    12  	~int | ~float64 | ~string
    13  }
    14  
    15  func min[T Ordered](x, y T) T { panic(0) }
    16  
    17  func _() {
    18  	// min can be called with explicit instantiation.
    19  	_ = min[int](1, 2)
    20  
    21  	// Alternatively, the type argument can be inferred from
    22  	// one of the arguments. Untyped arguments will be considered
    23  	// last.
    24  	var x int
    25  	_ = min(x, x)
    26  	_ = min(x, 1)
    27  	_ = min(x, 1.0)
    28  	_ = min(1, 2)
    29  	_ = min(1, 2.3)
    30  
    31  	var y float64
    32  	_ = min(1, y)
    33  	_ = min(1.2, y)
    34  	_ = min(1.2, 3.4)
    35  	_ = min(1.2, 3)
    36  
    37  	var s string
    38  	_ = min(s, "foo")
    39  	_ = min("foo", "bar")
    40  }
    41  
    42  func mixed[T1, T2, T3 any](T1, T2, T3) {}
    43  
    44  func _() {
    45  	// mixed can be called with explicit instantiation.
    46  	mixed[int, string, bool](0, "", false)
    47  
    48  	// Alternatively, partial type arguments may be provided
    49  	// (from left to right), and the other may be inferred.
    50  	mixed[int, string](0, "", false)
    51  	mixed[int](0, "", false)
    52  	mixed(0, "", false)
    53  
    54  	// Provided type arguments always take precedence over
    55  	// inferred types.
    56  	mixed[int, string](1.1 /* ERROR "cannot use 1.1" */, "", false)
    57  }
    58  
    59  func related1[Slice interface{ ~[]Elem }, Elem any](s Slice, e Elem) {}
    60  
    61  func _() {
    62  	// related1 can be called with explicit instantiation.
    63  	var si []int
    64  	related1[[]int, int](si, 0)
    65  
    66  	// Alternatively, the 2nd type argument can be inferred
    67  	// from the first one through constraint type inference.
    68  	var ss []string
    69  	_ = related1[[]string]
    70  	related1[[]string](ss, "foo")
    71  
    72  	// A type argument inferred from another explicitly provided
    73  	// type argument overrides whatever value argument type is given.
    74  	related1[[]string](ss, 0 /* ERROR "cannot use 0" */)
    75  
    76  	// A type argument may be inferred from a value argument
    77  	// and then help infer another type argument via constraint
    78  	// type inference.
    79  	related1(si, 0)
    80  	related1(si, "foo" /* ERROR `cannot use "foo"` */)
    81  }
    82  
    83  func related2[Elem any, Slice interface{ []Elem }](e Elem, s Slice) {}
    84  
    85  func _() {
    86  	// related2 can be called with explicit instantiation.
    87  	var si []int
    88  	related2[int, []int](0, si)
    89  
    90  	// Alternatively, the 2nd type argument can be inferred
    91  	// from the first one through constraint type inference.
    92  	var ss []string
    93  	_ = related2[string]
    94  	related2[string]("foo", ss)
    95  
    96  	// A type argument may be inferred from a value argument
    97  	// and then help infer another type argument via constraint
    98  	// type inference. Untyped arguments are always considered
    99  	// last.
   100  	related2(1.2, []float64{})
   101  	related2(1.0, []int{})
   102  	related2 /* ERROR "Slice (type []int) does not satisfy interface{[]Elem}" */ (float64(1.0), []int{}) // TODO(gri) better error message
   103  }
   104  
   105  type List[P any] []P
   106  
   107  func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
   108  
   109  func _() {
   110  	// related3 can be instantiated explicitly
   111  	related3[int, []int]()
   112  	related3[byte, List[byte]]()
   113  
   114  	// The 2nd type argument cannot be inferred from the first
   115  	// one because there's two possible choices: []Elem and
   116  	// List[Elem].
   117  	related3 /* ERROR "cannot infer Slice" */ [int]()
   118  }
   119  
   120  func wantsMethods[P interface {
   121  	m1(Q)
   122  	m2() R
   123  }, Q, R any](P) {
   124  }
   125  
   126  type hasMethods1 struct{}
   127  
   128  func (hasMethods1) m1(int)
   129  func (hasMethods1) m2() string
   130  
   131  type hasMethods2 struct{}
   132  
   133  func (*hasMethods2) m1(int)
   134  func (*hasMethods2) m2() string
   135  
   136  type hasMethods3 interface {
   137  	m1(float64)
   138  	m2() complex128
   139  }
   140  
   141  type hasMethods4 interface {
   142  	m1()
   143  }
   144  
   145  func _() {
   146  	// wantsMethod can be called with arguments that have the relevant methods
   147  	// and wantsMethod's type arguments are inferred from those types' method
   148  	// signatures.
   149  	wantsMethods(hasMethods1{})
   150  	wantsMethods(&hasMethods1{})
   151  	wantsMethods /* ERROR "P (type hasMethods2) does not satisfy interface{m1(Q); m2() R} (method m1 has pointer receiver)" */ (hasMethods2{})
   152  	wantsMethods(&hasMethods2{})
   153  	wantsMethods(hasMethods3(nil))
   154  	wantsMethods /* ERROR "P (type any) does not satisfy interface{m1(Q); m2() R} (missing method m1)" */ (any(nil))
   155  	wantsMethods /* ERROR "P (type hasMethods4) does not satisfy interface{m1(Q); m2() R} (wrong type for method m1)" */ (hasMethods4(nil))
   156  }
   157  
   158  // "Reverse" type inference is not yet permitted.
   159  
   160  func f[P any](P) {}
   161  
   162  // This must not crash.
   163  var _ func(int) = f // ERROR "implicitly instantiated function in assignment requires go1.21 or later"