diff --git a/src/cmd/go2go/testdata/go2path/src/alg/alg.go2 b/src/cmd/go2go/testdata/go2path/src/alg/alg.go2 index 52020bf16b..c2e48bfff7 100644 --- a/src/cmd/go2go/testdata/go2path/src/alg/alg.go2 +++ b/src/cmd/go2go/testdata/go2path/src/alg/alg.go2 @@ -8,7 +8,7 @@ package alg import "constraints" // Max returns the maximum of two values of some ordered type. -func Max[type T constraints.Ordered](a, b T) T { +func Max[T constraints.Ordered](a, b T) T { if a < b { return b } @@ -16,7 +16,7 @@ func Max[type T constraints.Ordered](a, b T) T { } // Min returns the minimum of two values of some ordered type. -func Min[type T constraints.Ordered](a, b T) T { +func Min[T constraints.Ordered](a, b T) T { if a < b { return a } diff --git a/src/cmd/go2go/testdata/go2path/src/chans/chans.go2 b/src/cmd/go2go/testdata/go2path/src/chans/chans.go2 index d7f36bca5c..c5369ab83c 100644 --- a/src/cmd/go2go/testdata/go2path/src/chans/chans.go2 +++ b/src/cmd/go2go/testdata/go2path/src/chans/chans.go2 @@ -12,7 +12,7 @@ import ( // ReadAll reads from c until the channel is closed or the context is // canceled, returning all the values read. -func ReadAll[type Elem](ctx context.Context, c <-chan Elem) []Elem { +func ReadAll[Elem any](ctx context.Context, c <-chan Elem) []Elem { var r []Elem for { select { @@ -30,7 +30,7 @@ func ReadAll[type Elem](ctx context.Context, c <-chan Elem) []Elem { // Merge merges two channels into a single channel. // This will leave a goroutine running until either both channels are closed // or the context is canceled, at which point the returned channel is closed. -func Merge[type Elem](ctx context.Context, c1, c2 <-chan Elem) <-chan Elem { +func Merge[Elem any](ctx context.Context, c1, c2 <-chan Elem) <-chan Elem { r := make(chan Elem) go func(ctx context.Context, c1, c2 <-chan Elem, r chan<- Elem) { defer close(r) @@ -60,7 +60,7 @@ func Merge[type Elem](ctx context.Context, c1, c2 <-chan Elem) <-chan Elem { // is sent on the returned channel. This will leave a goroutine running // until c is closed or the context is canceled, at which point the // returned channel is closed. -func Filter[type Elem](ctx context.Context, c <-chan Elem, f func(Elem) bool) <-chan Elem { +func Filter[Elem any](ctx context.Context, c <-chan Elem, f func(Elem) bool) <-chan Elem { r := make(chan Elem) go func(ctx context.Context, c <-chan Elem, f func(Elem) bool, r chan<- Elem) { defer close(r) @@ -84,7 +84,7 @@ func Filter[type Elem](ctx context.Context, c <-chan Elem, f func(Elem) bool) <- // Sink returns a channel that discards all values sent to it. // This will leave a goroutine running until the context is canceled // or the returned channel is closed. -func Sink[type Elem](ctx context.Context) chan<- Elem { +func Sink[Elem any](ctx context.Context) chan<- Elem { r := make(chan Elem) go func(ctx context.Context, r <-chan Elem) { for { @@ -103,12 +103,12 @@ func Sink[type Elem](ctx context.Context) chan<- Elem { // An Exclusive is a value that may only be used by a single goroutine // at a time. This is implemented using channels rather than a mutex. -type Exclusive[type Val] struct { +type Exclusive[Val any] struct { c chan Val } // MakeExclusive makes an initialized exclusive value. -func MakeExclusive[type Val](initial Val) *Exclusive[Val] { +func MakeExclusive[Val any](initial Val) *Exclusive[Val] { r := &Exclusive[Val]{ c: make(chan Val, 1), } @@ -152,7 +152,7 @@ func (e *Exclusive[Val]) Release(v Val) { // // This is a convenient way to exit a goroutine sending values when // the receiver stops reading them. -func Ranger[type Elem]() (*Sender[Elem], *Receiver[Elem]) { +func Ranger[Elem any]() (*Sender[Elem], *Receiver[Elem]) { c := make(chan Elem) d := make(chan struct{}) s := &Sender[Elem]{ @@ -168,7 +168,7 @@ func Ranger[type Elem]() (*Sender[Elem], *Receiver[Elem]) { } // A Sender is used to send values to a Receiver. -type Sender[type Elem] struct { +type Sender[Elem any] struct { values chan<- Elem done <-chan struct{} } @@ -194,7 +194,7 @@ func (s *Sender[Elem]) Close() { } // A Receiver receives values from a Sender. -type Receiver[type Elem] struct { +type Receiver[Elem any] struct { values <-chan Elem done chan<- struct{} } diff --git a/src/cmd/go2go/testdata/go2path/src/graph/graph.go2 b/src/cmd/go2go/testdata/go2path/src/graph/graph.go2 index 90c6683308..edddbeb3bb 100644 --- a/src/cmd/go2go/testdata/go2path/src/graph/graph.go2 +++ b/src/cmd/go2go/testdata/go2path/src/graph/graph.go2 @@ -10,31 +10,31 @@ import "errors" // A Graph is a collection of nodes. A node may have an arbitrary number // of edges. An edge connects two nodes. Both nodes and edges must be // comparable. This is an undirected simple graph. -type Graph[type Node NodeC[Edge], Edge EdgeC[Node]] struct { +type Graph[Node NodeC[Edge], Edge EdgeC[Node]] struct { nodes []Node } // NodeC is the contraints on a node in a graph, given the Edge type. -type NodeC[type Edge] interface { +type NodeC[Edge any] interface { comparable Edges() []Edge } // Edgec is the constraints on an edge in a graph, given the Node type. -type EdgeC[type Node] interface { +type EdgeC[Node any] interface { comparable Nodes() (a, b Node) } // New creates a new Graph from a collection of Nodes. -func New[type Node NodeC[Edge], Edge EdgeC[Node]](nodes []Node) *Graph[Node, Edge] { +func New[Node NodeC[Edge], Edge EdgeC[Node]](nodes []Node) *Graph[Node, Edge] { return &Graph[Node, Edge]{nodes: nodes} } // nodePath holds the path to a node during ShortestPath. // This should ideally be a type defined inside ShortestPath, // but the translator tool doesn't support that. -type nodePath[type Node NodeC[Edge], Edge EdgeC[Node]] struct { +type nodePath[Node NodeC[Edge], Edge EdgeC[Node]] struct { node Node path []Edge } @@ -79,12 +79,12 @@ type GraphP[type *Node NodeCP[Edge], *Edge EdgeCP[Node]] struct { } // NodeCP is the contraint on a Node in a GraphP. -type NodeCP[type Edge] interface { +type NodeCP[Edge any] interface { Edges() []*Edge } // EdgeCP is the contraint on an Edge in a GraphP. -type EdgeCP[type Node] interface { +type EdgeCP[Node any] interface { Nodes() (a, b *Node) } diff --git a/src/cmd/go2go/testdata/go2path/src/gsort/gsort.go2 b/src/cmd/go2go/testdata/go2path/src/gsort/gsort.go2 index 2c54e9d1d8..5d4301a7e8 100644 --- a/src/cmd/go2go/testdata/go2path/src/gsort/gsort.go2 +++ b/src/cmd/go2go/testdata/go2path/src/gsort/gsort.go2 @@ -12,7 +12,7 @@ import ( ) // orderedSlice is a slice of values of some ordered type. -type orderedSlice[type Elem constraints.Ordered] []Elem +type orderedSlice[Elem constraints.Ordered] []Elem // orderedSlice implements sort.Interface. @@ -30,13 +30,13 @@ func (s orderedSlice[Elem]) Less(i, j int) bool { func (s orderedSlice[Elem]) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // OrderedSlice sorts a slice of any ordered type in ascending order. -func OrderedSlice[type Elem constraints.Ordered](s []Elem) { +func OrderedSlice[Elem constraints.Ordered](s []Elem) { sort.Sort(orderedSlice[Elem](s)) } // sliceFn implements sort.Interface for a slice of any type with an // explicit less-than function. -type sliceFn[type Elem] struct { +type sliceFn[Elem any] struct { s []Elem less func(Elem, Elem) bool } @@ -46,6 +46,6 @@ func (s sliceFn[Elem]) Less(i, j int) bool { return s.less(s.s[i], s.s[j]) } func (s sliceFn[Elem]) Swap(i, j int) { s.s[i], s.s[j] = s.s[j], s.s[i] } // SliceFn sorts a slice of any type according to a less-than function. -func SliceFn[type Elem](s []Elem, less func(Elem, Elem) bool) { +func SliceFn[Elem any](s []Elem, less func(Elem, Elem) bool) { sort.Sort(sliceFn[Elem]{s, less}) } diff --git a/src/cmd/go2go/testdata/go2path/src/gsort/gsort_test.go2 b/src/cmd/go2go/testdata/go2path/src/gsort/gsort_test.go2 index eb69893f1f..a7bb15742f 100644 --- a/src/cmd/go2go/testdata/go2path/src/gsort/gsort_test.go2 +++ b/src/cmd/go2go/testdata/go2path/src/gsort/gsort_test.go2 @@ -31,7 +31,7 @@ func TestSortOrderedStrings(t *testing.T) { testOrdered(t, strs, sort.Strings) } -func testOrdered[type Elem constraints.Ordered](t *testing.T, s []Elem, sorter func([]Elem)) { +func testOrdered[Elem constraints.Ordered](t *testing.T, s []Elem, sorter func([]Elem)) { s1 := make([]Elem, len(s)) copy(s1, s) s2 := make([]Elem, len(s)) diff --git a/src/cmd/go2go/testdata/go2path/src/list/list.go2 b/src/cmd/go2go/testdata/go2path/src/list/list.go2 index aa466a2792..2740fd4072 100644 --- a/src/cmd/go2go/testdata/go2path/src/list/list.go2 +++ b/src/cmd/go2go/testdata/go2path/src/list/list.go2 @@ -9,7 +9,7 @@ package list // perhaps with different type names. // Element is an element of a linked list. -type Element[type TElem] struct { +type Element[TElem any] struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last @@ -42,7 +42,7 @@ func (e *Element[TElem]) Prev() *Element[TElem] { // List represents a doubly linked list. // The zero value for List is an empty list ready to use. -type List[type TElem] struct { +type List[TElem any] struct { root Element[TElem] // sentinel list element, only &root, root.prev, and root.next are used len int // current list length excluding (this) sentinel element } @@ -56,7 +56,7 @@ func (l *List[TElem]) Init() *List[TElem] { } // New returns an initialized list. -func New[type TElem]() *List[TElem] { return new(List[TElem]).Init() } +func New[TElem any]() *List[TElem] { return new(List[TElem]).Init() } // Len returns the number of elements of list l. // The complexity is O(1). @@ -235,7 +235,7 @@ func (l *List[TElem]) PushFrontList(other *List[TElem]) { } // Transform runs a transform function on a list returning a new list. -func Transform[type TElem1, TElem2](lst *List[TElem1], f func(TElem1) TElem2) *List[TElem2] { +func Transform[TElem1, TElem2 any](lst *List[TElem1], f func(TElem1) TElem2) *List[TElem2] { ret := New[TElem2]() for p := lst.Front(); p != nil; p = p.Next() { ret.PushBack(f(p.Value)) diff --git a/src/cmd/go2go/testdata/go2path/src/list/list_test.go2 b/src/cmd/go2go/testdata/go2path/src/list/list_test.go2 index 4f91736a1b..0671c76848 100644 --- a/src/cmd/go2go/testdata/go2path/src/list/list_test.go2 +++ b/src/cmd/go2go/testdata/go2path/src/list/list_test.go2 @@ -9,7 +9,7 @@ import ( "testing" ) -func checkListLen[type TElem](t *testing.T, l *List[TElem], len int) bool { +func checkListLen[TElem any](t *testing.T, l *List[TElem], len int) bool { if n := l.Len(); n != len { t.Errorf("l.Len() = %d, want %d", n, len) return false @@ -17,7 +17,7 @@ func checkListLen[type TElem](t *testing.T, l *List[TElem], len int) bool { return true } -func checkListPointers[type TElem](t *testing.T, l *List[TElem], es []*Element[TElem]) { +func checkListPointers[TElem any](t *testing.T, l *List[TElem], es []*Element[TElem]) { root := &l.root if !checkListLen(t, l, len(es)) { @@ -143,7 +143,7 @@ func TestList(t *testing.T) { checkListPointers(t, l2, []*(Element[int]){}) } -func checkList[type TElem comparable](t *testing.T, l *List[TElem], es []interface{}) { +func checkList[TElem comparable](t *testing.T, l *List[TElem], es []interface{}) { if !checkListLen(t, l, len(es)) { return } diff --git a/src/cmd/go2go/testdata/go2path/src/maps/maps.go2 b/src/cmd/go2go/testdata/go2path/src/maps/maps.go2 index ac0b968c48..77e98988bb 100644 --- a/src/cmd/go2go/testdata/go2path/src/maps/maps.go2 +++ b/src/cmd/go2go/testdata/go2path/src/maps/maps.go2 @@ -5,12 +5,9 @@ // Package maps implements simple functions to manipulate maps in various ways. package maps -// any is a convenient type bound. -type any interface{} - // Keys returns the keys of the map m. // The keys will be an indeterminate order. -func Keys[type K comparable, V any](m map[K]V) []K { +func Keys[K comparable, V any](m map[K]V) []K { r := make([]K, 0, len(m)) for k := range m { r = append(r, k) @@ -20,7 +17,7 @@ func Keys[type K comparable, V any](m map[K]V) []K { // Values returns the values of the map m. // The values will be in an indeterminate order. -func Values[type K comparable, V any](m map[K]V) []V { +func Values[K comparable, V any](m map[K]V) []V { r := make([]V, 0, len(m)) for _, v := range m { r = append(r, v) @@ -30,7 +27,7 @@ func Values[type K comparable, V any](m map[K]V) []V { // Equal reports whether two maps contain the same key/value pairs. // Values are compared using ==. -func Equal[type K, V comparable](m1, m2 map[K]V) bool { +func Equal[K, V comparable](m1, m2 map[K]V) bool { if len(m1) != len(m2) { return false } @@ -43,7 +40,7 @@ func Equal[type K, V comparable](m1, m2 map[K]V) bool { } // Copy returns a copy of m. -func Copy[type K comparable, V any](m map[K]V) map[K]V { +func Copy[K comparable, V any](m map[K]V) map[K]V { r := make(map[K]V, len(m)) for k, v := range m { r[k] = v @@ -53,7 +50,7 @@ func Copy[type K comparable, V any](m map[K]V) map[K]V { // Add adds all key/value pairs in m2 to m1. Keys in m2 that are already // present in m1 will be overwritten with the value in m2. -func Add[type K comparable, V any](m1, m2 map[K]V) { +func Add[K comparable, V any](m1, m2 map[K]V) { for k, v := range m2 { m1[k] = v } @@ -61,7 +58,7 @@ func Add[type K comparable, V any](m1, m2 map[K]V) { // Sub removes all keys in m2 from m1. Keys in m2 that are not present // in m1 are ignored. The values in m2 are ignored. -func Sub[type K comparable, V any](m1, m2 map[K]V) { +func Sub[K comparable, V any](m1, m2 map[K]V) { for k := range m2 { delete(m1, k) } @@ -69,7 +66,7 @@ func Sub[type K comparable, V any](m1, m2 map[K]V) { // Intersect removes all keys from m1 that are not present in m2. // Keys in m2 that are not in m1 are ignored. The values in m2 are ignored. -func Intersect[type K comparable, V any](m1, m2 map[K]V) { +func Intersect[K comparable, V any](m1, m2 map[K]V) { for k := range m1 { if _, ok := m2[k]; !ok { delete(m1, k) @@ -78,7 +75,7 @@ func Intersect[type K comparable, V any](m1, m2 map[K]V) { } // Filter deletes any key/value pairs from m for which f returns false. -func Filter[type K comparable, V any](m map[K]V, f func(K, V) bool) { +func Filter[K comparable, V any](m map[K]V, f func(K, V) bool) { for k, v := range m { if !f(k, v) { delete(m, k) @@ -87,7 +84,7 @@ func Filter[type K comparable, V any](m map[K]V, f func(K, V) bool) { } // TransformValues applies f to each value in m. The keys remain unchanged. -func TransformValues[type K comparable, V any](m map[K]V, f func(V) V) { +func TransformValues[K comparable, V any](m map[K]V, f func(V) V) { for k, v := range m { m[k] = f(v) } diff --git a/src/cmd/go2go/testdata/go2path/src/metrics/metrics.go2 b/src/cmd/go2go/testdata/go2path/src/metrics/metrics.go2 index 5e470314bf..0467fd6f55 100644 --- a/src/cmd/go2go/testdata/go2path/src/metrics/metrics.go2 +++ b/src/cmd/go2go/testdata/go2path/src/metrics/metrics.go2 @@ -13,7 +13,7 @@ import ( ) // Metric1 tracks metrics of values of some type. -type Metric1[type T comparable] struct { +type Metric1[T comparable] struct { mu sync.Mutex m map[T]int } @@ -40,13 +40,13 @@ func (m *Metric1[T]) Metrics() []T { return maps.Keys(m.m) } -type key2[type T1, T2 comparable] struct { +type key2[T1, T2 comparable] struct { f1 T1 f2 T2 } // Metric2 tracks metrics of pairs of values. -type Metric2[type T1, T2 comparable] struct { +type Metric2[T1, T2 comparable] struct { mu sync.Mutex m map[key2[T1, T2]]int } @@ -77,14 +77,14 @@ func (m *Metric2[T1, T2]) Metrics() (r1 []T1, r2 []T2) { return r1, r2 } -type key3[type T1, T2, T3 comparable] struct { +type key3[T1, T2, T3 comparable] struct { f1 T1 f2 T2 f3 T3 } // Metric3 tracks metrics of triplets of values. -type Metric3[type T1, T2, T3 comparable] struct { +type Metric3[T1, T2, T3 comparable] struct { mu sync.Mutex m map[key3[T1, T2, T3]]int } diff --git a/src/cmd/go2go/testdata/go2path/src/orderedmap/orderedmap.go2 b/src/cmd/go2go/testdata/go2path/src/orderedmap/orderedmap.go2 index c216d159b5..ad048546c1 100644 --- a/src/cmd/go2go/testdata/go2path/src/orderedmap/orderedmap.go2 +++ b/src/cmd/go2go/testdata/go2path/src/orderedmap/orderedmap.go2 @@ -15,13 +15,13 @@ import ( ) // Map is an ordered map. -type Map[type K, V] struct { +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[type K, V] struct { +type node[K, V any] struct { key K val V left, right *node[K, V] @@ -30,14 +30,14 @@ type node[type K, V] struct { // New returns a new map. It takes a comparison function that compares two // keys and returns < 0 if the first is less, == 0 if they are equal, // > 0 if the first is greater. -func New[type K, V](compare func(K, K) int) *Map[K, V] { +func New[K, V any](compare func(K, K) int) *Map[K, V] { return &Map[K, V]{compare: compare} } // NewOrdered returns a new map whose key is an ordered type. // This is like New, but does not require providing a compare function. // The map compare function uses the obvious key ordering. -func NewOrdered[type K constraints.Ordered, V interface{}]() *Map[K, V] { +func NewOrdered[K constraints.Ordered, V any]() *Map[K, V] { return New[K, V](func(k1, k2 K) int { switch { case k1 < k2: @@ -92,7 +92,7 @@ func (m *Map[K, V]) Find(key K) (V, bool) { } // keyValue is a pair of key and value used while iterating. -type keyValue[type K, V] struct { +type keyValue[K, V any] struct { key K val V } @@ -119,7 +119,7 @@ func (m *Map[K, V]) Iterate() *Iterator[K, V] { } // Iterator is used to iterate over the map. -type Iterator[type K, V] struct { +type Iterator[K, V any] struct { r *chans.Receiver[keyValue[K, V]] } diff --git a/src/cmd/go2go/testdata/go2path/src/sets/sets.go2 b/src/cmd/go2go/testdata/go2path/src/sets/sets.go2 index 05dc6d1ea4..539a98c960 100644 --- a/src/cmd/go2go/testdata/go2path/src/sets/sets.go2 +++ b/src/cmd/go2go/testdata/go2path/src/sets/sets.go2 @@ -6,12 +6,12 @@ package sets // A Set is a set of elements of some type. -type Set[type Elem comparable] struct { +type Set[Elem comparable] struct { m map[Elem]struct{} } // Make makes a new set. -func Make[type Elem comparable]() Set[Elem] { +func Make[Elem comparable]() Set[Elem] { return Set[Elem]{m: make(map[Elem]struct{})} } @@ -48,7 +48,7 @@ func (s Set[Elem]) Values() []Elem { } // Equal reports whether two sets contain the same elements. -func Equal[type Elem comparable](s1, s2 Set[Elem]) bool { +func Equal[Elem comparable](s1, s2 Set[Elem]) bool { if len(s1.m) != len(s2.m) { return false } diff --git a/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 b/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 index 123a822a88..990ad43f63 100644 --- a/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 +++ b/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 @@ -13,7 +13,7 @@ import ( // Equal reports whether two slices are equal: the same length and all // elements equal. All floating point NaNs are considered equal. -func Equal[type Elem comparable](s1, s2 []Elem) bool { +func Equal[Elem comparable](s1, s2 []Elem) bool { if len(s1) != len(s2) { return false } @@ -31,7 +31,7 @@ func Equal[type Elem comparable](s1, s2 []Elem) bool { // EqualFn reports whether two slices are equal using a comparision // function on each element. -func EqualFn[type Elem](s1, s2 []Elem, eq func(Elem, Elem) bool) bool { +func EqualFn[Elem any](s1, s2 []Elem, eq func(Elem, Elem) bool) bool { if len(s1) != len(s2) { return false } @@ -45,7 +45,7 @@ func EqualFn[type Elem](s1, s2 []Elem, eq func(Elem, Elem) bool) bool { } // Map turns a []Elem1 to a []Elem2 using a mapping function. -func Map[type Elem1, Elem2](s []Elem1, f func(Elem1) Elem2) []Elem2 { +func Map[Elem1, Elem2 any](s []Elem1, f func(Elem1) Elem2) []Elem2 { r := make([]Elem2, len(s)) for i, v := range s { r[i] = f(v) @@ -55,7 +55,7 @@ func Map[type Elem1, Elem2](s []Elem1, f func(Elem1) Elem2) []Elem2 { // Reduce reduces a []Elem1 to a single value of type Elem2 using // a reduction function. -func Reduce[type Elem1, Elem2](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { +func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { r := initializer for _, v := range s { r = f(r, v) @@ -64,7 +64,7 @@ func Reduce[type Elem1, Elem2](s []Elem1, initializer Elem2, f func(Elem2, Elem1 } // Filter filters values from a slice using a filter function. -func Filter[type Elem](s []Elem, f func(Elem) bool) []Elem { +func Filter[Elem any](s []Elem, f func(Elem) bool) []Elem { var r []Elem for _, v := range s { if f(v) { @@ -76,7 +76,7 @@ func Filter[type Elem](s []Elem, f func(Elem) bool) []Elem { // Max returns the maximum element in a slice of some ordered type. // If the slice is empty it returns the zero value of the element type. -func Max[type Elem constraints.Ordered](s []Elem) Elem { +func Max[Elem constraints.Ordered](s []Elem) Elem { if len(s) == 0 { var zero Elem return zero @@ -86,7 +86,7 @@ func Max[type Elem constraints.Ordered](s []Elem) Elem { // Min returns the minimum element in a slice of some ordered type. // If the slice is empty it returns the zero value of the element type. -func Min[type Elem constraints.Ordered](s []Elem) Elem { +func Min[Elem constraints.Ordered](s []Elem) Elem { if len(s) == 0 { var zero Elem return zero @@ -99,7 +99,7 @@ func Min[type Elem constraints.Ordered](s []Elem) Elem { // of how to write it using generics. We used to write code like // this before append was added to the language, but we had to write // a separate copy for each type. -func Append[type T](s []T, t ...T) []T { +func Append[T any](s []T, t ...T) []T { lens := len(s) tot := lens + len(t) if tot <= cap(s) { @@ -116,7 +116,7 @@ func Append[type T](s []T, t ...T) []T { // Copy copies values from t to s, stopping when either slice is full, // returning the number of values copied. This is like the predeclared // copy function; it's an example of how to write it using generics. -func Copy[type T](s, t []T) int { +func Copy[T any](s, t []T) int { i := 0 for ; i < len(s) && i < len(t); i++ { s[i] = t[i] diff --git a/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 b/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 index 3ee2bfc411..c90474a8b2 100644 --- a/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 +++ b/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 @@ -42,7 +42,7 @@ func TestEqual(t *testing.T) { } } -func offByOne[type Elem constraints.Integer](a, b Elem) bool { +func offByOne[Elem constraints.Integer](a, b Elem) bool { return a == b + 1 || a == b - 1 }