// The elements are copied using assignment, so this is a shallow clone.
// The result may have additional unused capacity.
func Clone[S ~[]E, E any](s S) S {
- // The s[:0:0] preserves nil in case it matters.
- return append(s[:0:0], s...)
+ // Preserve nilness in case it matters.
+ if s == nil {
+ return nil
+ }
+ // Avoid s[:0:0] as it leads to unwanted liveness when cloning a
+ // zero-length slice of a large array; see https://go.dev/issue/68488.
+ return append(S{}, s...)
}
// Compact replaces consecutive runs of equal elements with a single copy.
. "slices"
"strings"
"testing"
+ "unsafe"
)
var equalIntTests = []struct {
}
}
}
+
+func TestIssue68488(t *testing.T) {
+ s := make([]int, 3)
+ clone := Clone(s[1:1])
+ switch unsafe.SliceData(clone) {
+ case &s[0], &s[1], &s[2]:
+ t.Error("clone keeps alive s due to array overlap")
+ }
+}