Text file src/go/types/testdata/check/issues.go2

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

View as plain text