go/types: avoid importer.Default

It uses a throwaway FileSet, so all position info is
wrong, and potentially misleading.

(Various other helpers in go/types testing also use a
throwaway FileSet, and should really accept it as a parameter.)

Fixes #71272

Change-Id: I9d899b987837b4041a299aad5ec266cb4f5d125c
Reviewed-on: https://go-review.googlesource.com/c/go/+/643777
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
This commit is contained in:
Alan Donovan 2025-01-22 10:43:44 -05:00 committed by Gopher Robot
parent 9d21ef3bd4
commit 608acff847
10 changed files with 36 additions and 27 deletions

View file

@ -19,11 +19,16 @@ import (
"testing" "testing"
. "go/types" . "go/types"
"runtime"
) )
// nopos indicates an unknown position // nopos indicates an unknown position
var nopos token.Pos var nopos token.Pos
func defaultImporter(fset *token.FileSet) Importer {
return importer.ForCompiler(fset, runtime.Compiler, nil)
}
func mustParse(fset *token.FileSet, src string) *ast.File { func mustParse(fset *token.FileSet, src string) *ast.File {
f, err := parser.ParseFile(fset, pkgName(src), src, parser.ParseComments) f, err := parser.ParseFile(fset, pkgName(src), src, parser.ParseComments)
if err != nil { if err != nil {
@ -33,12 +38,13 @@ func mustParse(fset *token.FileSet, src string) *ast.File {
} }
func typecheck(src string, conf *Config, info *Info) (*Package, error) { func typecheck(src string, conf *Config, info *Info) (*Package, error) {
// TODO(adonovan): plumb this from caller.
fset := token.NewFileSet() fset := token.NewFileSet()
f := mustParse(fset, src) f := mustParse(fset, src)
if conf == nil { if conf == nil {
conf = &Config{ conf = &Config{
Error: func(err error) {}, // collect all errors Error: func(err error) {}, // collect all errors
Importer: importer.Default(), Importer: defaultImporter(fset),
} }
} }
return conf.Check(f.Name.Name, fset, []*ast.File{f}, info) return conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
@ -1128,7 +1134,7 @@ var (
Implicits: make(map[ast.Node]Object), Implicits: make(map[ast.Node]Object),
} }
var conf Config var conf Config
conf.Importer = importer.Default() conf.Importer = defaultImporter(fset)
_, err := conf.Check("p", fset, []*ast.File{f}, &info) _, err := conf.Check("p", fset, []*ast.File{f}, &info)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -34,7 +34,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"go/ast" "go/ast"
"go/importer"
"go/parser" "go/parser"
"go/scanner" "go/scanner"
"go/token" "go/token"
@ -164,7 +163,7 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, manual bool,
// set up typechecker // set up typechecker
var conf Config var conf Config
*boolFieldAddr(&conf, "_Trace") = manual && testing.Verbose() *boolFieldAddr(&conf, "_Trace") = manual && testing.Verbose()
conf.Importer = importer.Default() conf.Importer = defaultImporter(fset)
conf.Error = func(err error) { conf.Error = func(err error) {
if *haltOnError { if *haltOnError {
defer panic(err) defer panic(err)

View file

@ -9,7 +9,6 @@ package types_test
import ( import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/importer"
"go/parser" "go/parser"
"go/token" "go/token"
"go/types" "go/types"
@ -188,7 +187,7 @@ func TestEvalPos(t *testing.T) {
files = append(files, file) files = append(files, file)
} }
conf := Config{Importer: importer.Default()} conf := Config{Importer: defaultImporter(fset)}
pkg, err := conf.Check("p", fset, files, nil) pkg, err := conf.Check("p", fset, files, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -257,7 +256,7 @@ func f(a int, s string) S {
t.Fatal(err) t.Fatal(err)
} }
conf := Config{Importer: importer.Default()} conf := Config{Importer: defaultImporter(fset)}
pkg, err := conf.Check("p", fset, []*ast.File{f}, nil) pkg, err := conf.Check("p", fset, []*ast.File{f}, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -19,7 +19,6 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/format" "go/format"
"go/importer"
"go/parser" "go/parser"
"go/token" "go/token"
"go/types" "go/types"
@ -57,7 +56,7 @@ func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get
// Type-check a package consisting of these files. // Type-check a package consisting of these files.
// Type information for the imported "fmt" package // Type information for the imported "fmt" package
// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a. // comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
conf := types.Config{Importer: importer.Default()} conf := types.Config{Importer: defaultImporter(fset)}
pkg, err := conf.Check("temperature", fset, files, nil) pkg, err := conf.Check("temperature", fset, files, nil)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -126,7 +125,7 @@ type I interface { m() byte }
// Type-check a package consisting of this file. // Type-check a package consisting of this file.
// Type information for the imported packages // Type information for the imported packages
// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a. // comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
conf := types.Config{Importer: importer.Default()} conf := types.Config{Importer: defaultImporter(fset)}
pkg, err := conf.Check("temperature", fset, []*ast.File{f}, nil) pkg, err := conf.Check("temperature", fset, []*ast.File{f}, nil)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View file

@ -9,7 +9,6 @@ package types_test
import ( import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/importer"
"go/parser" "go/parser"
"go/token" "go/token"
"internal/testenv" "internal/testenv"
@ -291,7 +290,7 @@ func TestIssue25627(t *testing.T) {
} { } {
f := mustParse(fset, prefix+src) f := mustParse(fset, prefix+src)
cfg := Config{Importer: importer.Default(), Error: func(err error) {}} cfg := Config{Importer: defaultImporter(fset), Error: func(err error) {}}
info := &Info{Types: make(map[ast.Expr]TypeAndValue)} info := &Info{Types: make(map[ast.Expr]TypeAndValue)}
_, err := cfg.Check(f.Name.Name, fset, []*ast.File{f}, info) _, err := cfg.Check(f.Name.Name, fset, []*ast.File{f}, info)
if err != nil { if err != nil {
@ -595,7 +594,11 @@ var _ T = template /* ERRORx "cannot use.*text/template.* as T value" */.Templat
) )
a := mustTypecheck(asrc, nil, nil) a := mustTypecheck(asrc, nil, nil)
imp := importHelper{pkg: a, fallback: importer.Default()} imp := importHelper{
pkg: a,
// TODO(adonovan): use same FileSet as mustTypecheck.
fallback: defaultImporter(token.NewFileSet()),
}
withImporter := func(cfg *Config) { withImporter := func(cfg *Config) {
cfg.Importer = imp cfg.Importer = imp

View file

@ -5,7 +5,6 @@
package types_test package types_test
import ( import (
"go/importer"
"go/token" "go/token"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -28,7 +27,7 @@ func BenchmarkLookupFieldOrMethod(b *testing.B) {
} }
conf := Config{ conf := Config{
Importer: importer.Default(), Importer: defaultImporter(fset),
} }
pkg, err := conf.Check("http", fset, files, nil) pkg, err := conf.Check("http", fset, files, nil)

View file

@ -7,7 +7,6 @@ package types_test
import ( import (
"errors" "errors"
"fmt" "fmt"
"go/importer"
"go/types" "go/types"
"strings" "strings"
"testing" "testing"
@ -19,7 +18,7 @@ func checkMono(t *testing.T, body string) error {
var buf strings.Builder var buf strings.Builder
conf := types.Config{ conf := types.Config{
Error: func(err error) { fmt.Fprintln(&buf, err) }, Error: func(err error) { fmt.Fprintln(&buf, err) },
Importer: importer.Default(), Importer: defaultImporter(fset), // TODO(adonovan): use same FileSet as typecheck
} }
typecheck(src, &conf, nil) typecheck(src, &conf, nil)
if buf.Len() == 0 { if buf.Len() == 0 {

View file

@ -7,7 +7,6 @@ package types_test
import ( import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/importer"
"go/token" "go/token"
"internal/testenv" "internal/testenv"
"slices" "slices"
@ -17,6 +16,7 @@ import (
) )
type resolveTestImporter struct { type resolveTestImporter struct {
fset *token.FileSet
importer ImporterFrom importer ImporterFrom
imported map[string]bool imported map[string]bool
} }
@ -30,7 +30,7 @@ func (imp *resolveTestImporter) ImportFrom(path, srcDir string, mode ImportMode)
panic("mode must be 0") panic("mode must be 0")
} }
if imp.importer == nil { if imp.importer == nil {
imp.importer = importer.Default().(ImporterFrom) imp.importer = defaultImporter(fset).(ImporterFrom)
imp.imported = make(map[string]bool) imp.imported = make(map[string]bool)
} }
pkg, err := imp.importer.ImportFrom(path, srcDir, mode) pkg, err := imp.importer.ImportFrom(path, srcDir, mode)
@ -124,7 +124,7 @@ func TestResolveIdents(t *testing.T) {
} }
// resolve and type-check package AST // resolve and type-check package AST
importer := new(resolveTestImporter) importer := &resolveTestImporter{fset: fset}
conf := Config{Importer: importer} conf := Config{Importer: importer}
uses := make(map[*ast.Ident]Object) uses := make(map[*ast.Ident]Object)
defs := make(map[*ast.Ident]Object) defs := make(map[*ast.Ident]Object)

View file

@ -6,7 +6,6 @@ package types_test
import ( import (
"go/ast" "go/ast"
"go/importer"
"go/parser" "go/parser"
"go/token" "go/token"
"internal/testenv" "internal/testenv"
@ -27,7 +26,7 @@ func TestSelf(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
conf := Config{Importer: importer.Default()} conf := Config{Importer: defaultImporter(fset)}
_, err = conf.Check("go/types", fset, files, nil) _, err = conf.Check("go/types", fset, files, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -82,7 +81,7 @@ func runbench(b *testing.B, path string, ignoreFuncBodies, writeInfo bool) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
conf := Config{ conf := Config{
IgnoreFuncBodies: ignoreFuncBodies, IgnoreFuncBodies: ignoreFuncBodies,
Importer: importer.Default(), Importer: defaultImporter(fset),
} }
var info *Info var info *Info
if writeInfo { if writeInfo {

View file

@ -8,7 +8,7 @@ package types_test
import ( import (
"go/ast" "go/ast"
"go/importer" "go/token"
"go/types" "go/types"
"internal/testenv" "internal/testenv"
"testing" "testing"
@ -87,7 +87,8 @@ const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
` `
info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)} info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
conf := types.Config{ conf := types.Config{
Importer: importer.Default(), // TODO(adonovan): use same FileSet as mustTypecheck.
Importer: defaultImporter(token.NewFileSet()),
Sizes: &types.StdSizes{WordSize: 8, MaxAlign: 8}, Sizes: &types.StdSizes{WordSize: 8, MaxAlign: 8},
} }
mustTypecheck(src, &conf, &info) mustTypecheck(src, &conf, &info)
@ -117,7 +118,8 @@ var s struct {
for _, arch := range []string{"386", "amd64"} { for _, arch := range []string{"386", "amd64"} {
t.Run(arch, func(t *testing.T) { t.Run(arch, func(t *testing.T) {
conf := types.Config{ conf := types.Config{
Importer: importer.Default(), // TODO(adonovan): use same FileSet as findStructTypeConfig.
Importer: defaultImporter(token.NewFileSet()),
Sizes: types.SizesFor("gc", arch), Sizes: types.SizesFor("gc", arch),
} }
ts := findStructTypeConfig(t, src, &conf) ts := findStructTypeConfig(t, src, &conf)
@ -188,7 +190,11 @@ func TestGCSizes(t *testing.T) {
tc := tc tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
conf := types.Config{Importer: importer.Default(), Sizes: types.SizesFor("gc", "amd64")} conf := types.Config{
// TODO(adonovan): use same FileSet as mustTypecheck.
Importer: defaultImporter(token.NewFileSet()),
Sizes: types.SizesFor("gc", "amd64"),
}
mustTypecheck(tc.src, &conf, nil) mustTypecheck(tc.src, &conf, nil)
}) })
} }