Source file src/internal/types/testdata/check/funcinference.go

     1  // Copyright 2020 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 funcInference
     6  
     7  import "strconv"
     8  
     9  type any interface{}
    10  
    11  func f0[A any, B interface{*C}, C interface{*D}, D interface{*A}](A, B, C, D) {}
    12  func _() {
    13  	f := f0[string]
    14  	f("a", nil, nil, nil)
    15  	f0("a", nil, nil, nil)
    16  }
    17  
    18  func f1[A any, B interface{*A}](A, B) {}
    19  func _() {
    20  	f := f1[int]
    21  	f(int(0), new(int))
    22  	f1(int(0), new(int))
    23  }
    24  
    25  func f2[A any, B interface{[]A}](A, B) {}
    26  func _() {
    27  	f := f2[byte]
    28  	f(byte(0), []byte{})
    29  	f2(byte(0), []byte{})
    30  }
    31  
    32  // Embedding stand-alone type parameters is not permitted for now. Disabled.
    33  // func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
    34  // func _() {
    35  // 	f := f3[int]
    36  // 	var x int
    37  // 	f(x, &x, &x)
    38  // 	f3(x, &x, &x)
    39  // }
    40  
    41  func f4[A any, B interface{[]C}, C interface{*A}](A, B, C) {}
    42  func _() {
    43  	f := f4[int]
    44  	var x int
    45  	f(x, []*int{}, &x)
    46  	f4(x, []*int{}, &x)
    47  }
    48  
    49  func f5[A interface{struct{b B; c C}}, B any, C interface{*B}](x B) A { panic(0) }
    50  func _() {
    51  	x := f5(1.2)
    52  	var _ float64 = x.b
    53  	var _ float64 = *x.c
    54  }
    55  
    56  func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
    57  func _() {
    58  	x := f6(struct{f []string}{})
    59  	var _ string = x
    60  }
    61  
    62  func f7[A interface{*B}, B interface{~*A}]() {}
    63  
    64  // More realistic examples
    65  
    66  func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S {
    67  	r := make(S, len(s))
    68  	for i, v := range s {
    69  		r[i] = v + v
    70  	}
    71  	return r
    72  }
    73  
    74  type MySlice []int
    75  
    76  var _ = Double(MySlice{1})
    77  
    78  // From the draft design.
    79  
    80  type Setter[B any] interface {
    81  	Set(string)
    82  	*B
    83  }
    84  
    85  func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
    86  	result := make([]T, len(s))
    87  	for i, v := range s {
    88  		// The type of &result[i] is *T which is in the type set
    89  		// of Setter, so we can convert it to PT.
    90  		p := PT(&result[i])
    91  		// PT has a Set method.
    92  		p.Set(v)
    93  	}
    94  	return result
    95  }
    96  
    97  type Settable int
    98  
    99  func (p *Settable) Set(s string) {
   100  	i, _ := strconv.Atoi(s) // real code should not ignore the error
   101  	*p = Settable(i)
   102  }
   103  
   104  var _ = FromStrings[Settable]([]string{"1", "2"})
   105  
   106  // Suitable error message when the type parameter is provided (rather than inferred).
   107  
   108  func f8[P, Q any](P, Q) {}
   109  
   110  func _(s string) {
   111  	f8[int](s /* ERROR "cannot use s (variable of type string) as int value in argument to f8[int]" */ , s)
   112  }
   113  

View as plain text