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
}
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
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
name = pkg.Name()
}
} else {
- name = mustTypecheck("TypesInfo", test.src, &info).Name()
+ name = mustTypecheck("TypesInfo", test.src, nil, &info).Name()
}
// look for expression type
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
}
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
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
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 {
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>"
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) {
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) {
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
}
}
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 {
}
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 {
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)
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)
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) {
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
}
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.
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)
return
}
- mustTypecheck("hilbert.go", string(src), nil)
+ mustTypecheck("hilbert.go", string(src), nil, nil)
}
func program(n int, out string) []byte {
}
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()
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)
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)
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 {
)
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)
_ = (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
}
`
types := make(map[syntax.Expr]TypeAndValue)
- mustTypecheck("p", src, &Info{Types: types})
+ mustTypecheck("p", src, nil, &Info{Types: types})
want := Typ[Int]
n := 0
_, _, _ = 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
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)
}
`
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
}
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
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 {
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")
}
}
// ...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")
}
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 {
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)
package types2_test
import (
- "cmd/compile/internal/syntax"
"cmd/compile/internal/types2"
"errors"
"fmt"
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
}
type Inst = G[int]
`
- pkg := mustTypecheck("p", src, nil)
+ pkg := mustTypecheck("p", src, nil, nil)
var (
T = pkg.Scope().Lookup("T").Type()
// 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")
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
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
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)
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
}
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 {
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
}
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
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
name = pkg.Name()
}
} else {
- name = mustTypecheck("TypesInfo", test.src, &info).Name()
+ name = mustTypecheck("TypesInfo", test.src, nil, &info).Name()
}
// look for expression type
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
}
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
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
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 {
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>"
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) {
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) {
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}
}
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 {
}
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 {
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)
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)
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) {
import (
"fmt"
"go/ast"
- "go/importer"
"testing"
. "go/types"
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
}
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)
return
}
- mustTypecheck("hilbert.go", string(src), nil)
+ mustTypecheck("hilbert.go", string(src), nil, nil)
}
func program(n int, out string) []byte {
}
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()
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)
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)
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 {
)
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)
_ = (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
}
`
types := make(map[ast.Expr]TypeAndValue)
- mustTypecheck("p", src, &Info{Types: types})
+ mustTypecheck("p", src, nil, &Info{Types: types})
want := Typ[Int]
n := 0
_, _, _ = 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._()
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)
}
`
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
}
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
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 {
`
)
- 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)
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 {
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)
}
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 {
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
}
type Inst = G[int]
`
- pkg := mustTypecheck("p", src, nil)
+ pkg := mustTypecheck("p", src, nil, nil)
var (
T = pkg.Scope().Lookup("T").Type()
// 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")
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
import (
"go/ast"
"go/importer"
- "go/token"
"go/types"
"internal/testenv"
"testing"
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
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)
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
}
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 {