From 40a278e5eee1f4b78bc7cd47541330819f1d6d75 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 18 Jul 2013 17:07:44 -0700 Subject: [PATCH] go.tools/go/types: rename Context -> Config (more apt name) Also: Various minor cleanups. R=adonovan, r CC=golang-dev https://golang.org/cl/11445044 --- cmd/vet/types.go | 6 +++--- go/types/api.go | 22 +++++++++++----------- go/types/assignments.go | 2 +- go/types/builtins.go | 8 ++++---- go/types/check.go | 20 ++++++++++---------- go/types/check_test.go | 6 +++--- go/types/conversions.go | 6 +++--- go/types/errors.go | 2 +- go/types/eval.go | 6 +++--- go/types/expr.go | 30 ++++++++++++++++-------------- go/types/issues_test.go | 4 ++-- go/types/methodset.go | 1 + go/types/operand.go | 8 +++----- go/types/resolver.go | 10 +++++----- go/types/resolver_test.go | 6 +++--- go/types/sizes.go | 30 +++++++++++++++--------------- go/types/stdlib_test.go | 6 +++--- importer/importer.go | 2 +- 18 files changed, 88 insertions(+), 87 deletions(-) diff --git a/cmd/vet/types.go b/cmd/vet/types.go index c91e6d6e..27ce4687 100644 --- a/cmd/vet/types.go +++ b/cmd/vet/types.go @@ -19,9 +19,9 @@ func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error { pkg.spans = make(map[types.Object]Span) pkg.types = make(map[ast.Expr]types.Type) pkg.values = make(map[ast.Expr]exact.Value) - // By providing the Context with our own error function, it will continue + // By providing a Config with our own error function, it will continue // past the first error. There is no need for that function to do anything. - context := types.Context{ + config := types.Config{ Error: func(error) {}, } info := &types.Info{ @@ -29,7 +29,7 @@ func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error { Values: pkg.values, Objects: pkg.idents, } - _, err := context.Check(pkg.path, fs, astFiles, info) + _, err := config.Check(pkg.path, fs, astFiles, info) // update spans for id, obj := range pkg.idents { pkg.growSpan(id, obj) diff --git a/go/types/api.go b/go/types/api.go index a81e3b00..9d34474d 100644 --- a/go/types/api.go +++ b/go/types/api.go @@ -4,7 +4,7 @@ // Package types declares the data types and implements // the algorithms for type-checking of Go packages. -// Use Check and Context.Check to invoke the type-checker. +// Use Check and Config.Check to invoke the type-checker. // // Type-checking consists of several interdependent phases: // @@ -34,19 +34,19 @@ import ( // list of *ast.Files and corresponding file set, and the import path // the package is identified with. The path must not be empty or dot ("."). // -// For more control over type-checking and results, use Context.Check. +// For more control over type-checking and results, use Config.Check. func Check(path string, fset *token.FileSet, files []*ast.File) (*Package, error) { - var ctxt Context - pkg, err := ctxt.check(path, fset, files, nil) + var conf Config + pkg, err := conf.check(path, fset, files, nil) if err != nil { return nil, err } return pkg, nil } -// A Context specifies the supporting context for type checking. -// The zero value for a Context is a ready-to-use default context. -type Context struct { +// A Config specifies the configuration for type checking. +// The zero value for Config is a ready-to-use default configuration. +type Config struct { // If Error != nil, it is called with each error found // during type checking. The error strings of errors with // detailed position information are formatted as follows: @@ -103,7 +103,7 @@ type Info struct { // are not recorded. Objects map[*ast.Ident]Object - // If Implicits != nil, it records the object for each node the implicitly + // If Implicits != nil, it records the object for each node that implicitly // declares objects. The following node and object types may appear: // // node obj @@ -118,15 +118,15 @@ type Info struct { // error if any, and if info != nil, additional type information. The package is // specified by a list of *ast.Files and corresponding file set, and the import // path the package is identified with. The path must not be empty or dot ("."). -func (ctxt *Context) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) { - return ctxt.check(path, fset, files, info) +func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) { + return conf.check(path, fset, files, info) } // IsAssignableTo reports whether a value of type V // is assignable to a variable of type T. func IsAssignableTo(V, T Type) bool { x := operand{mode: value, typ: V} - return x.isAssignableTo(nil, T) // context not needed for non-constant x + return x.isAssignableTo(nil, T) // config not needed for non-constant x } // BUG(gri): Conversions of constants only change the type, not the value (e.g., int(1.1) is wrong). diff --git a/go/types/assignments.go b/go/types/assignments.go index 6de6b783..f045acb4 100644 --- a/go/types/assignments.go +++ b/go/types/assignments.go @@ -32,7 +32,7 @@ func (check *checker) assignment(x *operand, to Type) bool { check.convertUntyped(x, to) - return x.mode != invalid && x.isAssignableTo(check.ctxt, to) + return x.mode != invalid && x.isAssignableTo(check.conf, to) } func (check *checker) initConst(lhs *Const, x *operand) { diff --git a/go/types/builtins.go b/go/types/builtins.go index dcd5d1da..a1c706c3 100644 --- a/go/types/builtins.go +++ b/go/types/builtins.go @@ -236,7 +236,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *Builtin) { if x.mode == invalid { goto Error } - if !x.isAssignableTo(check.ctxt, m.key) { + if !x.isAssignableTo(check.conf, m.key) { check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key) goto Error } @@ -327,7 +327,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *Builtin) { case _Alignof: x.mode = constant - x.val = exact.MakeInt64(check.ctxt.alignof(x.typ)) + x.val = exact.MakeInt64(check.conf.alignof(x.typ)) x.typ = Typ[Uintptr] case _Offsetof: @@ -355,14 +355,14 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *Builtin) { check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base) goto Error } - offs := check.ctxt.offsetof(base, index) + offs := check.conf.offsetof(base, index) x.mode = constant x.val = exact.MakeInt64(offs) x.typ = Typ[Uintptr] case _Sizeof: x.mode = constant - x.val = exact.MakeInt64(check.ctxt.sizeof(x.typ)) + x.val = exact.MakeInt64(check.conf.sizeof(x.typ)) x.typ = Typ[Uintptr] case _Assert: diff --git a/go/types/check.go b/go/types/check.go index 8a2eff30..449b5e65 100644 --- a/go/types/check.go +++ b/go/types/check.go @@ -36,7 +36,7 @@ type exprInfo struct { // A checker is an instance of the type checker. type checker struct { - ctxt *Context + conf *Config fset *token.FileSet Info @@ -59,9 +59,9 @@ type checker struct { indent int // indentation for tracing } -func newChecker(ctxt *Context, fset *token.FileSet, pkg *Package) *checker { +func newChecker(conf *Config, fset *token.FileSet, pkg *Package) *checker { return &checker{ - ctxt: ctxt, + conf: conf, fset: fset, pkg: pkg, methods: make(map[*TypeName]*Scope), @@ -133,14 +133,14 @@ func (check *checker) handleBailout(err *error) { } } -func (ctxt *Context) check(pkgPath string, fset *token.FileSet, files []*ast.File, info *Info) (pkg *Package, err error) { +func (conf *Config) check(pkgPath string, fset *token.FileSet, files []*ast.File, info *Info) (pkg *Package, err error) { pkg = &Package{ path: pkgPath, scope: NewScope(Universe), imports: make(map[string]*Package), } - check := newChecker(ctxt, fset, pkg) + check := newChecker(conf, fset, pkg) defer check.handleBailout(&err) // we need a reasonable path to continue @@ -149,11 +149,6 @@ func (ctxt *Context) check(pkgPath string, fset *token.FileSet, files []*ast.Fil return } - // install optional info - if info != nil { - check.Info = *info - } - // determine package name and files i := 0 for _, file := range files { @@ -170,6 +165,11 @@ func (ctxt *Context) check(pkgPath string, fset *token.FileSet, files []*ast.Fil } } + // install optional info + if info != nil { + check.Info = *info + } + // TODO(gri) resolveFiles needs to be split up and renamed (cleanup) check.resolveFiles(files[:i]) diff --git a/go/types/check_test.go b/go/types/check_test.go index 10ddf38d..c7fbf52f 100644 --- a/go/types/check_test.go +++ b/go/types/check_test.go @@ -203,8 +203,8 @@ func checkFiles(t *testing.T, testfiles []string) { } // typecheck and collect typechecker errors - var ctxt Context - ctxt.Error = func(err error) { + var conf Config + conf.Error = func(err error) { if *listErrors { t.Error(err) return @@ -216,7 +216,7 @@ func checkFiles(t *testing.T, testfiles []string) { errlist = append(errlist, err) } } - ctxt.Check(pkgName, fset, files, nil) + conf.Check(pkgName, fset, files, nil) if *listErrors { return diff --git a/go/types/conversions.go b/go/types/conversions.go index 7ca10089..8e1f32bc 100644 --- a/go/types/conversions.go +++ b/go/types/conversions.go @@ -58,7 +58,7 @@ func (check *checker) conversion(x *operand, conv *ast.CallExpr, typ Type) { // TODO(gri) verify the remaining conversions. } else { // non-constant conversion - if !x.isConvertible(check.ctxt, typ) { + if !x.isConvertible(check.conf, typ) { goto ErrorMsg } x.mode = value @@ -91,9 +91,9 @@ Error: x.expr = conv } -func (x *operand) isConvertible(ctxt *Context, T Type) bool { +func (x *operand) isConvertible(conf *Config, T Type) bool { // "x is assignable to T" - if x.isAssignableTo(ctxt, T) { + if x.isAssignableTo(conf, T) { return true } diff --git a/go/types/errors.go b/go/types/errors.go index f8a4a7b5..502e76ba 100644 --- a/go/types/errors.go +++ b/go/types/errors.go @@ -58,7 +58,7 @@ func (check *checker) err(err error) { if check.firsterr == nil { check.firsterr = err } - f := check.ctxt.Error + f := check.conf.Error if f == nil { panic(bailout{}) // report only first error } diff --git a/go/types/eval.go b/go/types/eval.go index 028f5664..8f49b84b 100644 --- a/go/types/eval.go +++ b/go/types/eval.go @@ -86,8 +86,8 @@ func EvalNode(fset *token.FileSet, node ast.Expr, pkg *Package, scope *Scope) (t } // initialize checker - var ctxt Context - check := newChecker(&ctxt, fset, pkg) + var conf Config + check := newChecker(&conf, fset, pkg) check.topScope = scope defer check.handleBailout(&err) @@ -95,7 +95,7 @@ func EvalNode(fset *token.FileSet, node ast.Expr, pkg *Package, scope *Scope) (t var x operand check.exprOrType(&x, node) switch x.mode { - case invalid, novalue, typexprn: + case invalid, novalue: fallthrough default: unreachable() // or bailed out with error diff --git a/go/types/expr.go b/go/types/expr.go index 338c25c6..341ac85f 100644 --- a/go/types/expr.go +++ b/go/types/expr.go @@ -61,7 +61,8 @@ constant lhs must be representable as an integer. When an expression gets its final type, either on the way out from rawExpr, on the way down in updateExprType, or at the end of the type checker run, -if present the Context.Expr method is invoked to notify a go/types client. +the type (and constant value, if any) is recorded via Info.Types and Values, +if present. */ type opPredicates map[token.Token]func(Type) bool @@ -124,7 +125,7 @@ func (check *checker) unary(x *operand, op token.Token) { typ := x.typ.Underlying().(*Basic) size := -1 if isUnsigned(typ) { - size = int(check.ctxt.sizeof(typ)) + size = int(check.conf.sizeof(typ)) } x.val = exact.UnaryOp(op, x.val, size) // Typed constants must be representable in @@ -154,7 +155,7 @@ func isComparison(op token.Token) bool { return false } -func isRepresentableConst(x exact.Value, ctxt *Context, as BasicKind) bool { +func isRepresentableConst(x exact.Value, conf *Config, as BasicKind) bool { switch x.Kind() { case exact.Unknown: return true @@ -166,7 +167,7 @@ func isRepresentableConst(x exact.Value, ctxt *Context, as BasicKind) bool { if x, ok := exact.Int64Val(x); ok { switch as { case Int: - var s = uint(ctxt.sizeof(Typ[as])) * 8 + var s = uint(conf.sizeof(Typ[as])) * 8 return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1 case Int8: const s = 8 @@ -180,7 +181,7 @@ func isRepresentableConst(x exact.Value, ctxt *Context, as BasicKind) bool { case Int64: return true case Uint, Uintptr: - if s := uint(ctxt.sizeof(Typ[as])) * 8; s < 64 { + if s := uint(conf.sizeof(Typ[as])) * 8; s < 64 { return 0 <= x && x <= int64(1)<= 0 && n <= int(s) case Uint64: return exact.Sign(x) >= 0 && n <= 64 @@ -270,7 +271,7 @@ func (check *checker) isRepresentable(x *operand, typ *Basic) { return } - if !isRepresentableConst(x.val, check.ctxt, typ.kind) { + if !isRepresentableConst(x.val, check.conf, typ.kind) { var msg string if isNumeric(x.typ) && isNumeric(typ) { msg = "%s overflows (or cannot be accurately represented as) %s" @@ -287,7 +288,7 @@ func (check *checker) isRepresentable(x *operand, typ *Basic) { // If typ is still an untyped and not the final type, updateExprType // only updates the recorded untyped type for x and possibly its // operands. Otherwise (i.e., typ is not an untyped type anymore, -// or it is the final type for x), Context.Expr is invoked, if present. +// or it is the final type for x), the type and value are recorded. // Also, if x is a constant, it must be representable as a value of typ, // and if x is the (formerly untyped) lhs operand of a non-constant // shift, it must be an integer value. @@ -469,7 +470,7 @@ func (check *checker) comparison(x, y *operand, op token.Token) { // TODO(gri) deal with interface vs non-interface comparison valid := false - if x.isAssignableTo(check.ctxt, y.typ) || y.isAssignableTo(check.ctxt, x.typ) { + if x.isAssignableTo(check.conf, y.typ) || y.isAssignableTo(check.conf, x.typ) { switch op { case token.EQL, token.NEQ: valid = isComparable(x.typ) || @@ -779,10 +780,6 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type) { case constant: typ = x.typ val = x.val - case typexprn: - x.mode = typexpr - typ = x.typ - record = false // type was already recorded default: typ = x.typ } @@ -1220,8 +1217,13 @@ func (check *checker) expr0(x *operand, e ast.Expr, hint Type) { case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: - x.mode = typexprn // not typexpr; Context.Expr callback was invoked by check.typ + x.mode = typexpr x.typ = check.typ(e, nil, false) + // Note: rawExpr (caller of expr0) will call check.recordTypeAndValue + // even though check.typ has already called it. This is fine as both + // times the same expression and type are recorded. It is also not a + // performance issue because we only reach here for composite literal + // types, which are comparatively rare. default: if debug { diff --git a/go/types/issues_test.go b/go/types/issues_test.go index 3b521e1a..e55c300e 100644 --- a/go/types/issues_test.go +++ b/go/types/issues_test.go @@ -46,9 +46,9 @@ var ( return } - var ctxt Context + var conf Config types := make(map[ast.Expr]Type) - _, err = ctxt.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types}) + _, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types}) if err != nil { t.Error(err) } diff --git a/go/types/methodset.go b/go/types/methodset.go index 83fa3ec0..783450cc 100644 --- a/go/types/methodset.go +++ b/go/types/methodset.go @@ -14,6 +14,7 @@ import ( ) // TODO(gri) Move Method and accessors to objects.go. +// TODO(gri) Method.Type() returns the wrong receiver type. // A Method represents a concrete or abstract (interface) // method of a method set. diff --git a/go/types/operand.go b/go/types/operand.go index f713a9ac..a7e82c62 100644 --- a/go/types/operand.go +++ b/go/types/operand.go @@ -22,7 +22,6 @@ const ( invalid operandMode = iota // operand is invalid novalue // operand represents no value (result of a function call w/o result) typexpr // operand is a type - typexprn // like typexpr; only used to communicate between checker.expr0 and checker.rawExpr constant // operand is a constant; the operand's typ is a Basic type variable // operand is an addressable variable value // operand is a computed value @@ -33,7 +32,6 @@ var operandModeString = [...]string{ invalid: "invalid", novalue: "no value", typexpr: "type", - typexprn: "type/n", constant: "constant", variable: "variable", value: "value", @@ -127,7 +125,7 @@ func (x *operand) isNil() bool { // overlapping in functionality. Need to simplify and clean up. // isAssignableTo reports whether x is assignable to a variable of type T. -func (x *operand) isAssignableTo(ctxt *Context, T Type) bool { +func (x *operand) isAssignableTo(conf *Config, T Type) bool { if x.mode == invalid || T == Typ[Invalid] { return true // avoid spurious errors } @@ -186,7 +184,7 @@ func (x *operand) isAssignableTo(ctxt *Context, T Type) bool { switch t := Tu.(type) { case *Basic: if x.mode == constant { - return isRepresentableConst(x.val, ctxt, t.kind) + return isRepresentableConst(x.val, conf, t.kind) } // The result of a comparison is an untyped boolean, // but may not be a constant. @@ -207,5 +205,5 @@ func (x *operand) isAssignableTo(ctxt *Context, T Type) bool { func (x *operand) isInteger() bool { return x.mode == invalid || isInteger(x.typ) || - x.mode == constant && isRepresentableConst(x.val, nil, UntypedInt) // no context required for UntypedInt + x.mode == constant && isRepresentableConst(x.val, nil, UntypedInt) // no *Config required for UntypedInt } diff --git a/go/types/resolver.go b/go/types/resolver.go index 11011830..acbf4fc1 100644 --- a/go/types/resolver.go +++ b/go/types/resolver.go @@ -86,14 +86,14 @@ func (check *checker) arityMatch(s, init *ast.ValueSpec) { func (check *checker) resolveFiles(files []*ast.File) { pkg := check.pkg - // Phase 1: Pre-declare all package scope objects so that they can be found - // when type-checking package objects. + // Phase 1: Pre-declare all package-level objects so that they can be found + // independent of source order. var scopes []*Scope // corresponding file scope per file var objList []Object var objMap = make(map[Object]*decl) var methods []*mdecl - var fileScope *Scope // current file scope, used by collect + var fileScope *Scope // current file scope, used by declare declare := func(ident *ast.Ident, obj Object, typ, init ast.Expr) { assert(ident.Name == obj.Name()) @@ -118,7 +118,7 @@ func (check *checker) resolveFiles(files []*ast.File) { objMap[obj] = &decl{fileScope, typ, init} } - importer := check.ctxt.Import + importer := check.conf.Import if importer == nil { importer = GcImport } @@ -146,7 +146,7 @@ func (check *checker) resolveFiles(files []*ast.File) { path, _ := strconv.Unquote(s.Path.Value) imp, err := importer(pkg.imports, path) if imp == nil && err == nil { - err = errors.New("Context.Import returned nil") + err = errors.New("Config.Import returned nil") } if err != nil { check.errorf(s.Path.Pos(), "could not import %s (%s)", path, err) diff --git a/go/types/resolver_test.go b/go/types/resolver_test.go index 58b9a22e..bb1ed913 100644 --- a/go/types/resolver_test.go +++ b/go/types/resolver_test.go @@ -67,9 +67,9 @@ func TestResolveIdents(t *testing.T) { } // resolve and type-check package AST - var ctxt Context + var conf Config idents := make(map[*ast.Ident]Object) - pkg, err := ctxt.Check("testResolveIdents", fset, files, &Info{Objects: idents}) + pkg, err := conf.Check("testResolveIdents", fset, files, &Info{Objects: idents}) if err != nil { t.Fatal(err) } @@ -103,7 +103,7 @@ func TestResolveIdents(t *testing.T) { }) } - // check that each identifier in the source is enumerated by the Context.Ident callback + // check that each identifier in the source is found in the idents map for _, f := range files { ast.Inspect(f, func(n ast.Node) bool { if x, ok := n.(*ast.Ident); ok { diff --git a/go/types/sizes.go b/go/types/sizes.go index 6d1ab2e0..90cb832c 100644 --- a/go/types/sizes.go +++ b/go/types/sizes.go @@ -6,29 +6,29 @@ package types -func (ctxt *Context) alignof(typ Type) int64 { - if f := ctxt.Alignof; f != nil { +func (conf *Config) alignof(typ Type) int64 { + if f := conf.Alignof; f != nil { if a := f(typ); a >= 1 { return a } - panic("Context.Alignof returned an alignment < 1") + panic("Config.Alignof returned an alignment < 1") } return DefaultAlignof(typ) } -func (ctxt *Context) offsetsof(s *Struct) []int64 { +func (conf *Config) offsetsof(s *Struct) []int64 { offsets := s.offsets if offsets == nil && s.NumFields() > 0 { // compute offsets on demand - if f := ctxt.Offsetsof; f != nil { + if f := conf.Offsetsof; f != nil { offsets = f(s.fields) // sanity checks if len(offsets) != s.NumFields() { - panic("Context.Offsetsof returned the wrong number of offsets") + panic("Config.Offsetsof returned the wrong number of offsets") } for _, o := range offsets { if o < 0 { - panic("Context.Offsetsof returned an offset < 0") + panic("Config.Offsetsof returned an offset < 0") } } } else { @@ -42,22 +42,22 @@ func (ctxt *Context) offsetsof(s *Struct) []int64 { // offsetof returns the offset of the field specified via // the index sequence relative to typ. All embedded fields // must be structs (rather than pointer to structs). -func (ctxt *Context) offsetof(typ Type, index []int) int64 { +func (conf *Config) offsetof(typ Type, index []int) int64 { var o int64 for _, i := range index { s := typ.Underlying().(*Struct) - o += ctxt.offsetsof(s)[i] + o += conf.offsetsof(s)[i] typ = s.fields[i].typ } return o } -func (ctxt *Context) sizeof(typ Type) int64 { - if f := ctxt.Sizeof; f != nil { +func (conf *Config) sizeof(typ Type) int64 { + if f := conf.Sizeof; f != nil { if s := f(typ); s >= 0 { return s } - panic("Context.Sizeof returned a size < 0") + panic("Config.Sizeof returned a size < 0") } return DefaultSizeof(typ) } @@ -67,7 +67,7 @@ func (ctxt *Context) sizeof(typ Type) int64 { const DefaultMaxAlign = 8 // DefaultAlignof implements the default alignment computation -// for unsafe.Alignof. It is used if Context.Alignof == nil. +// for unsafe.Alignof. It is used if Config.Alignof == nil. func DefaultAlignof(typ Type) int64 { // For arrays and structs, alignment is defined in terms // of alignment of the elements and fields, respectively. @@ -106,7 +106,7 @@ func align(x, a int64) int64 { } // DefaultOffsetsof implements the default field offset computation -// for unsafe.Offsetof. It is used if Context.Offsetsof == nil. +// for unsafe.Offsetof. It is used if Config.Offsetsof == nil. func DefaultOffsetsof(fields []*Field) []int64 { offsets := make([]int64, len(fields)) var o int64 @@ -124,7 +124,7 @@ func DefaultOffsetsof(fields []*Field) []int64 { const DefaultPtrSize = 8 // DefaultSizeof implements the default size computation -// for unsafe.Sizeof. It is used if Context.Sizeof == nil. +// for unsafe.Sizeof. It is used if Config.Sizeof == nil. func DefaultSizeof(typ Type) int64 { switch t := typ.Underlying().(type) { case *Basic: diff --git a/go/types/stdlib_test.go b/go/types/stdlib_test.go index 552ea115..71d165a3 100644 --- a/go/types/stdlib_test.go +++ b/go/types/stdlib_test.go @@ -72,9 +72,9 @@ func typecheck(t *testing.T, path string, filenames []string) { } // typecheck package files - var ctxt Context - ctxt.Error = func(err error) { t.Error(err) } - ctxt.Check(path, fset, files, nil) + var conf Config + conf.Error = func(err error) { t.Error(err) } + conf.Check(path, fset, files, nil) pkgCount++ } diff --git a/importer/importer.go b/importer/importer.go index d7b09b4f..099dadd4 100644 --- a/importer/importer.go +++ b/importer/importer.go @@ -30,7 +30,7 @@ type Context struct { // The Importer will override any user-supplied values for its // Expr, Ident, ImplicitObj and Import fields; other fields // will be passed through to the type checker. - TypeChecker types.Context + TypeChecker types.Config // If Loader is non-nil, it is used to satisfy imports. //