blob: 86a8211e54eef19fb0031eedcdd2188ce067b8a1 [file]
// Copyright 2026 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 test
import (
"internal/testenv"
"os"
"path/filepath"
"testing"
)
// TestBinarySearchFuncInlinable checks that BinarySearchFunc stays within the
// inliner's budget. Inlining it is what lets the calls to cmp be made directly
// instead of through the func value, which is worth considerably more than the
// code it costs: while BinarySearchFunc was over budget, searching with a
// comparison function was substantially slower than the equivalent
// sort.Search.
//
// The check cannot be made by compiling package slices itself, since the body
// of a generic function is only checked for inlinability once instantiated, so
// instantiate it in a package of our own and compile that.
func TestBinarySearchFuncInlinable(t *testing.T) {
testenv.MustHaveGoBuild(t)
t.Parallel()
dir := t.TempDir()
src := filepath.Join(dir, "x.go")
const prog = `package x
import "slices"
var _ = slices.BinarySearchFunc[[]string, string, string]
`
if err := os.WriteFile(src, []byte(prog), 0o644); err != nil {
t.Fatal(err)
}
cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-gcflags=-m", src)
cmd.Dir = dir
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%v: %v\n%s", cmd, err, out)
}
inlCands := collectInlCands(string(out))
want := "slices.BinarySearchFunc[go.shape.[]string,go.shape.string,go.shape.string]"
if _, ok := inlCands[want]; !ok {
t.Errorf("BinarySearchFunc is no longer inlinable: %q not found in compiler output:\n%s", want, out)
}
}