diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
commit | 47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch) | |
tree | a61a0ffd83f4a3def4b36e5c8e99630c559aa723 /src/cmd/compile/internal/syntax/testdata | |
parent | Initial commit. (diff) | |
download | golang-1.18-47ab3d4a42e9ab51c465c4322d2ec233f6324e6b.tar.xz golang-1.18-47ab3d4a42e9ab51c465c4322d2ec233f6324e6b.zip |
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/compile/internal/syntax/testdata')
24 files changed, 1723 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/chans.go2 b/src/cmd/compile/internal/syntax/testdata/go2/chans.go2 new file mode 100644 index 0000000..fad2bce --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/chans.go2 @@ -0,0 +1,62 @@ +package chans + +import "runtime" + +// Ranger returns a Sender and a Receiver. The Receiver provides a +// Next method to retrieve values. The Sender provides a Send method +// to send values and a Close method to stop sending values. The Next +// method indicates when the Sender has been closed, and the Send +// method indicates when the Receiver has been freed. +// +// This is a convenient way to exit a goroutine sending values when +// the receiver stops reading them. +func Ranger[T any]() (*Sender[T], *Receiver[T]) { + c := make(chan T) + d := make(chan bool) + s := &Sender[T]{values: c, done: d} + r := &Receiver[T]{values: c, done: d} + runtime.SetFinalizer(r, r.finalize) + return s, r +} + +// A sender is used to send values to a Receiver. +type Sender[T any] struct { + values chan<- T + done <-chan bool +} + +// Send sends a value to the receiver. It returns whether any more +// values may be sent; if it returns false the value was not sent. +func (s *Sender[T]) Send(v T) bool { + select { + case s.values <- v: + return true + case <-s.done: + return false + } +} + +// Close tells the receiver that no more values will arrive. +// After Close is called, the Sender may no longer be used. +func (s *Sender[T]) Close() { + close(s.values) +} + +// A Receiver receives values from a Sender. +type Receiver[T any] struct { + values <-chan T + done chan<- bool +} + +// Next returns the next value from the channel. The bool result +// indicates whether the value is valid, or whether the Sender has +// been closed and no more values will be received. +func (r *Receiver[T]) Next() (T, bool) { + v, ok := <-r.values + return v, ok +} + +// finalize is a finalizer for the receiver. +func (r *Receiver[T]) finalize() { + close(r.done) +} diff --git a/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2 b/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2 new file mode 100644 index 0000000..822d028 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2 @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package linalg + +import "math" + +// Numeric is type bound that matches any numeric type. +// It would likely be in a constraints package in the standard library. +type Numeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + float32 | ~float64 | + complex64 | ~complex128 +} + +func DotProduct[T Numeric](s1, s2 []T) T { + if len(s1) != len(s2) { + panic("DotProduct: slices of unequal length") + } + var r T + for i := range s1 { + r += s1[i] * s2[i] + } + return r +} + +// NumericAbs matches numeric types with an Abs method. +type NumericAbs[T any] interface { + Numeric + + Abs() T +} + +// AbsDifference computes the absolute value of the difference of +// a and b, where the absolute value is determined by the Abs method. +func AbsDifference[T NumericAbs[T]](a, b T) T { + d := a - b + return d.Abs() +} + +// OrderedNumeric is a type bound that matches numeric types that support the < operator. +type OrderedNumeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + float32 | ~float64 +} + +// Complex is a type bound that matches the two complex types, which do not have a < operator. +type Complex interface { + ~complex64 | ~complex128 +} + +// OrderedAbs is a helper type that defines an Abs method for +// ordered numeric types. +type OrderedAbs[T OrderedNumeric] T + +func (a OrderedAbs[T]) Abs() OrderedAbs[T] { + if a < 0 { + return -a + } + return a +} + +// ComplexAbs is a helper type that defines an Abs method for +// complex types. +type ComplexAbs[T Complex] T + +func (a ComplexAbs[T]) Abs() ComplexAbs[T] { + r := float64(real(a)) + i := float64(imag(a)) + d := math.Sqrt(r * r + i * i) + return ComplexAbs[T](complex(d, 0)) +} + +func OrderedAbsDifference[T OrderedNumeric](a, b T) T { + return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b))) +} + +func ComplexAbsDifference[T Complex](a, b T) T { + return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b))) +} diff --git a/src/cmd/compile/internal/syntax/testdata/go2/map.go2 b/src/cmd/compile/internal/syntax/testdata/go2/map.go2 new file mode 100644 index 0000000..814d953 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/map.go2 @@ -0,0 +1,113 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package orderedmap provides an ordered map, implemented as a binary tree. +package orderedmap + +// TODO(gri) fix imports for tests +import "chans" // ERROR could not import + +// Map is an ordered map. +type Map[K, V any] struct { + root *node[K, V] + compare func(K, K) int +} + +// node is the type of a node in the binary tree. +type node[K, V any] struct { + key K + val V + left, right *node[K, V] +} + +// New returns a new map. +func New[K, V any](compare func(K, K) int) *Map[K, V] { + return &Map[K, V]{compare: compare} +} + +// find looks up key in the map, and returns either a pointer +// to the node holding key, or a pointer to the location where +// such a node would go. +func (m *Map[K, V]) find(key K) **node[K, V] { + pn := &m.root + for *pn != nil { + switch cmp := m.compare(key, (*pn).key); { + case cmp < 0: + pn = &(*pn).left + case cmp > 0: + pn = &(*pn).right + default: + return pn + } + } + return pn +} + +// Insert inserts a new key/value into the map. +// If the key is already present, the value is replaced. +// Returns true if this is a new key, false if already present. +func (m *Map[K, V]) Insert(key K, val V) bool { + pn := m.find(key) + if *pn != nil { + (*pn).val = val + return false + } + *pn = &node[K, V]{key: key, val: val} + return true +} + +// Find returns the value associated with a key, or zero if not present. +// The found result reports whether the key was found. +func (m *Map[K, V]) Find(key K) (V, bool) { + pn := m.find(key) + if *pn == nil { + var zero V // see the discussion of zero values, above + return zero, false + } + return (*pn).val, true +} + +// keyValue is a pair of key and value used when iterating. +type keyValue[K, V any] struct { + key K + val V +} + +// InOrder returns an iterator that does an in-order traversal of the map. +func (m *Map[K, V]) InOrder() *Iterator[K, V] { + sender, receiver := chans.Ranger[keyValue[K, V]]() + var f func(*node[K, V]) bool + f = func(n *node[K, V]) bool { + if n == nil { + return true + } + // Stop sending values if sender.Send returns false, + // meaning that nothing is listening at the receiver end. + return f(n.left) && + sender.Send(keyValue[K, V]{n.key, n.val}) && + f(n.right) + } + go func() { + f(m.root) + sender.Close() + }() + return &Iterator[K, V]{receiver} +} + +// Iterator is used to iterate over the map. +type Iterator[K, V any] struct { + r *chans.Receiver[keyValue[K, V]] +} + +// Next returns the next key and value pair, and a boolean indicating +// whether they are valid or whether we have reached the end. +func (it *Iterator[K, V]) Next() (K, V, bool) { + keyval, ok := it.r.Next() + if !ok { + var zerok K + var zerov V + return zerok, zerov, false + } + return keyval.key, keyval.val, true +} diff --git a/src/cmd/compile/internal/syntax/testdata/go2/map2.go2 b/src/cmd/compile/internal/syntax/testdata/go2/map2.go2 new file mode 100644 index 0000000..2833445 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/map2.go2 @@ -0,0 +1,146 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is like map.go2, but instead if importing chans, it contains +// the necessary functionality at the end of the file. + +// Package orderedmap provides an ordered map, implemented as a binary tree. +package orderedmap + +// Map is an ordered map. +type Map[K, V any] struct { + root *node[K, V] + compare func(K, K) int +} + +// node is the type of a node in the binary tree. +type node[K, V any] struct { + key K + val V + left, right *node[K, V] +} + +// New returns a new map. +func New[K, V any](compare func(K, K) int) *Map[K, V] { + return &Map[K, V]{compare: compare} +} + +// find looks up key in the map, and returns either a pointer +// to the node holding key, or a pointer to the location where +// such a node would go. +func (m *Map[K, V]) find(key K) **node[K, V] { + pn := &m.root + for *pn != nil { + switch cmp := m.compare(key, (*pn).key); { + case cmp < 0: + pn = &(*pn).left + case cmp > 0: + pn = &(*pn).right + default: + return pn + } + } + return pn +} + +// Insert inserts a new key/value into the map. +// If the key is already present, the value is replaced. +// Returns true if this is a new key, false if already present. +func (m *Map[K, V]) Insert(key K, val V) bool { + pn := m.find(key) + if *pn != nil { + (*pn).val = val + return false + } + *pn = &node[K, V]{key: key, val: val} + return true +} + +// Find returns the value associated with a key, or zero if not present. +// The found result reports whether the key was found. +func (m *Map[K, V]) Find(key K) (V, bool) { + pn := m.find(key) + if *pn == nil { + var zero V // see the discussion of zero values, above + return zero, false + } + return (*pn).val, true +} + +// keyValue is a pair of key and value used when iterating. +type keyValue[K, V any] struct { + key K + val V +} + +// InOrder returns an iterator that does an in-order traversal of the map. +func (m *Map[K, V]) InOrder() *Iterator[K, V] { + sender, receiver := chans_Ranger[keyValue[K, V]]() + var f func(*node[K, V]) bool + f = func(n *node[K, V]) bool { + if n == nil { + return true + } + // Stop sending values if sender.Send returns false, + // meaning that nothing is listening at the receiver end. + return f(n.left) && + sender.Send(keyValue[K, V]{n.key, n.val}) && + f(n.right) + } + go func() { + f(m.root) + sender.Close() + }() + return &Iterator[K, V]{receiver} +} + +// Iterator is used to iterate over the map. +type Iterator[K, V any] struct { + r *chans_Receiver[keyValue[K, V]] +} + +// Next returns the next key and value pair, and a boolean indicating +// whether they are valid or whether we have reached the end. +func (it *Iterator[K, V]) Next() (K, V, bool) { + keyval, ok := it.r.Next() + if !ok { + var zerok K + var zerov V + return zerok, zerov, false + } + return keyval.key, keyval.val, true +} + +// chans + +func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T]) + +// A sender is used to send values to a Receiver. +type chans_Sender[T any] struct { + values chan<- T + done <-chan bool +} + +func (s *chans_Sender[T]) Send(v T) bool { + select { + case s.values <- v: + return true + case <-s.done: + return false + } +} + +func (s *chans_Sender[T]) Close() { + close(s.values) +} + +type chans_Receiver[T any] struct { + values <-chan T + done chan<- bool +} + +func (r *chans_Receiver[T]) Next() (T, bool) { + v, ok := <-r.values + return v, ok +}
\ No newline at end of file diff --git a/src/cmd/compile/internal/syntax/testdata/go2/slices.go2 b/src/cmd/compile/internal/syntax/testdata/go2/slices.go2 new file mode 100644 index 0000000..2bacd1c --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/slices.go2 @@ -0,0 +1,68 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package slices implements various slice algorithms. +package slices + +// Map turns a []T1 to a []T2 using a mapping function. +func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 { + r := make([]T2, len(s)) + for i, v := range s { + r[i] = f(v) + } + return r +} + +// Reduce reduces a []T1 to a single value using a reduction function. +func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 { + r := initializer + for _, v := range s { + r = f(r, v) + } + return r +} + +// Filter filters values from a slice using a filter function. +func Filter[T any](s []T, f func(T) bool) []T { + var r []T + for _, v := range s { + if f(v) { + r = append(r, v) + } + } + return r +} + +// Example uses + +func limiter(x int) byte { + switch { + case x < 0: + return 0 + default: + return byte(x) + case x > 255: + return 255 + } +} + +var input = []int{-4, 68954, 7, 44, 0, -555, 6945} +var limited1 = Map[int, byte](input, limiter) +var limited2 = Map(input, limiter) // using type inference + +func reducer(x float64, y int) float64 { + return x + float64(y) +} + +var reduced1 = Reduce[int, float64](input, 0, reducer) +var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference +var reduced3 = Reduce(input, 1, reducer) // using type inference + +func filter(x int) bool { + return x&1 != 0 +} + +var filtered1 = Filter[int](input, filter) +var filtered2 = Filter(input, filter) // using type inference + diff --git a/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2 b/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2 new file mode 100644 index 0000000..42efb42 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2 @@ -0,0 +1,83 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains basic generic code snippets. + +package p + +// type parameter lists +type B[P any] struct{} +type _[P interface{}] struct{} +type _[P B] struct{} +type _[P B[P]] struct{} + +type _[A, B, C any] struct{} +type _[A, B, C B] struct{} +type _[A, B, C B[A, B, C]] struct{} +type _[A1, A2 B1, A3 B2, A4, A5, A6 B3] struct{} + +type _[A interface{}] struct{} +type _[A, B interface{ m() }] struct{} + +type _[A, B, C any] struct{} + +// in functions +func _[P any]() +func _[P interface{}]() +func _[P B]() +func _[P B[P]]() + +// in methods +func (T) _[P any]() +func (T) _[P interface{}]() +func (T) _[P B]() +func (T) _[P B[P]]() + +// type instantiations +type _ T[int] + +// in expressions +var _ = T[int]{} + +// in embedded types +type _ struct{ T[int] } + +// interfaces +type _ interface{ + m() + ~int +} + +type _ interface{ + ~int | ~float | ~string + ~complex128 + underlying(underlying underlying) underlying +} + +type _ interface{ + T + T[int] +} + +// tricky cases +func _(T[P], T[P1, P2]) +func _(a [N]T) + +type _ struct{ + T[P] + T[P1, P2] + f [N] +} +type _ interface{ + m() + + // generic methods - disabled for now + // m[] /* ERROR empty type parameter list */ () + // m[ /* ERROR cannot have type parameters */ P any](P) + + // instantiated types + // T[] /* ERROR empty type argument list */ + T[P] + T[P1, P2] +} diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2 new file mode 100644 index 0000000..a422d5e --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2 @@ -0,0 +1,60 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type myInt int + +// Parameterized type declarations + +type T1[P any] P + +type T2[P any] struct { + f P + g int // int should still be in scope chain +} + +type List[P any] []P + +// Alias type declarations cannot have type parameters. Syntax error. +// TODO(gri) Disabled for now as we don't check syntax error here. +// type A1[P any] = /* ERROR cannot be alias */ P + +// But an alias may refer to a generic, uninstantiated type. +type A2 = List +var _ A2[int] +var _ A2 /* ERROR without instantiation */ + +type A3 = List[int] +var _ A3 + +// Parameterized type instantiations + +var x int +type _ x /* ERROR not a type */ [int] + +type _ int /* ERROR not a generic type */ [int] +type _ myInt /* ERROR not a generic type */ [int] + +// TODO(gri) better error messages +type _ T1[int] +type _ T1[x /* ERROR not a type */ ] +type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32] + +var _ T2[int] = T2[int]{} + +var _ List[int] = []int{1, 2, 3} +var _ List[[]int] = [][]int{{1, 2, 3}} +var _ List[List[List[int]]] + +// Parameterized types containing parameterized types + +type T3[P any] List[P] + +var _ T3[int] = T3[int](List[int]{1, 2, 3}) + +// Self-recursive generic types are not permitted + +type self1[P any] self1 /* ERROR illegal cycle */ [P] +type self2[P any] *self2[P] // this is ok diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2 new file mode 100644 index 0000000..76b8d55 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2 @@ -0,0 +1,232 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type List[E any] []E +var _ List[List[List[int]]] +var _ List[List[List[int]]] = []List[List[int]]{} + +type ( + T1[P1 any] struct { + f1 T2[P1, float32] + } + + T2[P2, P3 any] struct { + f2 P2 + f3 P3 + } +) + +func _() { + var x1 T1[int] + var x2 T2[int, float32] + + x1.f1.f2 = 0 + x1.f1 = x2 +} + +type T3[P any] T1[T2[P, P]] + +func _() { + var x1 T3[int] + var x2 T2[int, int] + x1.f1.f2 = x2 +} + +func f[P any] (x P) List[P] { + return List[P]{x} +} + +var ( + _ []int = f(0) + _ []float32 = f[float32](10) + _ List[complex128] = f(1i) + _ []List[int] = f(List[int]{}) + _ List[List[int]] = []List[int]{} + _ = []List[int]{} +) + +// Parameterized types with methods + +func (l List[E]) Head() (_ E, _ bool) { + if len(l) > 0 { + return l[0], true + } + return +} + +// A test case for instantiating types with other types (extracted from map.go2) + +type Pair[K any] struct { + key K +} + +type Receiver[T any] struct { + values T +} + +type Iterator[K any] struct { + r Receiver[Pair[K]] +} + +func Values [T any] (r Receiver[T]) T { + return r.values +} + +func (it Iterator[K]) Next() K { + return Values[Pair[K]](it.r).key +} + +// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence) + +type NumericAbs[T any] interface { + Abs() T +} + +func AbsDifference[T NumericAbs[T]](x T) + +type OrderedAbs[T any] T + +func (a OrderedAbs[T]) Abs() OrderedAbs[T] + +func OrderedAbsDifference[T any](x T) { + AbsDifference(OrderedAbs[T](x)) +} + +// same code, reduced to essence + +func g[P interface{ m() P }](x P) + +type T4[P any] P + +func (_ T4[P]) m() T4[P] + +func _[Q any](x Q) { + g(T4[Q](x)) +} + +// Another test case that caused problems in the past + +type T5[_ interface { a() }, _ interface{}] struct{} + +type A[P any] struct{ x P } + +func (_ A[P]) a() {} + +var _ T5[A[int], int] + +// Invoking methods with parameterized receiver types uses +// type inference to determine the actual type arguments matching +// the receiver type parameters from the actual receiver argument. +// Go does implicit address-taking and dereferenciation depending +// on the actual receiver and the method's receiver type. To make +// type inference work, the type-checker matches "pointer-ness" +// of the actual receiver and the method's receiver type. +// The following code tests this mechanism. + +type R1[A any] struct{} +func (_ R1[A]) vm() +func (_ *R1[A]) pm() + +func _[T any](r R1[T], p *R1[T]) { + r.vm() + r.pm() + p.vm() + p.pm() +} + +type R2[A, B any] struct{} +func (_ R2[A, B]) vm() +func (_ *R2[A, B]) pm() + +func _[T any](r R2[T, int], p *R2[string, T]) { + r.vm() + r.pm() + p.vm() + p.pm() +} + +// Interface type constraints can contain any type, incl. *Named types. +// Verify that we use the underlying type to compute the operational type. +type MyInt int +func add1[T interface{ ~MyInt }](x T) T { + return x + 1 +} + +type MyString string +func double[T interface{ ~MyInt | ~MyString }](x T) T { + return x + x +} + +// Embedding of interfaces with type constraints leads to interfaces +// with type constraints that are the intersection of the embedded +// type constraints. + +type E0 interface { + ~int | ~bool | ~string +} + +type E1 interface { + ~int | ~float64 | ~string +} + +type E2 interface { + ~float64 +} + +type I0 interface { + E0 +} + +func f0[T I0]() +var _ = f0[int] +var _ = f0[bool] +var _ = f0[string] +var _ = f0[float64 /* ERROR does not satisfy I0 */ ] + +type I01 interface { + E0 + E1 +} + +func f01[T I01]() +var _ = f01[int] +var _ = f01[bool /* ERROR does not satisfy I0 */ ] +var _ = f01[string] +var _ = f01[float64 /* ERROR does not satisfy I0 */ ] + +type I012 interface { + E0 + E1 + E2 +} + +func f012[T I012]() +var _ = f012[int /* ERROR does not satisfy I012 */ ] +var _ = f012[bool /* ERROR does not satisfy I012 */ ] +var _ = f012[string /* ERROR does not satisfy I012 */ ] +var _ = f012[float64 /* ERROR does not satisfy I012 */ ] + +type I12 interface { + E1 + E2 +} + +func f12[T I12]() +var _ = f12[int /* ERROR does not satisfy I12 */ ] +var _ = f12[bool /* ERROR does not satisfy I12 */ ] +var _ = f12[string /* ERROR does not satisfy I12 */ ] +var _ = f12[float64] + +type I0_ interface { + E0 + ~int +} + +func f0_[T I0_]() +var _ = f0_[int] +var _ = f0_[bool /* ERROR does not satisfy I0_ */ ] +var _ = f0_[string /* ERROR does not satisfy I0_ */ ] +var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ] diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2 new file mode 100644 index 0000000..111f7c1 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2 @@ -0,0 +1,451 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +// import "io" // for type assertion tests + +// The predeclared identifier "any" is only visible as a constraint +// in a type parameter list. +var _ any // ERROR undeclared +func _[_ any /* ok here */ , _ interface{any /* ERROR undeclared */ }](any /* ERROR undeclared */ ) { + var _ any /* ERROR undeclared */ +} + +func identity[T any](x T) T { return x } + +func _[_ any](x int) int +func _[T any](T /* ERROR redeclared */ T)() +func _[T, T /* ERROR redeclared */ any]() + +func reverse[T any](list []T) []T { + rlist := make([]T, len(list)) + i := len(list) + for _, x := range list { + i-- + rlist[i] = x + } + return rlist +} + +var _ = reverse /* ERROR cannot use generic function reverse */ +var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3}) +var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3}) +var f = reverse[chan int] +var _ = f(0 /* ERROR cannot convert 0 .* to \[\]chan int */ ) + +func swap[A, B any](a A, b B) (B, A) { return b, a } + +var _ = swap /* ERROR single value is expected */ [int, float32](1, 2) +var f32, i = swap[int, float32](swap(float32, int)(1, 2)) +var _ float32 = f32 +var _ int = i + +func swapswap[A, B any](a A, b B) (A, B) { + return swap[B, A](b, a) +} + +type F[A, B any] func(A, B) (B, A) + +func min[T interface{ ~int }](x, y T) T { + if x < y { + return x + } + return y +} + +func _[T interface{ ~int | ~float32 }](x, y T) bool { return x < y } +func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y } +func _[T interface{ ~int | ~float32 | ~bool }](x, y T) bool { return x /* ERROR cannot compare */ < y } + +func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y } +func _[T C2[T]](x, y T) bool { return x < y } + +type C1[T any] interface{} +type C2[T any] interface{ ~int | ~float32 } + +func new[T any]() *T { + var x T + return &x +} + +var _ = new /* ERROR cannot use generic function new */ +var _ *int = new[int]() + +func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable + +func f1[T1 any](struct{T1}) int +var _ = f1(int)(struct{T1}{}) +type T1 = int + +func f2[t1 any](struct{t1; x float32}) int +var _ = f2(t1)(struct{t1; x float32}{}) +type t1 = int + + +func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int + +var _ = f3[int, rune, bool](1, struct{x rune}{}, nil) + +// indexing + +func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~string }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[10]int | ~*[20]int | ~map[string]int }] (x T, i int) { _ = x[i] } +func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } + +// slicing +// TODO(gri) implement this + +func _[T interface{ ~string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] } + +// len/cap built-ins + +func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string }](x T) { _ = len(x) } +func _[T interface{ ~[10]int }](x T) { _ = len(x) } +func _[T interface{ ~[]byte }](x T) { _ = len(x) } +func _[T interface{ ~map[int]int }](x T) { _ = len(x) } +func _[T interface{ ~chan int }](x T) { _ = len(x) } +func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) } + +func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~[10]int }](x T) { _ = cap(x) } +func _[T interface{ ~[]byte }](x T) { _ = cap(x) } +func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~chan int }](x T) { _ = cap(x) } +func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) } + +// range iteration + +func _[T interface{}](x T) { + for range x /* ERROR cannot range */ {} +} + +func _[T interface{ ~string | ~[]string }](x T) { + for range x {} + for i := range x { _ = i } + for i, _ := range x { _ = i } + for i, e := range x /* ERROR must have the same element type */ { _ = i } + for _, e := range x /* ERROR must have the same element type */ {} + var e rune + _ = e + for _, (e) = range x /* ERROR must have the same element type */ {} +} + + +func _[T interface{ ~string | ~[]rune | ~map[int]rune }](x T) { + for _, e := range x { _ = e } + for i, e := range x { _ = i; _ = e } +} + +func _[T interface{ ~string | ~[]rune | ~map[string]rune }](x T) { + for _, e := range x { _ = e } + for i, e := range x /* ERROR must have the same key type */ { _ = e } +} + +func _[T interface{ ~string | ~chan int }](x T) { + for range x {} + for i := range x { _ = i } + for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value +} + +func _[T interface{ ~string | ~chan<-int }](x T) { + for i := range x /* ERROR send-only channel */ { _ = i } +} + +// type inference checks + +var _ = new() /* ERROR cannot infer T */ + +func f4[A, B, C any](A, B) C + +var _ = f4(1, 2) /* ERROR cannot infer C */ +var _ = f4[int, float32, complex128](1, 2) + +func f5[A, B, C any](A, []*B, struct{f []C}) int + +var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{}) +var _ = f5(0, nil, struct{f []complex128}{}) // ERROR cannot infer +var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{}) + +func f6[A any](A, []A) int + +var _ = f6(0, nil) + +func f6nil[A any](A) int + +var _ = f6nil(nil) // ERROR cannot infer + +// type inference with variadic functions + +func f7[T any](...T) T + +var _ int = f7() /* ERROR cannot infer T */ +var _ int = f7(1) +var _ int = f7(1, 2) +var _ int = f7([]int{}...) +var _ int = f7 /* ERROR cannot use */ ([]float64{}...) +var _ float64 = f7([]float64{}...) +var _ = f7[float64](1, 2.3) +var _ = f7(float64(1), 2.3) +var _ = f7(1, 2.3 /* ERROR does not match */ ) +var _ = f7(1.2, 3 /* ERROR does not match */ ) + +func f8[A, B any](A, B, ...B) int + +var _ = f8(1) /* ERROR not enough arguments */ +var _ = f8(1, 2.3) +var _ = f8(1, 2.3, 3.4, 4.5) +var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ ) +var _ = f8(int, float64)(1, 2.3, 3.4, 4) + +var _ = f8(int, float64)(0, 0, nil...) // test case for #18268 + +// init functions cannot have type parameters + +func init() {} +func init[/* ERROR func init must have no type parameters */ _ any]() {} +func init[/* ERROR func init must have no type parameters */ P any]() {} + +type T struct {} + +func (T) m1() {} +// The type checker accepts method type parameters if configured accordingly. +func (T) m2[_ any]() {} +func (T) m3[P any]() {} + +// type inference across parameterized types + +type S1[P any] struct { f P } + +func f9[P any](x S1[P]) + +func _() { + f9[int](S1[int]{42}) + f9(S1[int]{42}) +} + +type S2[A, B, C any] struct{} + +func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) + +func _[P any]() { + f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{}) + f10(S2[int, int, string]{}, S2[int, float32, bool]{}) + f10(S2[P, int, P]{}, S2[P, float32, bool]{}) +} + +// corner case for type inference +// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic) + +func f11[T any]() + +func _() { + f11[int]() +} + +// the previous example was extracted from + +func f12[T interface{m() T}]() + +type A[T any] T + +func (a A[T]) m() A[T] + +func _[T any]() { + f12(A[T])() +} + +// method expressions + +func (_ S1[P]) m() + +func _() { + m := S1[int].m + m(struct { f int }{42}) +} + +func _[T any] (x T) { + m := S1[T].m + m(S1[T]{x}) +} + +// type parameters in methods (generalization) + +type R0 struct{} + +func (R0) _[T any](x T) +func (R0 /* ERROR invalid receiver */ ) _[R0 any]() // scope of type parameters starts at "func" + +type R1[A, B any] struct{} + +func (_ R1[A, B]) m0(A, B) +func (_ R1[A, B]) m1[T any](A, B, T) T +func (_ R1 /* ERROR not a generic type */ [R1, _]) _() +func (_ R1[A, B]) _[A /* ERROR redeclared */ any](B) + +func _() { + var r R1[int, string] + r.m1[rune](42, "foo", 'a') + r.m1[rune](42, "foo", 1.2 /* ERROR truncated to rune */) + r.m1(42, "foo", 1.2) // using type inference + var _ float64 = r.m1(42, "foo", 1.2) +} + +type I1[A any] interface { + m1(A) +} + +var _ I1[int] = r1[int]{} + +type r1[T any] struct{} + +func (_ r1[T]) m1(T) + +type I2[A, B any] interface { + m1(A) + m2(A) B +} + +var _ I2[int, float32] = R2[int, float32]{} + +type R2[P, Q any] struct{} + +func (_ R2[X, Y]) m1(X) +func (_ R2[X, Y]) m2(X) Y + +// type assertions and type switches over generic types +// NOTE: These are currently disabled because it's unclear what the correct +// approach is, and one can always work around by assigning the variable to +// an interface first. + +// // ReadByte1 corresponds to the ReadByte example in the draft design. +// func ReadByte1[T io.Reader](r T) (byte, error) { +// if br, ok := r.(io.ByteReader); ok { +// return br.ReadByte() +// } +// var b [1]byte +// _, err := r.Read(b[:]) +// return b[0], err +// } +// +// // ReadBytes2 is like ReadByte1 but uses a type switch instead. +// func ReadByte2[T io.Reader](r T) (byte, error) { +// switch br := r.(type) { +// case io.ByteReader: +// return br.ReadByte() +// } +// var b [1]byte +// _, err := r.Read(b[:]) +// return b[0], err +// } +// +// // type assertions and type switches over generic types are strict +// type I3 interface { +// m(int) +// } +// +// type I4 interface { +// m() int // different signature from I3.m +// } +// +// func _[T I3](x I3, p T) { +// // type assertions and type switches over interfaces are not strict +// _ = x.(I4) +// switch x.(type) { +// case I4: +// } +// +// // type assertions and type switches over generic types are strict +// _ = p /* ERROR cannot have dynamic type I4 */.(I4) +// switch p.(type) { +// case I4 /* ERROR cannot have dynamic type I4 */ : +// } +// } + +// type assertions and type switches over generic types lead to errors for now + +func _[T any](x T) { + _ = x /* ERROR not an interface */ .(int) + switch x /* ERROR not an interface */ .(type) { + } + + // work-around + var t interface{} = x + _ = t.(int) + switch t.(type) { + } +} + +func _[T interface{ ~int }](x T) { + _ = x /* ERROR not an interface */ .(int) + switch x /* ERROR not an interface */ .(type) { + } + + // work-around + var t interface{} = x + _ = t.(int) + switch t.(type) { + } +} + +// error messages related to type bounds mention those bounds +type C[P any] interface{} + +func _[P C[P]] (x P) { + x.m /* ERROR x.m undefined */ () +} + +type I interface {} + +func _[P I] (x P) { + x.m /* ERROR interface I has no method m */ () +} + +func _[P interface{}] (x P) { + x.m /* ERROR type bound for P has no method m */ () +} + +func _[P any] (x P) { + x.m /* ERROR type bound for P has no method m */ () +} + +// automatic distinguishing between array and generic types +// NOTE: Disabled when using unified parameter list syntax. +/* +const P = 10 +type A1 [P]byte +func _(a A1) { + assert(len(a) == 10) +} + +type A2 [P]struct{ + f [P]byte +} +func _(a A2) { + assert(len(a) == 10) + assert(len(a[0].f) == 10) +} + +type A3 [P]func(x [P]A3) +func _(a A3) { + assert(len(a) == 10) +} + +type T2[P] struct{ P } +var _ T2[int] + +type T3[P] func(P) +var _ T3[int] +*/
\ No newline at end of file diff --git a/src/cmd/compile/internal/syntax/testdata/interface.go2 b/src/cmd/compile/internal/syntax/testdata/interface.go2 new file mode 100644 index 0000000..dbc4187 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/interface.go2 @@ -0,0 +1,74 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains test cases for interfaces containing +// constraint elements. + +package p + +type _ interface { + m() + E +} + +type _ interface { + m() + ~int + int | string + int | ~string + ~int | ~string +} + +type _ interface { + m() + ~int + T[int, string] | string + int | ~T[string, struct{}] + ~int | ~string +} + +type _ interface { + int + []byte + [10]int + struct{} + *int + func() + interface{} + map[string]int + chan T + chan<- T + <-chan T + T[int] +} + +type _ interface { + int | string + []byte | string + [10]int | string + struct{} | string + *int | string + func() | string + interface{} | string + map[string]int | string + chan T | string + chan<- T | string + <-chan T | string + T[int] | string +} + +type _ interface { + ~int | string + ~[]byte | string + ~[10]int | string + ~struct{} | string + ~*int | string + ~func() | string + ~interface{} | string + ~map[string]int | string + ~chan T | string + ~chan<- T | string + ~<-chan T | string + ~T[int] | string +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue20789.src b/src/cmd/compile/internal/syntax/testdata/issue20789.src new file mode 100644 index 0000000..5f150db --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue20789.src @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Make sure this doesn't crash the compiler. +// Line 9 must end in EOF for this test (no newline). + +package e +func([<-chan<-[func /* ERROR unexpected u */ u){go /* ERROR must be function call */
\ No newline at end of file diff --git a/src/cmd/compile/internal/syntax/testdata/issue23385.src b/src/cmd/compile/internal/syntax/testdata/issue23385.src new file mode 100644 index 0000000..2459a73 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue23385.src @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Check error message for use of = instead of == . + +package p + +func _() { + if true || 0 /* ERROR cannot use assignment .* as value */ = 1 { + } +} + +func _(a, b string) { + if a == "a" && b /* ERROR cannot use assignment .* as value */ = "b" { + } +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue23434.src b/src/cmd/compile/internal/syntax/testdata/issue23434.src new file mode 100644 index 0000000..5a72a7f --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue23434.src @@ -0,0 +1,31 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test case for issue 23434: Better synchronization of +// parser after missing type. There should be exactly +// one error each time, with now follow errors. + +package p + +type T /* ERROR unexpected newline */ + +type Map map[int] /* ERROR unexpected newline */ + +// Examples from #23434: + +func g() { + m := make(map[string] /* ERROR unexpected ! */ !) + for { + x := 1 + print(x) + } +} + +func f() { + m := make(map[string] /* ERROR unexpected \) */ ) + for { + x := 1 + print(x) + } +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue31092.src b/src/cmd/compile/internal/syntax/testdata/issue31092.src new file mode 100644 index 0000000..b1839b8 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue31092.src @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test cases for issue 31092: Better synchronization of +// parser after seeing an := rather than an = in a const, +// type, or variable declaration. + +package p + +const _ /* ERROR unexpected := */ := 0 +type _ /* ERROR unexpected := */ := int +var _ /* ERROR unexpected := */ := 0 + +const _ int /* ERROR unexpected := */ := 0 +var _ int /* ERROR unexpected := */ := 0 diff --git a/src/cmd/compile/internal/syntax/testdata/issue43527.go2 b/src/cmd/compile/internal/syntax/testdata/issue43527.go2 new file mode 100644 index 0000000..dd2c9b1 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue43527.go2 @@ -0,0 +1,23 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type ( + // 0 and 1-element []-lists are syntactically valid + _[A, B /* ERROR missing type constraint */ ] int + _[A, /* ERROR type parameters must be named */ interface{}] int + _[A, B, C /* ERROR missing type constraint */ ] int + _[A B, C /* ERROR missing type constraint */ ] int + _[A B, /* ERROR type parameters must be named */ interface{}] int + _[A B, /* ERROR type parameters must be named */ interface{}, C D] int + _[A B, /* ERROR type parameters must be named */ interface{}, C, D] int + _[A B, /* ERROR type parameters must be named */ interface{}, C, interface{}] int + _[A B, C interface{}, D, /* ERROR type parameters must be named */ interface{}] int +) + +// function type parameters use the same parsing routine - just have a couple of tests + +func _[A, B /* ERROR missing type constraint */ ]() {} +func _[A, /* ERROR type parameters must be named */ interface{}]() {} diff --git a/src/cmd/compile/internal/syntax/testdata/issue43674.src b/src/cmd/compile/internal/syntax/testdata/issue43674.src new file mode 100644 index 0000000..51c692a --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue43674.src @@ -0,0 +1,13 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func _(... /* ERROR [.][.][.] is missing type */ ) +func _(... /* ERROR [.][.][.] is missing type */ , int) + +func _(a, b ... /* ERROR [.][.][.] is missing type */ ) +func _(a, b ... /* ERROR [.][.][.] is missing type */ , x int) + +func _()(... /* ERROR [.][.][.] is missing type */ ) diff --git a/src/cmd/compile/internal/syntax/testdata/issue46558.src b/src/cmd/compile/internal/syntax/testdata/issue46558.src new file mode 100644 index 0000000..a22b600 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue46558.src @@ -0,0 +1,14 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func F(s string) { + switch s[0] { + case 'a': + case s[2] { // ERROR unexpected { + case 'b': + } + } +} // ERROR non-declaration statement diff --git a/src/cmd/compile/internal/syntax/testdata/issue47704.go2 b/src/cmd/compile/internal/syntax/testdata/issue47704.go2 new file mode 100644 index 0000000..4e65857 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue47704.go2 @@ -0,0 +1,18 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +// error messages for parser in generic mode +func _() { + _ = m[] // ERROR expecting operand + _ = m[x,] + _ = m[x /* ERROR unexpected a */ a b c d] +} + +// test case from the issue +func f(m map[int]int) int { + return m[0 // ERROR expecting comma, \: or \] + ] +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue47704.src b/src/cmd/compile/internal/syntax/testdata/issue47704.src new file mode 100644 index 0000000..0156af7 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue47704.src @@ -0,0 +1,18 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +// error messages for parser in non-generic mode +func _() { + _ = m[] // ERROR expecting operand + _ = m[x,] // ERROR unexpected comma, expecting \: or \] + _ = m[x /* ERROR unexpected a */ a b c d] +} + +// test case from the issue +func f(m map[int]int) int { + return m[0 // ERROR expecting \: or \] + ] +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue48382.go2 b/src/cmd/compile/internal/syntax/testdata/issue48382.go2 new file mode 100644 index 0000000..c00fee6 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue48382.go2 @@ -0,0 +1,15 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type _ func /* ERROR function type must have no type parameters */ [ /* ERROR empty type parameter list */ ]() +type _ func /* ERROR function type must have no type parameters */ [ x /* ERROR missing type constraint */ ]() +type _ func /* ERROR function type must have no type parameters */ [P any]() + +var _ = func /* ERROR function literal must have no type parameters */ [P any]() {} + +type _ interface{ + m /* ERROR interface method must have no type parameters */ [P any]() +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue49482.go2 b/src/cmd/compile/internal/syntax/testdata/issue49482.go2 new file mode 100644 index 0000000..1fc303d --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue49482.go2 @@ -0,0 +1,31 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type ( + // these need a comma to disambiguate + _[P *T,] struct{} + _[P *T, _ any] struct{} + _[P (*T),] struct{} + _[P (*T), _ any] struct{} + _[P (T),] struct{} + _[P (T), _ any] struct{} + + // these parse as name followed by type + _[P *struct{}] struct{} + _[P (*struct{})] struct{} + _[P ([]int)] struct{} + + // array declarations + _ [P(T)]struct{} + _ [P((T))]struct{} + _ [P * *T] struct{} // this could be a name followed by a type but it makes the rules more complicated + _ [P * T]struct{} + _ [P(*T)]struct{} + _ [P(**T)]struct{} + _ [P * T - T]struct{} + _ [P*T-T /* ERROR unexpected comma */ ,]struct{} + _ [10 /* ERROR unexpected comma */ ,]struct{} +) diff --git a/src/cmd/compile/internal/syntax/testdata/sample.src b/src/cmd/compile/internal/syntax/testdata/sample.src new file mode 100644 index 0000000..5a2b4bf --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/sample.src @@ -0,0 +1,33 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This is a sample test file illustrating the use +// of error comments with the error test harness. + +package p + +// The following are invalid error comments; they are +// silently ignored. The prefix must be exactly one of +// "/* ERROR " or "// ERROR ". +// +/*ERROR*/ +/*ERROR foo*/ +/* ERRORfoo */ +/* ERROR foo */ +//ERROR +// ERROR +// ERRORfoo +// ERROR foo + +// This is a valid error comment; it applies to the +// immediately following token. +import "math" /* ERROR unexpected comma */ , + +// If there are multiple /*-style error comments before +// the next token, only the last one is considered. +type x = /* ERROR ignored */ /* ERROR literal 0 in type declaration */ 0 + +// A //-style error comment matches any error position +// on the same line. +func () foo() // ERROR method has no receiver diff --git a/src/cmd/compile/internal/syntax/testdata/tparams.go2 b/src/cmd/compile/internal/syntax/testdata/tparams.go2 new file mode 100644 index 0000000..a9bd72c --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/tparams.go2 @@ -0,0 +1,24 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type t[a, b /* ERROR missing type constraint */ ] struct{} +type t[a t, b t, c /* ERROR missing type constraint */ ] struct{} +type t struct { + t [n]byte + t[a] + t[a, b] +} +type t interface { + t[a] + m /* ERROR method must have no type parameters */ [_ _, /* ERROR mixed */ _]() + t[a, b] +} + +func f[ /* ERROR empty type parameter list */ ]() +func f[a, b /* ERROR missing type constraint */ ]() +func f[a t, b t, c /* ERROR missing type constraint */ ]() + +func f[a b, /* ERROR expecting ] */ 0] () diff --git a/src/cmd/compile/internal/syntax/testdata/typeset.go2 b/src/cmd/compile/internal/syntax/testdata/typeset.go2 new file mode 100644 index 0000000..19b74f2 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/typeset.go2 @@ -0,0 +1,89 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains test cases for typeset-only constraint elements. + +package p + +type ( + _[_ t] t + _[_ ~t] t + _[_ t|t] t + _[_ ~t|t] t + _[_ t|~t] t + _[_ ~t|~t] t + + _[_ t, _, _ t|t] t + _[_ t, _, _ ~t|t] t + _[_ t, _, _ t|~t] t + _[_ t, _, _ ~t|~t] t + + _[_ t.t] t + _[_ ~t.t] t + _[_ t.t|t.t] t + _[_ ~t.t|t.t] t + _[_ t.t|~t.t] t + _[_ ~t.t|~t.t] t + + _[_ t, _, _ t.t|t.t] t + _[_ t, _, _ ~t.t|t.t] t + _[_ t, _, _ t.t|~t.t] t + _[_ t, _, _ ~t.t|~t.t] t + + _[_ struct{}] t + _[_ ~struct{}] t + + _[_ struct{}|t] t + _[_ ~struct{}|t] t + _[_ struct{}|~t] t + _[_ ~struct{}|~t] t + + _[_ t|struct{}] t + _[_ ~t|struct{}] t + _[_ t|~struct{}] t + _[_ ~t|~struct{}] t + + // test cases for issue #49175 + _[_ []t]t + _[_ [1]t]t + _[_ ~[]t]t + _[_ ~[1]t]t + t [ /* ERROR type parameters must be named */ t[0]]t +) + +// test cases for issue #49174 +func _[_ t]() {} +func _[_ []t]() {} +func _[_ [1]t]() {} +func _[_ []t | t]() {} +func _[_ [1]t | t]() {} +func _[_ t | []t]() {} +func _[_ []t | []t]() {} +func _[_ [1]t | [1]t]() {} +func _[_ t[t] | t[t]]() {} + +// Single-expression type parameter lists and those that don't start +// with a (type parameter) name are considered array sizes. +// The term must be a valid expression (it could be a type - and then +// a type-checker will complain - but we don't allow ~ in the expr). +type ( + _[t] t + _[/* ERROR unexpected ~ */ ~t] t + _[t|t] t + _[/* ERROR unexpected ~ */ ~t|t] t + _[t| /* ERROR unexpected ~ */ ~t] t + _[/* ERROR unexpected ~ */ ~t|~t] t +) + +type ( + _[_ t, t /* ERROR missing type constraint */ ] t + _[_ ~t, t /* ERROR missing type constraint */ ] t + _[_ t, /* ERROR type parameters must be named */ ~t] t + _[_ ~t, /* ERROR type parameters must be named */ ~t] t + + _[_ t|t, /* ERROR type parameters must be named */ t|t] t + _[_ ~t|t, /* ERROR type parameters must be named */ t|t] t + _[_ t|t, /* ERROR type parameters must be named */ ~t|t] t + _[_ ~t|t, /* ERROR type parameters must be named */ ~t|t] t +) |