Source file src/internal/types/testdata/check/issues1.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  // This file contains regression tests for bugs found.
     6  
     7  package p
     8  
     9  import "io"
    10  import "context"
    11  
    12  func eql[T comparable](x, y T) bool {
    13  	return x == y
    14  }
    15  
    16  func _[X comparable, Y interface{comparable; m()}]() {
    17  	var x X
    18  	var y Y
    19  	eql(x, y /* ERROR "does not match" */ ) // interfaces of different types
    20  	eql(x, x)
    21  	eql(y, y)
    22  	eql(y, nil /* ERROR "cannot use nil as Y value in argument to eql" */ )
    23  	eql[io.Reader](nil, nil)
    24  }
    25  
    26  // If we have a receiver of pointer to type parameter type (below: *T)
    27  // we don't have any methods, like for interfaces.
    28  type C[T any] interface {
    29      m()
    30  }
    31  
    32  // using type bound C
    33  func _[T C[T]](x *T) {
    34  	x.m /* ERROR "x.m undefined" */ ()
    35  }
    36  
    37  // using an interface literal as bound
    38  func _[T interface{ m() }](x *T) {
    39  	x.m /* ERROR "x.m undefined" */ ()
    40  }
    41  
    42  func f2[_ interface{ m1(); m2() }]() {}
    43  
    44  type T struct{}
    45  func (T) m1()
    46  func (*T) m2()
    47  
    48  func _() {
    49  	f2[T /* ERROR "m2 has pointer receiver" */ ]()
    50  	f2[*T]()
    51  }
    52  
    53  // When a type parameter is used as an argument to instantiate a parameterized
    54  // type, the type argument's type set must be a subset of the instantiated type
    55  // parameter's type set.
    56  type T1[P interface{~uint}] struct{}
    57  
    58  func _[P any]() {
    59      _ = T1[P /* ERROR "P does not satisfy interface{~uint}" */ ]{}
    60  }
    61  
    62  // This is the original (simplified) program causing the same issue.
    63  type Unsigned interface {
    64  	~uint
    65  }
    66  
    67  type T2[U Unsigned] struct {
    68      s U
    69  }
    70  
    71  func (u T2[U]) Add1() U {
    72      return u.s + 1
    73  }
    74  
    75  func NewT2[U any]() T2[U /* ERROR "U does not satisfy Unsigned" */ ] {
    76      return T2[U /* ERROR "U does not satisfy Unsigned" */ ]{}
    77  }
    78  
    79  func _() {
    80      u := NewT2[string]()
    81      _ = u.Add1()
    82  }
    83  
    84  // When we encounter an instantiated type such as Elem[T] we must
    85  // not "expand" the instantiation when the type to be instantiated
    86  // (Elem in this case) is not yet fully set up.
    87  type Elem[T any] struct {
    88  	next *Elem[T]
    89  	list *List[T]
    90  }
    91  
    92  type List[T any] struct {
    93  	root Elem[T]
    94  }
    95  
    96  func (l *List[T]) Init() {
    97  	l.root.next = &l.root
    98  }
    99  
   100  // This is the original program causing the same issue.
   101  type Element2[TElem any] struct {
   102  	next, prev *Element2[TElem]
   103  	list *List2[TElem]
   104  	Value TElem
   105  }
   106  
   107  type List2[TElem any] struct {
   108  	root Element2[TElem]
   109  	len  int
   110  }
   111  
   112  func (l *List2[TElem]) Init() *List2[TElem] {
   113  	l.root.next = &l.root
   114  	l.root.prev = &l.root
   115  	l.len = 0
   116  	return l
   117  }
   118  
   119  // Self-recursive instantiations must work correctly.
   120  type A[P any] struct { _ *A[P] }
   121  
   122  type AB[P any] struct { _ *BA[P] }
   123  type BA[P any] struct { _ *AB[P] }
   124  
   125  // And a variation that also caused a problem with an
   126  // unresolved underlying type.
   127  type Element3[TElem any] struct {
   128  	next, prev *Element3[TElem]
   129  	list *List3[TElem]
   130  	Value TElem
   131  }
   132  
   133  func (e *Element3[TElem]) Next() *Element3[TElem] {
   134  	if p := e.next; e.list != nil && p != &e.list.root {
   135  		return p
   136  	}
   137  	return nil
   138  }
   139  
   140  type List3[TElem any] struct {
   141  	root Element3[TElem]
   142  	len  int
   143  }
   144  
   145  // Infinite generic type declarations must lead to an error.
   146  type inf1[T any] struct{ _ inf1 /* ERROR "invalid recursive type" */ [T] }
   147  type inf2[T any] struct{ inf2 /* ERROR "invalid recursive type" */ [T] }
   148  
   149  // The implementation of conversions T(x) between integers and floating-point
   150  // numbers checks that both T and x have either integer or floating-point
   151  // type. When the type of T or x is a type parameter, the respective simple
   152  // predicate disjunction in the implementation was wrong because if a type set
   153  // contains both an integer and a floating-point type, the type parameter is
   154  // neither an integer or a floating-point number.
   155  func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
   156  	return T2(v)
   157  }
   158  
   159  func _() {
   160  	convert[int, uint](5)
   161  }
   162  
   163  // When testing binary operators, for +, the operand types must either be
   164  // both numeric, or both strings. The implementation had the same problem
   165  // with this check as the conversion issue above (issue #39623).
   166  
   167  func issue39623[T interface{~int | ~string}](x, y T) T {
   168  	return x + y
   169  }
   170  
   171  // Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
   172  func Sum[T interface{~int | ~string}](s []T) (sum T) {
   173  	for _, v := range s {
   174  		sum += v
   175  	}
   176  	return
   177  }
   178  
   179  // Assignability of an unnamed pointer type to a type parameter that
   180  // has a matching underlying type.
   181  func _[T interface{}, PT interface{~*T}] (x T) PT {
   182      return &x
   183  }
   184  
   185  // Indexing of type parameters containing type parameters in their constraint terms:
   186  func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
   187          return x[i]
   188  }
   189  
   190  // Conversion of a local type to a type parameter.
   191  func _[T interface{~int}](x T) {
   192  	type myint int
   193  	var _ int = int(x)
   194  	var _ T = 42
   195  	var _ T = T(myint(42))
   196  }
   197  
   198  // Indexing a type parameter with an array type bound checks length.
   199  // (Example by mdempsky@.)
   200  func _[T interface { ~[10]int }](x T) {
   201  	_ = x[9] // ok
   202  	_ = x[20 /* ERROR "out of bounds" */ ]
   203  }
   204  
   205  // Pointer indirection of a type parameter.
   206  func _[T interface{ ~*int }](p T) int {
   207  	return *p
   208  }
   209  
   210  // Channel sends and receives on type parameters.
   211  func _[T interface{ ~chan int }](ch T) int {
   212  	ch <- 0
   213  	return <- ch
   214  }
   215  
   216  // Calling of a generic variable.
   217  func _[T interface{ ~func() }](f T) {
   218  	f()
   219  	go f()
   220  }
   221  
   222  type F1 func()
   223  type F2 func()
   224  func _[T interface{ func()|F1|F2 }](f T) {
   225  	f()
   226  	go f()
   227  }
   228  
   229  // We must compare against the (possibly underlying) types of term list
   230  // elements when checking if a constraint is satisfied by a type.
   231  // The underlying type of each term must be computed after the
   232  // interface has been instantiated as its constraint may contain
   233  // a type parameter that was substituted with a defined type.
   234  // Test case from an (originally) failing example.
   235  
   236  type sliceOf[E any] interface{ ~[]E }
   237  
   238  func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
   239  
   240  var f           func()
   241  var cancelSlice []context.CancelFunc
   242  var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
   243  
   244  // A generic function must be instantiated with a type, not a value.
   245  
   246  func g[T any](T) T { panic(0) }
   247  
   248  var _ = g[int]
   249  var _ = g[nil /* ERROR "is not a type" */ ]
   250  var _ = g(0)
   251  

View as plain text