Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: go/types/testdata/check

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

View as plain text