diff options
Diffstat (limited to 'src/cmd/compile/internal/syntax/testdata')
26 files changed, 1119 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/syntax/testdata/chans.go b/src/cmd/compile/internal/syntax/testdata/chans.go new file mode 100644 index 0000000..d4c4207 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/chans.go @@ -0,0 +1,66 @@ +// Copyright 2022 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 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/fallthrough.go b/src/cmd/compile/internal/syntax/testdata/fallthrough.go new file mode 100644 index 0000000..851da81 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/fallthrough.go @@ -0,0 +1,55 @@ +// Copyright 2022 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 fallthroughs + +func _() { + var x int + switch x { + case 0: + fallthrough + + case 1: + fallthrough // ERROR fallthrough statement out of place + { + } + + case 2: + { + fallthrough // ERROR fallthrough statement out of place + } + + case 3: + for { + fallthrough // ERROR fallthrough statement out of place + } + + case 4: + fallthrough // trailing empty statements are ok + ; + ; + + case 5: + fallthrough + + default: + fallthrough // ERROR cannot fallthrough final case in switch + } + + fallthrough // ERROR fallthrough statement out of place + + if true { + fallthrough // ERROR fallthrough statement out of place + } + + for { + fallthrough // ERROR fallthrough statement out of place + } + + var t any + switch t.(type) { + case int: + fallthrough // ERROR cannot fallthrough in type switch + } +} diff --git a/src/cmd/compile/internal/syntax/testdata/interface.go b/src/cmd/compile/internal/syntax/testdata/interface.go new file mode 100644 index 0000000..dbc4187 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/interface.go @@ -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.go b/src/cmd/compile/internal/syntax/testdata/issue20789.go new file mode 100644 index 0000000..0d5988b --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue20789.go @@ -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
\ No newline at end of file diff --git a/src/cmd/compile/internal/syntax/testdata/issue23385.go b/src/cmd/compile/internal/syntax/testdata/issue23385.go new file mode 100644 index 0000000..2459a73 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue23385.go @@ -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.go b/src/cmd/compile/internal/syntax/testdata/issue23434.go new file mode 100644 index 0000000..e436abf --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue23434.go @@ -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 go.dev/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 go.dev/issue/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.go b/src/cmd/compile/internal/syntax/testdata/issue31092.go new file mode 100644 index 0000000..0bd40bd --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue31092.go @@ -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 go.dev/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.go b/src/cmd/compile/internal/syntax/testdata/issue43527.go new file mode 100644 index 0000000..99a8c09 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue43527.go @@ -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 missing type parameter name */ interface{}] int + _[A, B, C /* ERROR missing type constraint */ ] int + _[A B, C /* ERROR missing type constraint */ ] int + _[A B, /* ERROR missing type parameter name */ interface{}] int + _[A B, /* ERROR missing type parameter name */ interface{}, C D] int + _[A B, /* ERROR missing type parameter name */ interface{}, C, D] int + _[A B, /* ERROR missing type parameter name */ interface{}, C, interface{}] int + _[A B, C interface{}, D, /* ERROR missing type parameter name */ 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 missing type parameter name */ interface{}]() {} diff --git a/src/cmd/compile/internal/syntax/testdata/issue43674.go b/src/cmd/compile/internal/syntax/testdata/issue43674.go new file mode 100644 index 0000000..51c692a --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue43674.go @@ -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.go b/src/cmd/compile/internal/syntax/testdata/issue46558.go new file mode 100644 index 0000000..a22b600 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue46558.go @@ -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.go b/src/cmd/compile/internal/syntax/testdata/issue47704.go new file mode 100644 index 0000000..e4cdad1 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue47704.go @@ -0,0 +1,17 @@ +// 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 _() { + _ = m[] // ERROR expected 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 expected comma, \: or \] + ] +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue48382.go b/src/cmd/compile/internal/syntax/testdata/issue48382.go new file mode 100644 index 0000000..7c024a0 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue48382.go @@ -0,0 +1,16 @@ +// 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 type must have no type parameters */ [P any]())(nil) +var _ = func /* ERROR function type 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/issue49205.go b/src/cmd/compile/internal/syntax/testdata/issue49205.go new file mode 100644 index 0000000..bbcc950 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue49205.go @@ -0,0 +1,27 @@ +// Copyright 2022 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 + +// test case from issue + +type _ interface{ + m /* ERROR unexpected int in interface type; possibly missing semicolon or newline or } */ int +} + +// other cases where the fix for this issue affects the error message + +const ( + x int = 10 /* ERROR unexpected literal "foo" in grouped declaration; possibly missing semicolon or newline or \) */ "foo" +) + +var _ = []int{1, 2, 3 /* ERROR unexpected int in composite literal; possibly missing comma or } */ int } + +type _ struct { + x y /* ERROR syntax error: unexpected comma in struct type; possibly missing semicolon or newline or } */ , +} + +func f(a, b c /* ERROR unexpected d in parameter list; possibly missing comma or \) */ d) { + f(a, b, c /* ERROR unexpected d in argument list; possibly missing comma or \) */ d) +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue49482.go b/src/cmd/compile/internal/syntax/testdata/issue49482.go new file mode 100644 index 0000000..1fc303d --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue49482.go @@ -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/issue52391.go b/src/cmd/compile/internal/syntax/testdata/issue52391.go new file mode 100644 index 0000000..f2098ce --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue52391.go @@ -0,0 +1,17 @@ +// Copyright 2022 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 _ interface { + int + (int) + (*int) + *([]byte) + ~(int) + (int) | (string) + (int) | ~(string) + (/* ERROR unexpected ~ */ ~int) + (int /* ERROR unexpected \| */ | /* ERROR unexpected string */ string /* ERROR unexpected \) */ ) +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue56022.go b/src/cmd/compile/internal/syntax/testdata/issue56022.go new file mode 100644 index 0000000..d28d35c --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue56022.go @@ -0,0 +1,10 @@ +// Copyright 2022 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 unexpected {, expected name or \($ */ {} +func (T) /* ERROR unexpected {, expected name$ */ {} +func (T) /* ERROR unexpected \(, expected name$ */ () {} +func (T) /* ERROR unexpected \(, expected name$ */ () diff --git a/src/cmd/compile/internal/syntax/testdata/issue60599.go b/src/cmd/compile/internal/syntax/testdata/issue60599.go new file mode 100644 index 0000000..711d97b --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue60599.go @@ -0,0 +1,11 @@ +// Copyright 2023 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 _(x, y, z int) { + if x /* ERROR cannot use assignment x = y as value */ = y {} + if x || y /* ERROR cannot use assignment \(x || y\) = z as value */ = z {} + if x /* ERROR cannot use assignment x = \(y || z\) as value */ = y || z {} +} diff --git a/src/cmd/compile/internal/syntax/testdata/issue63835.go b/src/cmd/compile/internal/syntax/testdata/issue63835.go new file mode 100644 index 0000000..3d165c0 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/issue63835.go @@ -0,0 +1,9 @@ +// Copyright 2023 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 (x string) /* ERROR syntax error: unexpected \[, expected name */ []byte { + return []byte(x) +} diff --git a/src/cmd/compile/internal/syntax/testdata/linalg.go b/src/cmd/compile/internal/syntax/testdata/linalg.go new file mode 100644 index 0000000..822d028 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/linalg.go @@ -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/map.go b/src/cmd/compile/internal/syntax/testdata/map.go new file mode 100644 index 0000000..a508d21 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/map.go @@ -0,0 +1,112 @@ +// 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 + +import "chans" + +// 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/map2.go b/src/cmd/compile/internal/syntax/testdata/map2.go new file mode 100644 index 0000000..3d1cbfb --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/map2.go @@ -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.go, but instead of 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 +} diff --git a/src/cmd/compile/internal/syntax/testdata/sample.go b/src/cmd/compile/internal/syntax/testdata/sample.go new file mode 100644 index 0000000..5a2b4bf --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/sample.go @@ -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/slices.go b/src/cmd/compile/internal/syntax/testdata/slices.go new file mode 100644 index 0000000..9265109 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/slices.go @@ -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, 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/smoketest.go b/src/cmd/compile/internal/syntax/testdata/smoketest.go new file mode 100644 index 0000000..6b3593a --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/smoketest.go @@ -0,0 +1,73 @@ +// 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]]() + +// 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() + + // instantiated types + T[ /* ERROR empty type argument list */ ] + T[P] + T[P1, P2] +} diff --git a/src/cmd/compile/internal/syntax/testdata/tparams.go b/src/cmd/compile/internal/syntax/testdata/tparams.go new file mode 100644 index 0000000..4b68a15 --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/tparams.go @@ -0,0 +1,57 @@ +// 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 expected ] */ 0] () + +// go.dev/issue/49482 +type ( + t[a *[]int] struct{} + t[a *t,] struct{} + t[a *t|[]int] struct{} + t[a *t|t,] struct{} + t[a *t|~t,] struct{} + t[a *struct{}|t] struct{} + t[a *t|struct{}] struct{} + t[a *struct{}|~t] struct{} +) + +// go.dev/issue/51488 +type ( + t[a *t|t,] struct{} + t[a *t|t, b t] struct{} + t[a *t|t] struct{} + t[a *[]t|t] struct{} + t[a ([]t)] struct{} + t[a ([]t)|t] struct{} +) + +// go.dev/issue/60812 +type ( + t [t]struct{} + t [[]t]struct{} + t [[t]t]struct{} + t [/* ERROR missing type parameter name or invalid array length */ t[t]]struct{} + t [t t[t], /* ERROR missing type parameter name */ t[t]]struct{} + t [/* ERROR missing type parameter name */ t[t], t t[t]]struct{} + t [/* ERROR missing type parameter name */ t[t], t[t]]struct{} // report only first error +) diff --git a/src/cmd/compile/internal/syntax/testdata/typeset.go b/src/cmd/compile/internal/syntax/testdata/typeset.go new file mode 100644 index 0000000..819025c --- /dev/null +++ b/src/cmd/compile/internal/syntax/testdata/typeset.go @@ -0,0 +1,91 @@ +// 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 go.dev/issue/49175 + _[_ []t]t + _[_ [1]t]t + _[_ ~[]t]t + _[_ ~[1]t]t + t [ /* ERROR missing type parameter name */ t[0]]t +) + +// test cases for go.dev/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 incl. a +// tilde term) but the type-checker will complain. +type ( + _[t] t + _[t|t] t + + // These are invalid and the type-checker will complain. + _[~t] t + _[~t|t] t + _[t|~t] t + _[~t|~t] t +) + +type ( + _[_ t, t /* ERROR missing type constraint */ ] t + _[_ ~t, t /* ERROR missing type constraint */ ] t + _[_ t, /* ERROR missing type parameter name */ ~t] t + _[_ ~t, /* ERROR missing type parameter name */ ~t] t + + _[_ t|t, /* ERROR missing type parameter name */ t|t] t + _[_ ~t|t, /* ERROR missing type parameter name */ t|t] t + _[_ t|t, /* ERROR missing type parameter name */ ~t|t] t + _[_ ~t|t, /* ERROR missing type parameter name */ ~t|t] t +) |