Skip to content

Commit dead583

Browse files
adonovangopherbot
authored andcommitted
maps,slices: add //go:fix inline annotations for std namesakes
The tooling will not yet offer to inline calls to these functions because it doesn't handle generics (golang/go#68236), but it will soon. Updates golang/go#32816 Change-Id: Ic19940efddab6267ca92f670ddc2f8029bc93402 Reviewed-on: https://go-review.googlesource.com/c/exp/+/653436 Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 17a8cdc commit dead583

File tree

4 files changed

+83
-21
lines changed

4 files changed

+83
-21
lines changed

constraints/constraints.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// with type parameters.
77
package constraints
88

9+
import "cmp"
10+
911
// Signed is a constraint that permits any signed integer type.
1012
// If future releases of Go add new predeclared signed integer types,
1113
// this constraint will be modified to include them.
@@ -47,6 +49,6 @@ type Complex interface {
4749
// this constraint will be modified to include them.
4850
//
4951
// This type is redundant since Go 1.21 introduced [cmp.Ordered].
50-
type Ordered interface {
51-
Integer | Float | ~string
52-
}
52+
//
53+
//go:fix inline
54+
type Ordered = cmp.Ordered

maps/maps.go

+20-10
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ package maps
77

88
import "maps"
99

10-
// TODO(adonovan): when https://go.dev/issue/32816 is accepted, all of
11-
// these functions except Keys and Values should be annotated
12-
// (provisionally with "//go:fix inline") so that tools can safely and
13-
// automatically replace calls to exp/maps with calls to std maps by
14-
// inlining them.
15-
1610
// Keys returns the keys of the map m.
1711
// The keys will be in an indeterminate order.
12+
//
13+
// The simplest true equivalent using the standard library is:
14+
//
15+
// slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m))
1816
func Keys[M ~map[K]V, K comparable, V any](m M) []K {
19-
// The simplest true equivalent using std is:
20-
// return slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m)).
2117

2218
r := make([]K, 0, len(m))
2319
for k := range m {
@@ -28,9 +24,11 @@ func Keys[M ~map[K]V, K comparable, V any](m M) []K {
2824

2925
// Values returns the values of the map m.
3026
// The values will be in an indeterminate order.
27+
//
28+
// The simplest true equivalent using the standard library is:
29+
//
30+
// slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m))
3131
func Values[M ~map[K]V, K comparable, V any](m M) []V {
32-
// The simplest true equivalent using std is:
33-
// return slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m)).
3432

3533
r := make([]V, 0, len(m))
3634
for _, v := range m {
@@ -41,23 +39,31 @@ func Values[M ~map[K]V, K comparable, V any](m M) []V {
4139

4240
// Equal reports whether two maps contain the same key/value pairs.
4341
// Values are compared using ==.
42+
//
43+
//go:fix inline
4444
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
4545
return maps.Equal(m1, m2)
4646
}
4747

4848
// EqualFunc is like Equal, but compares values using eq.
4949
// Keys are still compared with ==.
50+
//
51+
//go:fix inline
5052
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
5153
return maps.EqualFunc(m1, m2, eq)
5254
}
5355

5456
// Clear removes all entries from m, leaving it empty.
57+
//
58+
//go:fix inline
5559
func Clear[M ~map[K]V, K comparable, V any](m M) {
5660
clear(m)
5761
}
5862

5963
// Clone returns a copy of m. This is a shallow clone:
6064
// the new keys and values are set using ordinary assignment.
65+
//
66+
//go:fix inline
6167
func Clone[M ~map[K]V, K comparable, V any](m M) M {
6268
return maps.Clone(m)
6369
}
@@ -66,11 +72,15 @@ func Clone[M ~map[K]V, K comparable, V any](m M) M {
6672
// When a key in src is already present in dst,
6773
// the value in dst will be overwritten by the value associated
6874
// with the key in src.
75+
//
76+
//go:fix inline
6977
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
7078
maps.Copy(dst, src)
7179
}
7280

7381
// DeleteFunc deletes any key/value pairs from m for which del returns true.
82+
//
83+
//go:fix inline
7484
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
7585
maps.DeleteFunc(m, del)
7686
}

slices/slices.go

+36-5
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ import (
1010
"slices"
1111
)
1212

13-
// TODO(adonovan): when https://go.dev/issue/32816 is accepted, all of
14-
// these functions should be annotated (provisionally with "//go:fix
15-
// inline") so that tools can safely and automatically replace calls
16-
// to exp/slices with calls to std slices by inlining them.
17-
1813
// Equal reports whether two slices are equal: the same length and all
1914
// elements equal. If the lengths are different, Equal returns false.
2015
// Otherwise, the elements are compared in increasing index order, and the
2116
// comparison stops at the first unequal pair.
2217
// Floating point NaNs are not considered equal.
18+
//
19+
//go:fix inline
2320
func Equal[S ~[]E, E comparable](s1, s2 S) bool {
2421
return slices.Equal(s1, s2)
2522
}
@@ -29,6 +26,8 @@ func Equal[S ~[]E, E comparable](s1, s2 S) bool {
2926
// EqualFunc returns false. Otherwise, the elements are compared in
3027
// increasing index order, and the comparison stops at the first index
3128
// for which eq returns false.
29+
//
30+
//go:fix inline
3231
func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
3332
return slices.EqualFunc(s1, s2, eq)
3433
}
@@ -40,6 +39,8 @@ func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) boo
4039
// If both slices are equal until one of them ends, the shorter slice is
4140
// considered less than the longer one.
4241
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
42+
//
43+
//go:fix inline
4344
func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int {
4445
return slices.Compare(s1, s2)
4546
}
@@ -49,29 +50,39 @@ func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int {
4950
// The result is the first non-zero result of cmp; if cmp always
5051
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
5152
// and +1 if len(s1) > len(s2).
53+
//
54+
//go:fix inline
5255
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
5356
return slices.CompareFunc(s1, s2, cmp)
5457
}
5558

5659
// Index returns the index of the first occurrence of v in s,
5760
// or -1 if not present.
61+
//
62+
//go:fix inline
5863
func Index[S ~[]E, E comparable](s S, v E) int {
5964
return slices.Index(s, v)
6065
}
6166

6267
// IndexFunc returns the first index i satisfying f(s[i]),
6368
// or -1 if none do.
69+
//
70+
//go:fix inline
6471
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
6572
return slices.IndexFunc(s, f)
6673
}
6774

6875
// Contains reports whether v is present in s.
76+
//
77+
//go:fix inline
6978
func Contains[S ~[]E, E comparable](s S, v E) bool {
7079
return slices.Contains(s, v)
7180
}
7281

7382
// ContainsFunc reports whether at least one
7483
// element e of s satisfies f(e).
84+
//
85+
//go:fix inline
7586
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
7687
return slices.ContainsFunc(s, f)
7788
}
@@ -83,6 +94,8 @@ func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
8394
// and r[i+len(v)] == value originally at r[i].
8495
// Insert panics if i is out of range.
8596
// This function is O(len(s) + len(v)).
97+
//
98+
//go:fix inline
8699
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
87100
return slices.Insert(s, i, v...)
88101
}
@@ -92,26 +105,34 @@ func Insert[S ~[]E, E any](s S, i int, v ...E) S {
92105
// Delete is O(len(s)-i), so if many items must be deleted, it is better to
93106
// make a single call deleting them all together than to delete one at a time.
94107
// Delete zeroes the elements s[len(s)-(j-i):len(s)].
108+
//
109+
//go:fix inline
95110
func Delete[S ~[]E, E any](s S, i, j int) S {
96111
return slices.Delete(s, i, j)
97112
}
98113

99114
// DeleteFunc removes any elements from s for which del returns true,
100115
// returning the modified slice.
101116
// DeleteFunc zeroes the elements between the new length and the original length.
117+
//
118+
//go:fix inline
102119
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
103120
return slices.DeleteFunc(s, del)
104121
}
105122

106123
// Replace replaces the elements s[i:j] by the given v, and returns the
107124
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
108125
// When len(v) < (j-i), Replace zeroes the elements between the new length and the original length.
126+
//
127+
//go:fix inline
109128
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
110129
return slices.Replace(s, i, j, v...)
111130
}
112131

113132
// Clone returns a copy of the slice.
114133
// The elements are copied using assignment, so this is a shallow clone.
134+
//
135+
//go:fix inline
115136
func Clone[S ~[]E, E any](s S) S {
116137
return slices.Clone(s)
117138
}
@@ -121,13 +142,17 @@ func Clone[S ~[]E, E any](s S) S {
121142
// Compact modifies the contents of the slice s and returns the modified slice,
122143
// which may have a smaller length.
123144
// Compact zeroes the elements between the new length and the original length.
145+
//
146+
//go:fix inline
124147
func Compact[S ~[]E, E comparable](s S) S {
125148
return slices.Compact(s)
126149
}
127150

128151
// CompactFunc is like [Compact] but uses an equality function to compare elements.
129152
// For runs of elements that compare equal, CompactFunc keeps the first one.
130153
// CompactFunc zeroes the elements between the new length and the original length.
154+
//
155+
//go:fix inline
131156
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
132157
return slices.CompactFunc(s, eq)
133158
}
@@ -136,16 +161,22 @@ func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
136161
// another n elements. After Grow(n), at least n elements can be appended
137162
// to the slice without another allocation. If n is negative or too large to
138163
// allocate the memory, Grow panics.
164+
//
165+
//go:fix inline
139166
func Grow[S ~[]E, E any](s S, n int) S {
140167
return slices.Grow(s, n)
141168
}
142169

143170
// Clip removes unused capacity from the slice, returning s[:len(s):len(s)].
171+
//
172+
//go:fix inline
144173
func Clip[S ~[]E, E any](s S) S {
145174
return slices.Clip(s)
146175
}
147176

148177
// Reverse reverses the elements of the slice in place.
178+
//
179+
//go:fix inline
149180
func Reverse[S ~[]E, E any](s S) {
150181
slices.Reverse(s)
151182
}

slices/sort.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import (
99
"slices"
1010
)
1111

12-
// TODO(adonovan): add a "//go:fix inline" annotation to each function
13-
// in this file; see https://go.dev/issue/32816.
14-
1512
// Sort sorts a slice of any ordered type in ascending order.
1613
// When sorting floating-point numbers, NaNs are ordered before other values.
14+
//
15+
//go:fix inline
1716
func Sort[S ~[]E, E cmp.Ordered](x S) {
1817
slices.Sort(x)
1918
}
@@ -27,51 +26,67 @@ func Sort[S ~[]E, E cmp.Ordered](x S) {
2726
// SortFunc requires that cmp is a strict weak ordering.
2827
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
2928
// To indicate 'uncomparable', return 0 from the function.
29+
//
30+
//go:fix inline
3031
func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
3132
slices.SortFunc(x, cmp)
3233
}
3334

3435
// SortStableFunc sorts the slice x while keeping the original order of equal
3536
// elements, using cmp to compare elements in the same way as [SortFunc].
37+
//
38+
//go:fix inline
3639
func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
3740
slices.SortStableFunc(x, cmp)
3841
}
3942

4043
// IsSorted reports whether x is sorted in ascending order.
44+
//
45+
//go:fix inline
4146
func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
4247
return slices.IsSorted(x)
4348
}
4449

4550
// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
4651
// comparison function as defined by [SortFunc].
52+
//
53+
//go:fix inline
4754
func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
4855
return slices.IsSortedFunc(x, cmp)
4956
}
5057

5158
// Min returns the minimal value in x. It panics if x is empty.
5259
// For floating-point numbers, Min propagates NaNs (any NaN value in x
5360
// forces the output to be NaN).
61+
//
62+
//go:fix inline
5463
func Min[S ~[]E, E cmp.Ordered](x S) E {
5564
return slices.Min(x)
5665
}
5766

5867
// MinFunc returns the minimal value in x, using cmp to compare elements.
5968
// It panics if x is empty. If there is more than one minimal element
6069
// according to the cmp function, MinFunc returns the first one.
70+
//
71+
//go:fix inline
6172
func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
6273
return slices.MinFunc(x, cmp)
6374
}
6475

6576
// Max returns the maximal value in x. It panics if x is empty.
6677
// For floating-point E, Max propagates NaNs (any NaN value in x
6778
// forces the output to be NaN).
79+
//
80+
//go:fix inline
6881
func Max[S ~[]E, E cmp.Ordered](x S) E {
6982
return slices.Max(x)
7083
}
7184

7285
// MaxFunc returns the maximal value in x, using cmp to compare elements.
7386
// It panics if x is empty. If there is more than one maximal element
7487
// according to the cmp function, MaxFunc returns the first one.
88+
//
89+
//go:fix inline
7590
func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
7691
return slices.MaxFunc(x, cmp)
7792
}
@@ -80,6 +95,8 @@ func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
8095
// where target is found, or the position where target would appear in the
8196
// sort order; it also returns a bool saying whether the target is really found
8297
// in the slice. The slice must be sorted in increasing order.
98+
//
99+
//go:fix inline
83100
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
84101
return slices.BinarySearch(x, target)
85102
}
@@ -91,6 +108,8 @@ func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
91108
// or a positive number if the slice element follows the target.
92109
// cmp must implement the same ordering as the slice, such that if
93110
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
111+
//
112+
//go:fix inline
94113
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
95114
return slices.BinarySearchFunc(x, target, cmp)
96115
}

0 commit comments

Comments
 (0)