]> Cypherpunks.ru repositories - gostls13.git/commitdiff
types2: add *Config to typecheck functions for tests, factor more code
authorRobert Griesemer <gri@golang.org>
Wed, 18 Jan 2023 23:55:01 +0000 (15:55 -0800)
committerGopher Robot <gobot@golang.org>
Fri, 20 Jan 2023 18:13:01 +0000 (18:13 +0000)
Some tests in go/types can still not use the typecheck helper functions
because they need a specific fileset for position information.

(We could use a single global file set for all tests to make this work.)

Change-Id: I73552b08a00f08d809c319d3d2328acee9532619
Reviewed-on: https://go-review.googlesource.com/c/go/+/461694
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
23 files changed:
src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/builtins_test.go
src/cmd/compile/internal/types2/example_test.go
src/cmd/compile/internal/types2/hilbert_test.go
src/cmd/compile/internal/types2/instantiate_test.go
src/cmd/compile/internal/types2/issues_test.go
src/cmd/compile/internal/types2/mono_test.go
src/cmd/compile/internal/types2/named_test.go
src/cmd/compile/internal/types2/object_test.go
src/cmd/compile/internal/types2/sizes_test.go
src/cmd/compile/internal/types2/typestring_test.go
src/go/types/api_test.go
src/go/types/builtins_test.go
src/go/types/example_test.go
src/go/types/hilbert_test.go
src/go/types/instantiate_test.go
src/go/types/issues_test.go
src/go/types/methodset_test.go
src/go/types/mono_test.go
src/go/types/named_test.go
src/go/types/object_test.go
src/go/types/sizes_test.go
src/go/types/typestring_test.go

index 236b05e0598cd7b2d86a72e6d4512c1b068d438d..6d03935ca1c06fd833c80019a3bb157834715a3e 100644 (file)
@@ -34,20 +34,22 @@ func mustParse(path, src string) *syntax.File {
        return f
 }
 
-func typecheck(path, src string, info *Info) (*Package, error) {
+func typecheck(path, src string, conf *Config, info *Info) (*Package, error) {
        f, err := parse(path, src)
        if f == nil { // ignore errors unless f is nil
                return nil, err
        }
-       conf := Config{
-               Error:    func(err error) {}, // collect all errors
-               Importer: defaultImporter(),
+       if conf == nil {
+               conf = &Config{
+                       Error:    func(err error) {}, // collect all errors
+                       Importer: defaultImporter(),
+               }
        }
        return conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
 }
 
-func mustTypecheck(path, src string, info *Info) *Package {
-       pkg, err := typecheck(path, src, info)
+func mustTypecheck(path, src string, conf *Config, info *Info) *Package {
+       pkg, err := typecheck(path, src, conf, info)
        if err != nil {
                panic(err) // so we don't need to pass *testing.T
        }
@@ -137,7 +139,7 @@ func TestValuesInfo(t *testing.T) {
                info := Info{
                        Types: make(map[syntax.Expr]TypeAndValue),
                }
-               name := mustTypecheck("ValuesInfo", test.src, &info).Name()
+               name := mustTypecheck("ValuesInfo", test.src, nil, &info).Name()
 
                // look for expression
                var expr syntax.Expr
@@ -379,7 +381,7 @@ func TestTypesInfo(t *testing.T) {
                info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
                var name string
                if strings.HasPrefix(test.src, brokenPkg) {
-                       pkg, err := typecheck("TypesInfo", test.src, &info)
+                       pkg, err := typecheck("TypesInfo", test.src, nil, &info)
                        if err == nil {
                                t.Errorf("package %s: expected to fail but passed", pkg.Name())
                                continue
@@ -388,7 +390,7 @@ func TestTypesInfo(t *testing.T) {
                                name = pkg.Name()
                        }
                } else {
-                       name = mustTypecheck("TypesInfo", test.src, &info).Name()
+                       name = mustTypecheck("TypesInfo", test.src, nil, &info).Name()
                }
 
                // look for expression type
@@ -553,8 +555,7 @@ type T[P any] []P
                instMap := make(map[*syntax.Name]Instance)
                useMap := make(map[*syntax.Name]Object)
                makePkg := func(src string) *Package {
-                       f := mustParse("p.go", src)
-                       pkg, _ := conf.Check("", []*syntax.File{f}, &Info{Instances: instMap, Uses: useMap})
+                       pkg, _ := typecheck("p.go", src, &conf, &Info{Instances: instMap, Uses: useMap})
                        imports[pkg.Name()] = pkg
                        return pkg
                }
@@ -650,7 +651,7 @@ func TestDefsInfo(t *testing.T) {
                info := Info{
                        Defs: make(map[*syntax.Name]Object),
                }
-               name := mustTypecheck("DefsInfo", test.src, &info).Name()
+               name := mustTypecheck("DefsInfo", test.src, nil, &info).Name()
 
                // find object
                var def Object
@@ -715,7 +716,7 @@ func TestUsesInfo(t *testing.T) {
                info := Info{
                        Uses: make(map[*syntax.Name]Object),
                }
-               name := mustTypecheck("UsesInfo", test.src, &info).Name()
+               name := mustTypecheck("UsesInfo", test.src, nil, &info).Name()
 
                // find object
                var use Object
@@ -855,7 +856,7 @@ func TestImplicitsInfo(t *testing.T) {
                info := Info{
                        Implicits: make(map[syntax.Node]Object),
                }
-               name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
+               name := mustTypecheck("ImplicitsInfo", test.src, nil, &info).Name()
 
                // the test cases expect at most one Implicits entry
                if len(info.Implicits) > 1 {
@@ -983,7 +984,7 @@ func TestPredicatesInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
-               name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
+               name := mustTypecheck("PredicatesInfo", test.src, nil, &info).Name()
 
                // look for expression predicates
                got := "<missing>"
@@ -1075,7 +1076,7 @@ func TestScopesInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{Scopes: make(map[syntax.Node]*Scope)}
-               name := mustTypecheck("ScopesInfo", test.src, &info).Name()
+               name := mustTypecheck("ScopesInfo", test.src, nil, &info).Name()
 
                // number of scopes must match
                if len(info.Scopes) != len(test.scopes) {
@@ -1263,7 +1264,7 @@ func TestInitOrderInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{}
-               name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
+               name := mustTypecheck("InitOrderInfo", test.src, nil, &info).Name()
 
                // number of initializers must match
                if len(info.InitOrder) != len(test.inits) {
@@ -1354,11 +1355,7 @@ func TestSelection(t *testing.T) {
        imports := make(testImporter)
        conf := Config{Importer: imports}
        makePkg := func(path, src string) {
-               f := mustParse(path+".go", src)
-               pkg, err := conf.Check(path, []*syntax.File{f}, &Info{Selections: selections})
-               if err != nil {
-                       t.Fatal(err)
-               }
+               pkg := mustTypecheck(path, src, &conf, &Info{Selections: selections})
                imports[path] = pkg
        }
 
@@ -1632,7 +1629,7 @@ func TestLookupFieldOrMethod(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck("test", "package p;"+test.src, nil)
+               pkg := mustTypecheck("test", "package p;"+test.src, nil, nil)
 
                obj := pkg.Scope().Lookup("a")
                if obj == nil {
@@ -1912,7 +1909,7 @@ func TestIdentical(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck("test", "package p;"+test.src, nil)
+               pkg := mustTypecheck("test", "package p;"+test.src, nil, nil)
                X := pkg.Scope().Lookup("X")
                Y := pkg.Scope().Lookup("Y")
                if X == nil || Y == nil {
@@ -2187,7 +2184,7 @@ func f(x T) T { return foo.F(x) }
 func TestInstantiate(t *testing.T) {
        // eventually we like more tests but this is a start
        const src = "package p; type T[P any] *T[P]"
-       pkg := mustTypecheck(".", src, nil)
+       pkg := mustTypecheck(".", src, nil, nil)
 
        // type T should have one type parameter
        T := pkg.Scope().Lookup("T").Type().(*Named)
@@ -2222,7 +2219,7 @@ func TestInstantiateErrors(t *testing.T) {
 
        for _, test := range tests {
                src := "package p; " + test.src
-               pkg := mustTypecheck(".", src, nil)
+               pkg := mustTypecheck(".", src, nil, nil)
 
                T := pkg.Scope().Lookup("T").Type().(*Named)
 
@@ -2542,7 +2539,7 @@ type V4 struct{}
 func (V4) M()
 `
 
-       pkg := mustTypecheck("p.go", src, nil)
+       pkg := mustTypecheck("p.go", src, nil, nil)
 
        T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
        lookup := func(name string) (*Func, bool) {
index 0d4f57e277f3db60dc40dbf95e8dcc6eee34ee24..c3647e69a41ac0b7684275fa485af4665f9bb87b 100644 (file)
@@ -173,20 +173,10 @@ func TestBuiltinSignatures(t *testing.T) {
 
 func testBuiltinSignature(t *testing.T, name, src0, want string) {
        src := fmt.Sprintf(`package p; import "unsafe"; type _ unsafe.Pointer /* use unsafe */; func _[P ~[]byte]() { %s }`, src0)
-       f, err := parse("", src)
-       if err != nil {
-               t.Errorf("%s: %s", src0, err)
-               return
-       }
 
-       conf := Config{Importer: defaultImporter()}
        uses := make(map[*syntax.Name]Object)
        types := make(map[syntax.Expr]TypeAndValue)
-       _, err = conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Uses: uses, Types: types})
-       if err != nil {
-               t.Errorf("%s: %s", src0, err)
-               return
-       }
+       mustTypecheck("p", src, nil, &Info{Uses: uses, Types: types})
 
        // find called function
        n := 0
index b89cadfb4a24beaed6dfff90baa24b5f535aa9a1..9ff7d0cfa2e0d94e04332257ac5c782c48de2107 100644 (file)
@@ -119,8 +119,6 @@ func fib(x int) int {
        }
        return fib(x-1) - fib(x-2)
 }`
-       f := mustParse("fib.go", input)
-
        // Type-check the package.
        // We create an empty map for each kind of input
        // we're interested in, and Check populates them.
@@ -129,11 +127,7 @@ func fib(x int) int {
                Defs:  make(map[*syntax.Name]types2.Object),
                Uses:  make(map[*syntax.Name]types2.Object),
        }
-       var conf types2.Config
-       pkg, err := conf.Check("fib", []*syntax.File{f}, &info)
-       if err != nil {
-               log.Fatal(err)
-       }
+       pkg := mustTypecheck("fib.go", input, nil, &info)
 
        // Print package-level variables in initialization order.
        fmt.Printf("InitOrder: %v\n\n", info.InitOrder)
index 0e9d4c3f5b7cb335255e3cc97099f52dfe4b6180..8b7ceb3c97164d93c8523d81ac9f1fda59a6c32b 100644 (file)
@@ -25,7 +25,7 @@ func TestHilbert(t *testing.T) {
                return
        }
 
-       mustTypecheck("hilbert.go", string(src), nil)
+       mustTypecheck("hilbert.go", string(src), nil, nil)
 }
 
 func program(n int, out string) []byte {
index 33a34d76f39387cec4dd9e306d82f0adccedc20c..e809d17de13d6bf95f56561a8b58b03c9be73115 100644 (file)
@@ -107,7 +107,7 @@ func TestInstantiateEquality(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck(".", test.src, nil)
+               pkg := mustTypecheck(".", test.src, nil, nil)
 
                t.Run(pkg.Name(), func(t *testing.T) {
                        ctxt := NewContext()
@@ -133,8 +133,8 @@ func TestInstantiateEquality(t *testing.T) {
 
 func TestInstantiateNonEquality(t *testing.T) {
        const src = "package p; type T[P any] int"
-       pkg1 := mustTypecheck(".", src, nil)
-       pkg2 := mustTypecheck(".", src, nil)
+       pkg1 := mustTypecheck(".", src, nil, nil)
+       pkg2 := mustTypecheck(".", src, nil, nil)
        // We consider T1 and T2 to be distinct types, so their instances should not
        // be deduplicated by the context.
        T1 := pkg1.Scope().Lookup("T").Type().(*Named)
@@ -179,7 +179,7 @@ var X T[int]
 
        for _, test := range tests {
                src := prefix + test.decl
-               pkg := mustTypecheck(".", src, nil)
+               pkg := mustTypecheck(".", src, nil, nil)
                typ := NewPointer(pkg.Scope().Lookup("X").Type())
                obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
                m, _ := obj.(*Func)
@@ -201,7 +201,7 @@ func (T[P]) m() {}
 
 var _ T[int]
 `
-       pkg := mustTypecheck(".", src, nil)
+       pkg := mustTypecheck(".", src, nil, nil)
        typ := pkg.Scope().Lookup("T").Type().(*Named)
        obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
        if obj == nil {
index 1333870dc982c980c31779beb4c305df0508c4ef..c7b63a1e68006aef1cd1f062a0b524d3eee9770f 100644 (file)
@@ -19,7 +19,7 @@ import (
 )
 
 func TestIssue5770(t *testing.T) {
-       _, err := typecheck("p", `package p; type S struct{T}`, nil)
+       _, err := typecheck("p", `package p; type S struct{T}`, nil, nil)
        const want = "undefined: T"
        if err == nil || !strings.Contains(err.Error(), want) {
                t.Errorf("got: %v; want: %s", err, want)
@@ -39,7 +39,7 @@ var (
        _ = (interface{})(nil)
 )`
        types := make(map[syntax.Expr]TypeAndValue)
-       mustTypecheck("p", src, &Info{Types: types})
+       mustTypecheck("p", src, nil, &Info{Types: types})
 
        for x, tv := range types {
                var want Type
@@ -78,7 +78,7 @@ func f() int {
 }
 `
        types := make(map[syntax.Expr]TypeAndValue)
-       mustTypecheck("p", src, &Info{Types: types})
+       mustTypecheck("p", src, nil, &Info{Types: types})
 
        want := Typ[Int]
        n := 0
@@ -133,8 +133,6 @@ func _() {
         _, _, _ = x, y, z  // uses x, y, z
 }
 `
-       f := mustParse("", src)
-
        const want = `L3 defs func p._()
 L4 defs const w untyped int
 L5 defs var x int
@@ -150,8 +148,8 @@ L7 uses var z int`
        conf := Config{Error: func(err error) { t.Log(err) }}
        defs := make(map[*syntax.Name]Object)
        uses := make(map[*syntax.Name]Object)
-       _, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Defs: defs, Uses: uses})
-       if s := fmt.Sprint(err); !strings.HasSuffix(s, "cannot assign to w") {
+       _, err := typecheck("p", src, &conf, &Info{Defs: defs, Uses: uses})
+       if s := err.Error(); !strings.HasSuffix(s, "cannot assign to w") {
                t.Errorf("Check: unexpected error: %s", s)
        }
 
@@ -230,7 +228,7 @@ func main() {
 `
        f := func(test, src string) {
                info := &Info{Uses: make(map[*syntax.Name]Object)}
-               mustTypecheck("main", src, info)
+               mustTypecheck("main", src, nil, info)
 
                var pkg *Package
                count := 0
@@ -254,11 +252,11 @@ func main() {
 }
 
 func TestIssue22525(t *testing.T) {
-       f := mustParse("", `package p; func f() { var a, b, c, d, e int }`)
+       const src = `package p; func f() { var a, b, c, d, e int }`
 
        got := "\n"
        conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
-       conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
+       typecheck("", src, &conf, nil) // do not crash
        want := `
 :1:27: a declared and not used
 :1:30: b declared and not used
@@ -443,14 +441,10 @@ func TestIssue34151(t *testing.T) {
        const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
        const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
 
-       a := mustTypecheck("a", asrc, nil)
+       a := mustTypecheck("a", asrc, nil, nil)
 
-       bast := mustParse("", bsrc)
        conf := Config{Importer: importHelper{pkg: a}}
-       b, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
-       if err != nil {
-               t.Errorf("package %s failed to typecheck: %v", b.Name(), err)
-       }
+       mustTypecheck("b", bsrc, &conf, nil)
 }
 
 type importHelper struct {
@@ -557,13 +551,12 @@ func TestIssue43124(t *testing.T) {
                csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
        )
 
-       a := mustTypecheck("a", asrc, nil)
+       a := mustTypecheck("a", asrc, nil, nil)
        conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
 
        // Packages should be fully qualified when there is ambiguity within the
        // error string itself.
-       bast := mustParse("", bsrc)
-       _, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
+       _, err := typecheck("b", bsrc, &conf, nil)
        if err == nil {
                t.Fatal("package b had no errors")
        }
@@ -572,8 +565,7 @@ func TestIssue43124(t *testing.T) {
        }
 
        // ...and also when there is any ambiguity in reachable packages.
-       cast := mustParse("", csrc)
-       _, err = conf.Check(cast.PkgName.Value, []*syntax.File{cast}, nil)
+       _, err = typecheck("c", csrc, &conf, nil)
        if err == nil {
                t.Fatal("package c had no errors")
        }
@@ -671,7 +663,7 @@ func TestIssue51093(t *testing.T) {
        for _, test := range tests {
                src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
                types := make(map[syntax.Expr]TypeAndValue)
-               mustTypecheck("p", src, &Info{Types: types})
+               mustTypecheck("p", src, nil, &Info{Types: types})
 
                var n int
                for x, tv := range types {
@@ -801,7 +793,7 @@ func (S) M5(struct {S;t}) {}
 
        test := func(main, b, want string) {
                re := regexp.MustCompile(want)
-               bpkg := mustTypecheck("b", b, nil)
+               bpkg := mustTypecheck("b", b, nil, nil)
                mast := mustParse("main.go", main)
                conf := Config{Importer: importHelper{pkg: bpkg}}
                _, err := conf.Check(mast.PkgName.Value, []*syntax.File{mast}, nil)
index 506762abae50c652c02c507cd83afb5af8182d24..17450aa04b13a157b41c50e4ae6148bd9f74840b 100644 (file)
@@ -5,7 +5,6 @@
 package types2_test
 
 import (
-       "cmd/compile/internal/syntax"
        "cmd/compile/internal/types2"
        "errors"
        "fmt"
@@ -15,14 +14,13 @@ import (
 
 func checkMono(t *testing.T, body string) error {
        src := "package x; import `unsafe`; var _ unsafe.Pointer;\n" + body
-       files := []*syntax.File{mustParse("x.go", src)}
 
        var buf strings.Builder
        conf := types2.Config{
                Error:    func(err error) { fmt.Fprintln(&buf, err) },
                Importer: defaultImporter(),
        }
-       conf.Check("x", files, nil)
+       typecheck("x", src, &conf, nil)
        if buf.Len() == 0 {
                return nil
        }
index 4140bca53972e461eba6268e5b572bf82c2e082d..7938904a9325f1987f54d50791f18f1d6ffa9d4d 100644 (file)
@@ -31,7 +31,7 @@ func (G[P]) N() (p P) { return }
 
 type Inst = G[int]
        `
-       pkg := mustTypecheck("p", src, nil)
+       pkg := mustTypecheck("p", src, nil, nil)
 
        var (
                T        = pkg.Scope().Lookup("T").Type()
index 1a0182c88574cc877f0c8506d5fa277bfe881210..ce47003474323a55cb7946edb3c2224ebfb35111 100644 (file)
@@ -56,7 +56,7 @@ func TestIsAlias(t *testing.T) {
 // the same Func Object as the original method. See also issue #34421.
 func TestEmbeddedMethod(t *testing.T) {
        const src = `package p; type I interface { error }`
-       pkg := mustTypecheck("p", src, nil)
+       pkg := mustTypecheck("p", src, nil, nil)
 
        // get original error.Error method
        eface := Universe.Lookup("error")
@@ -110,7 +110,7 @@ func TestObjectString(t *testing.T) {
 
        for _, test := range testObjects {
                src := "package p; " + test.src
-               pkg, err := typecheck(filename, src, nil)
+               pkg, err := typecheck(filename, src, nil, nil)
                if err != nil {
                        t.Errorf("%s: %s", src, err)
                        continue
index e548c2d0478391fe3e6909ff692c6596540d27c0..664eff3cf0d115fa4e7d6e67d0bda7e16076af24 100644 (file)
@@ -20,7 +20,7 @@ func findStructType(t *testing.T, src string) *types2.Struct {
 
 func findStructTypeConfig(t *testing.T, src string, conf *types2.Config) *types2.Struct {
        types := make(map[syntax.Expr]types2.TypeAndValue)
-       mustTypecheck("x", src, &types2.Info{Types: types})
+       mustTypecheck("x", src, nil, &types2.Info{Types: types})
        for _, tv := range types {
                if ts, ok := tv.Type.(*types2.Struct); ok {
                        return ts
@@ -84,16 +84,12 @@ import "unsafe"
 
 const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
 `
-       f := mustParse("x.go", src)
        info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
        conf := types2.Config{
                Importer: defaultImporter(),
                Sizes:    &types2.StdSizes{WordSize: 8, MaxAlign: 8},
        }
-       _, err := conf.Check("x", []*syntax.File{f}, &info)
-       if err != nil {
-               t.Fatal(err)
-       }
+       mustTypecheck("x", src, &conf, &info)
        for _, tv := range info.Types {
                _ = conf.Sizes.Sizeof(tv.Type)
                _ = conf.Sizes.Alignof(tv.Type)
index 7dd9b3528115088bf0f280d275757816c52db63b..193ee251f09ab3db4838e9ab9df48402b3e12f88 100644 (file)
@@ -118,7 +118,7 @@ func TestTypeString(t *testing.T) {
 
        for _, test := range tests {
                src := `package generic_p; import "io"; type _ io.Writer; type T ` + test.src
-               pkg, err := typecheck(filename, src, nil)
+               pkg, err := typecheck(filename, src, nil, nil)
                if err != nil {
                        t.Errorf("%s: %s", src, err)
                        continue
@@ -136,8 +136,8 @@ func TestTypeString(t *testing.T) {
 }
 
 func TestQualifiedTypeString(t *testing.T) {
-       p := mustTypecheck("p.go", "package p; type T int", nil)
-       q := mustTypecheck("q.go", "package q", nil)
+       p := mustTypecheck("p.go", "package p; type T int", nil, nil)
+       q := mustTypecheck("q.go", "package q", nil, nil)
 
        pT := p.Scope().Lookup("T").Type()
        for _, test := range []struct {
index ba45ca293ef33a84e1b09685224bc3f0a8239246..b154ad58524911ceed436598347864159d5ee2e0 100644 (file)
@@ -36,21 +36,23 @@ func mustParse(fset *token.FileSet, filename, src string) *ast.File {
        return f
 }
 
-func typecheck(path, src string, info *Info) (*Package, error) {
+func typecheck(path, src string, conf *Config, info *Info) (*Package, error) {
        fset := token.NewFileSet()
        f, err := parse(fset, path, src)
        if f == nil { // ignore errors unless f is nil
                return nil, err
        }
-       conf := Config{
-               Error:    func(err error) {}, // collect all errors
-               Importer: importer.Default(),
+       if conf == nil {
+               conf = &Config{
+                       Error:    func(err error) {}, // collect all errors
+                       Importer: importer.Default(),
+               }
        }
        return conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
 }
 
-func mustTypecheck(path, src string, info *Info) *Package {
-       pkg, err := typecheck(path, src, info)
+func mustTypecheck(path, src string, conf *Config, info *Info) *Package {
+       pkg, err := typecheck(path, src, conf, info)
        if err != nil {
                panic(err) // so we don't need to pass *testing.T
        }
@@ -140,7 +142,7 @@ func TestValuesInfo(t *testing.T) {
                info := Info{
                        Types: make(map[ast.Expr]TypeAndValue),
                }
-               name := mustTypecheck("ValuesInfo", test.src, &info).Name()
+               name := mustTypecheck("ValuesInfo", test.src, nil, &info).Name()
 
                // look for expression
                var expr ast.Expr
@@ -378,7 +380,7 @@ func TestTypesInfo(t *testing.T) {
                info := Info{Types: make(map[ast.Expr]TypeAndValue)}
                var name string
                if strings.HasPrefix(test.src, broken) {
-                       pkg, err := typecheck("TypesInfo", test.src, &info)
+                       pkg, err := typecheck("TypesInfo", test.src, nil, &info)
                        if err == nil {
                                t.Errorf("package %s: expected to fail but passed", pkg.Name())
                                continue
@@ -387,7 +389,7 @@ func TestTypesInfo(t *testing.T) {
                                name = pkg.Name()
                        }
                } else {
-                       name = mustTypecheck("TypesInfo", test.src, &info).Name()
+                       name = mustTypecheck("TypesInfo", test.src, nil, &info).Name()
                }
 
                // look for expression type
@@ -552,8 +554,7 @@ type T[P any] []P
                instMap := make(map[*ast.Ident]Instance)
                useMap := make(map[*ast.Ident]Object)
                makePkg := func(src string) *Package {
-                       f := mustParse(fset, "p.go", src)
-                       pkg, _ := conf.Check("", fset, []*ast.File{f}, &Info{Instances: instMap, Uses: useMap})
+                       pkg, _ := typecheck("p.go", src, &conf, &Info{Instances: instMap, Uses: useMap})
                        imports[pkg.Name()] = pkg
                        return pkg
                }
@@ -648,7 +649,7 @@ func TestDefsInfo(t *testing.T) {
                info := Info{
                        Defs: make(map[*ast.Ident]Object),
                }
-               name := mustTypecheck("DefsInfo", test.src, &info).Name()
+               name := mustTypecheck("DefsInfo", test.src, nil, &info).Name()
 
                // find object
                var def Object
@@ -715,7 +716,7 @@ func TestUsesInfo(t *testing.T) {
                info := Info{
                        Uses: make(map[*ast.Ident]Object),
                }
-               name := mustTypecheck("UsesInfo", test.src, &info).Name()
+               name := mustTypecheck("UsesInfo", test.src, nil, &info).Name()
 
                // find object
                var use Object
@@ -856,7 +857,7 @@ func TestImplicitsInfo(t *testing.T) {
                info := Info{
                        Implicits: make(map[ast.Node]Object),
                }
-               name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
+               name := mustTypecheck("ImplicitsInfo", test.src, nil, &info).Name()
 
                // the test cases expect at most one Implicits entry
                if len(info.Implicits) > 1 {
@@ -984,7 +985,7 @@ func TestPredicatesInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{Types: make(map[ast.Expr]TypeAndValue)}
-               name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
+               name := mustTypecheck("PredicatesInfo", test.src, nil, &info).Name()
 
                // look for expression predicates
                got := "<missing>"
@@ -1076,7 +1077,7 @@ func TestScopesInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{Scopes: make(map[ast.Node]*Scope)}
-               name := mustTypecheck("ScopesInfo", test.src, &info).Name()
+               name := mustTypecheck("ScopesInfo", test.src, nil, &info).Name()
 
                // number of scopes must match
                if len(info.Scopes) != len(test.scopes) {
@@ -1264,7 +1265,7 @@ func TestInitOrderInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{}
-               name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
+               name := mustTypecheck("InitOrderInfo", test.src, nil, &info).Name()
 
                // number of initializers must match
                if len(info.InitOrder) != len(test.inits) {
@@ -1354,6 +1355,8 @@ func (m testImporter) Import(path string) (*Package, error) {
 func TestSelection(t *testing.T) {
        selections := make(map[*ast.SelectorExpr]*Selection)
 
+       // We need a specific fileset in this test below for positions.
+       // Cannot use typecheck helper.
        fset := token.NewFileSet()
        imports := make(testImporter)
        conf := Config{Importer: imports}
@@ -1626,7 +1629,7 @@ func TestLookupFieldOrMethod(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck("test", "package p;"+test.src, nil)
+               pkg := mustTypecheck("test", "package p;"+test.src, nil, nil)
 
                obj := pkg.Scope().Lookup("a")
                if obj == nil {
@@ -1905,7 +1908,7 @@ func TestIdentical(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck("test", "package p;"+test.src, nil)
+               pkg := mustTypecheck("test", "package p;"+test.src, nil, nil)
                X := pkg.Scope().Lookup("X")
                Y := pkg.Scope().Lookup("Y")
                if X == nil || Y == nil {
@@ -2184,7 +2187,7 @@ func f(x T) T { return foo.F(x) }
 func TestInstantiate(t *testing.T) {
        // eventually we like more tests but this is a start
        const src = "package p; type T[P any] *T[P]"
-       pkg := mustTypecheck(".", src, nil)
+       pkg := mustTypecheck(".", src, nil, nil)
 
        // type T should have one type parameter
        T := pkg.Scope().Lookup("T").Type().(*Named)
@@ -2219,7 +2222,7 @@ func TestInstantiateErrors(t *testing.T) {
 
        for _, test := range tests {
                src := "package p; " + test.src
-               pkg := mustTypecheck(".", src, nil)
+               pkg := mustTypecheck(".", src, nil, nil)
 
                T := pkg.Scope().Lookup("T").Type().(*Named)
 
@@ -2542,7 +2545,7 @@ type V4 struct{}
 func (V4) M()
 `
 
-       pkg := mustTypecheck("p.go", src, nil)
+       pkg := mustTypecheck("p.go", src, nil, nil)
 
        T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
        lookup := func(name string) (*Func, bool) {
index 662ececf742f4c32cbcb342170efdfbf60dfb182..e15bb3242fd226447ab2bbec7fd2aa225f1203ae 100644 (file)
@@ -7,7 +7,6 @@ package types_test
 import (
        "fmt"
        "go/ast"
-       "go/importer"
        "testing"
 
        . "go/types"
@@ -174,20 +173,10 @@ func TestBuiltinSignatures(t *testing.T) {
 
 func testBuiltinSignature(t *testing.T, name, src0, want string) {
        src := fmt.Sprintf(`package p; import "unsafe"; type _ unsafe.Pointer /* use unsafe */; func _[P ~[]byte]() { %s }`, src0)
-       f, err := parse(fset, "", src)
-       if err != nil {
-               t.Errorf("%s: %s", src0, err)
-               return
-       }
 
-       conf := Config{Importer: importer.Default()}
        uses := make(map[*ast.Ident]Object)
        types := make(map[ast.Expr]TypeAndValue)
-       _, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Uses: uses, Types: types})
-       if err != nil {
-               t.Errorf("%s: %s", src0, err)
-               return
-       }
+       mustTypecheck("p", src, nil, &Info{Uses: uses, Types: types})
 
        // find called function
        n := 0
index 605e9874088de78f6a7340cac6cc1a4c5f4494fe..b54a142bd4f3455cecabec7e04bddd62d3800d4e 100644 (file)
@@ -180,6 +180,8 @@ func fib(x int) int {
        }
        return fib(x-1) - fib(x-2)
 }`
+       // We need a specific fileset in this test below for positions.
+       // Cannot use typecheck helper.
        fset := token.NewFileSet()
        f := mustParse(fset, "fib.go", input)
 
index ed7b9866c9a001efc5cfe6a68236a7d73c2d7ad6..15e5ae3aca6999c60cebf4ddf090c72ce210c946 100644 (file)
@@ -27,7 +27,7 @@ func TestHilbert(t *testing.T) {
                return
        }
 
-       mustTypecheck("hilbert.go", string(src), nil)
+       mustTypecheck("hilbert.go", string(src), nil, nil)
 }
 
 func program(n int, out string) []byte {
index 54e725fc972dffbd65a84e36bd5015484216006b..91b2a1aaba55fa2482d6ceb278475af3186ca579 100644 (file)
@@ -109,7 +109,7 @@ func TestInstantiateEquality(t *testing.T) {
        }
 
        for _, test := range tests {
-               pkg := mustTypecheck(".", test.src, nil)
+               pkg := mustTypecheck(".", test.src, nil, nil)
 
                t.Run(pkg.Name(), func(t *testing.T) {
                        ctxt := NewContext()
@@ -135,8 +135,8 @@ func TestInstantiateEquality(t *testing.T) {
 
 func TestInstantiateNonEquality(t *testing.T) {
        const src = "package p; type T[P any] int"
-       pkg1 := mustTypecheck(".", src, nil)
-       pkg2 := mustTypecheck(".", src, nil)
+       pkg1 := mustTypecheck(".", src, nil, nil)
+       pkg2 := mustTypecheck(".", src, nil, nil)
        // We consider T1 and T2 to be distinct types, so their instances should not
        // be deduplicated by the context.
        T1 := pkg1.Scope().Lookup("T").Type().(*Named)
@@ -181,7 +181,7 @@ var X T[int]
 
        for _, test := range tests {
                src := prefix + test.decl
-               pkg := mustTypecheck(".", src, nil)
+               pkg := mustTypecheck(".", src, nil, nil)
                typ := NewPointer(pkg.Scope().Lookup("X").Type())
                obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
                m, _ := obj.(*Func)
@@ -203,7 +203,7 @@ func (T[P]) m() {}
 
 var _ T[int]
 `
-       pkg := mustTypecheck(".", src, nil)
+       pkg := mustTypecheck(".", src, nil, nil)
        typ := pkg.Scope().Lookup("T").Type().(*Named)
        obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
        if obj == nil {
index 472faae0ed33fb5ba3006e89266076c92564d13b..2b7618cbd08464cd2f0e9b136d76365eb28eead7 100644 (file)
@@ -21,7 +21,7 @@ import (
 )
 
 func TestIssue5770(t *testing.T) {
-       _, err := typecheck("p", `package p; type S struct{T}`, nil)
+       _, err := typecheck("p", `package p; type S struct{T}`, nil, nil)
        const want = "undefined: T"
        if err == nil || !strings.Contains(err.Error(), want) {
                t.Errorf("got: %v; want: %s", err, want)
@@ -41,7 +41,7 @@ var (
        _ = (interface{})(nil)
 )`
        types := make(map[ast.Expr]TypeAndValue)
-       mustTypecheck("p", src, &Info{Types: types})
+       mustTypecheck("p", src, nil, &Info{Types: types})
 
        for x, tv := range types {
                var want Type
@@ -80,7 +80,7 @@ func f() int {
 }
 `
        types := make(map[ast.Expr]TypeAndValue)
-       mustTypecheck("p", src, &Info{Types: types})
+       mustTypecheck("p", src, nil, &Info{Types: types})
 
        want := Typ[Int]
        n := 0
@@ -135,6 +135,9 @@ func _() {
         _, _, _ = x, y, z  // uses x, y, z
 }
 `
+       // We need a specific fileset in this test below for positions.
+       // Cannot use typecheck helper.
+       fset := token.NewFileSet()
        f := mustParse(fset, "", src)
 
        const want = `L3 defs func p._()
@@ -153,7 +156,7 @@ L7 uses var z int`
        defs := make(map[*ast.Ident]Object)
        uses := make(map[*ast.Ident]Object)
        _, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Defs: defs, Uses: uses})
-       if s := fmt.Sprint(err); !strings.HasSuffix(s, "cannot assign to w") {
+       if s := err.Error(); !strings.HasSuffix(s, "cannot assign to w") {
                t.Errorf("Check: unexpected error: %s", s)
        }
 
@@ -232,7 +235,7 @@ func main() {
 `
        f := func(test, src string) {
                info := &Info{Uses: make(map[*ast.Ident]Object)}
-               mustTypecheck("main", src, info)
+               mustTypecheck("main", src, nil, info)
 
                var pkg *Package
                count := 0
@@ -256,11 +259,11 @@ func main() {
 }
 
 func TestIssue22525(t *testing.T) {
-       f := mustParse(fset, "", `package p; func f() { var a, b, c, d, e int }`)
+       const src = `package p; func f() { var a, b, c, d, e int }`
 
        got := "\n"
        conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
-       conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash
+       typecheck("", src, &conf, nil) // do not crash
        want := `
 1:27: a declared and not used
 1:30: b declared and not used
@@ -444,14 +447,10 @@ func TestIssue34151(t *testing.T) {
        const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
        const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
 
-       a := mustTypecheck("a", asrc, nil)
+       a := mustTypecheck("a", asrc, nil, nil)
 
-       bast := mustParse(fset, "", bsrc)
        conf := Config{Importer: importHelper{pkg: a}}
-       b, err := conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil)
-       if err != nil {
-               t.Errorf("package %s failed to typecheck: %v", b.Name(), err)
-       }
+       mustTypecheck("b", bsrc, &conf, nil)
 }
 
 type importHelper struct {
@@ -600,7 +599,7 @@ var _ T = template /* ERRORx "cannot use.*text/template.* as T value" */.Templat
 `
        )
 
-       a := mustTypecheck("a", asrc, nil)
+       a := mustTypecheck("a", asrc, nil, nil)
        imp := importHelper{pkg: a, fallback: importer.Default()}
 
        testFiles(t, nil, []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
@@ -697,7 +696,7 @@ func TestIssue51093(t *testing.T) {
        for _, test := range tests {
                src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
                types := make(map[ast.Expr]TypeAndValue)
-               mustTypecheck("p", src, &Info{Types: types})
+               mustTypecheck("p", src, nil, &Info{Types: types})
 
                var n int
                for x, tv := range types {
@@ -829,7 +828,7 @@ func (S) M5(struct {S;t}) {}
        fset := token.NewFileSet()
        test := func(main, b, want string) {
                re := regexp.MustCompile(want)
-               bpkg := mustTypecheck("b", b, nil)
+               bpkg := mustTypecheck("b", b, nil, nil)
                mast := mustParse(fset, "main.go", main)
                conf := Config{Importer: importHelper{pkg: bpkg}}
                _, err := conf.Check(mast.Name.Name, fset, []*ast.File{mast}, nil)
index 443994be3e65698dc4526f5243baa75c6b5347a4..13ccf9623e3b9b9bf13d71ad87db242c21624f16 100644 (file)
@@ -84,7 +84,7 @@ func TestNewMethodSet(t *testing.T) {
        }
 
        check := func(src string, methods []method, generic bool) {
-               pkg := mustTypecheck("test", "package p;"+src, nil)
+               pkg := mustTypecheck("test", "package p;"+src, nil, nil)
 
                scope := pkg.Scope()
                if generic {
index 9dda2c28f3773a7accda6a9dadb5bf64f5f0e79f..a8d2acfd66c71579e092f5f284d47b71af658b90 100644 (file)
@@ -7,25 +7,21 @@ package types_test
 import (
        "errors"
        "fmt"
-       "go/ast"
        "go/importer"
-       "go/token"
        "go/types"
        "strings"
        "testing"
 )
 
 func checkMono(t *testing.T, body string) error {
-       fset := token.NewFileSet()
        src := "package x; import `unsafe`; var _ unsafe.Pointer;\n" + body
-       files := []*ast.File{mustParse(fset, "x.go", src)}
 
        var buf strings.Builder
        conf := types.Config{
                Error:    func(err error) { fmt.Fprintln(&buf, err) },
                Importer: importer.Default(),
        }
-       conf.Check("x", fset, files, nil)
+       typecheck("x", src, &conf, nil)
        if buf.Len() == 0 {
                return nil
        }
index 92f17e5455e735d6e600c7d68f5fe1aaf38585d9..3cbe1ef83b04e524cfb06eaa298f99279bdc2a6f 100644 (file)
@@ -32,7 +32,7 @@ func (G[P]) N() (p P) { return }
 
 type Inst = G[int]
        `
-       pkg := mustTypecheck("p", src, nil)
+       pkg := mustTypecheck("p", src, nil, nil)
 
        var (
                T        = pkg.Scope().Lookup("T").Type()
index 5658e38cbe9610c0b3a70c13830754c92144c301..912716b9e0b20887d79e83b36b764adb1285489b 100644 (file)
@@ -58,7 +58,7 @@ func TestIsAlias(t *testing.T) {
 // the same Func Object as the original method. See also issue #34421.
 func TestEmbeddedMethod(t *testing.T) {
        const src = `package p; type I interface { error }`
-       pkg := mustTypecheck("p", src, nil)
+       pkg := mustTypecheck("p", src, nil, nil)
 
        // get original error.Error method
        eface := Universe.Lookup("error")
@@ -112,7 +112,7 @@ func TestObjectString(t *testing.T) {
 
        for _, test := range testObjects {
                src := "package p; " + test.src
-               pkg, err := typecheck(filename, src, nil)
+               pkg, err := typecheck(filename, src, nil, nil)
                if err != nil {
                        t.Errorf("%s: %s", src, err)
                        continue
index 09ac9e2c26d66cb0400390853d24dff522985a74..7fbafd82c49a27e5ff627cff97cc1dd21db07042 100644 (file)
@@ -9,7 +9,6 @@ package types_test
 import (
        "go/ast"
        "go/importer"
-       "go/token"
        "go/types"
        "internal/testenv"
        "testing"
@@ -22,7 +21,7 @@ func findStructType(t *testing.T, src string) *types.Struct {
 
 func findStructTypeConfig(t *testing.T, src string, conf *types.Config) *types.Struct {
        types_ := make(map[ast.Expr]types.TypeAndValue)
-       mustTypecheck("x", src, &types.Info{Types: types_})
+       mustTypecheck("x", src, nil, &types.Info{Types: types_})
        for _, tv := range types_ {
                if ts, ok := tv.Type.(*types.Struct); ok {
                        return ts
@@ -86,17 +85,12 @@ import "unsafe"
 
 const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
 `
-       fset := token.NewFileSet()
-       f := mustParse(fset, "x.go", src)
        info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
        conf := types.Config{
                Importer: importer.Default(),
                Sizes:    &types.StdSizes{WordSize: 8, MaxAlign: 8},
        }
-       _, err := conf.Check("x", fset, []*ast.File{f}, &info)
-       if err != nil {
-               t.Fatal(err)
-       }
+       mustTypecheck("x", src, &conf, &info)
        for _, tv := range info.Types {
                _ = conf.Sizes.Sizeof(tv.Type)
                _ = conf.Sizes.Alignof(tv.Type)
index e73f24138bde633915301bfba9703923eca73cf8..d3172d6bb9b5d585066c2af1805717d4ee14c7cf 100644 (file)
@@ -119,7 +119,7 @@ func TestTypeString(t *testing.T) {
 
        for _, test := range tests {
                src := `package p; import "io"; type _ io.Writer; type T ` + test.src
-               pkg, err := typecheck(filename, src, nil)
+               pkg, err := typecheck(filename, src, nil, nil)
                if err != nil {
                        t.Errorf("%s: %s", src, err)
                        continue
@@ -137,8 +137,8 @@ func TestTypeString(t *testing.T) {
 }
 
 func TestQualifiedTypeString(t *testing.T) {
-       p := mustTypecheck("p.go", "package p; type T int", nil)
-       q := mustTypecheck("q.go", "package q", nil)
+       p := mustTypecheck("p.go", "package p; type T int", nil, nil)
+       q := mustTypecheck("q.go", "package q", nil, nil)
 
        pT := p.Scope().Lookup("T").Type()
        for _, test := range []struct {