From: Robert Griesemer Date: Mon, 9 Jan 2023 21:02:08 +0000 (-0800) Subject: go/types: make tracing configurable (matching types2) X-Git-Tag: go1.21rc1~1925 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4210ebcd089f216798152b5e523eaa71fbefe65d;p=gostls13.git go/types: make tracing configurable (matching types2) This CL replaces the internal trace flag with Config.trace. While unexported, it can still be set for testing via reflection. The typical use is for manual tests, where -v (verbose) turns on tracing output. Typical use: go test -run Manual -v This change makes go/types match types2 behavior. Change-Id: I22842f4bba8fd632efe5929c950f4b1cab0a8569 Reviewed-on: https://go-review.googlesource.com/c/go/+/461081 TryBot-Result: Gopher Robot Run-TryBot: Robert Griesemer Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer Reviewed-by: Robert Findley --- diff --git a/src/go/types/api.go b/src/go/types/api.go index eda41b366a..d9d561c25d 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -143,6 +143,9 @@ type Config struct { // It is an error to set both FakeImportC and go115UsesCgo. go115UsesCgo bool + // If trace is set, a debug trace is printed to stdout. + trace bool + // If Error != nil, it is called with each error found // during type checking; err has dynamic type Error. // Secondary errors (for instance, to enumerate all types diff --git a/src/go/types/call.go b/src/go/types/call.go index db603b5260..f0d612d018 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -65,7 +65,7 @@ func (check *Checker) instantiateSignature(pos token.Pos, typ *Signature, targs assert(check != nil) assert(len(targs) == typ.TypeParams().Len()) - if trace { + if check.conf.trace { check.trace(pos, "-- instantiating signature %s with %s", typ, targs) check.indent++ defer func() { diff --git a/src/go/types/check.go b/src/go/types/check.go index 50d8afe4e3..76be498042 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -16,10 +16,7 @@ import ( ) // debugging/development support -const ( - debug = false // leave on during development - trace = false // turn on for detailed type resolution traces -) +const debug = false // leave on during development // exprInfo stores information about an untyped expression. type exprInfo struct { @@ -313,7 +310,7 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) { defer check.handleBailout(&err) print := func(msg string) { - if trace { + if check.conf.trace { fmt.Println() fmt.Println(msg) } @@ -377,7 +374,7 @@ func (check *Checker) processDelayed(top int) { // this is a sufficiently bounded process. for i := top; i < len(check.delayed); i++ { a := &check.delayed[i] - if trace { + if check.conf.trace { if a.desc != nil { check.trace(a.desc.pos.Pos(), "-- "+a.desc.format, a.desc.args...) } else { @@ -385,7 +382,7 @@ func (check *Checker) processDelayed(top int) { } } a.f() // may append to check.delayed - if trace { + if check.conf.trace { fmt.Println() } } diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index 638355049e..1107f9592a 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -145,7 +145,7 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man flags := flag.NewFlagSet("", flag.PanicOnError) flags.StringVar(&conf.GoVersion, "lang", "", "") flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "") - flags.BoolVar(addrOldComparableSemantics(&conf), "oldComparableSemantics", false, "") + flags.BoolVar(boolFieldAddr(&conf, "oldComparableSemantics"), "oldComparableSemantics", false, "") if err := parseFlags(filenames[0], srcs[0], flags); err != nil { t.Fatal(err) } @@ -166,6 +166,7 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man } // typecheck and collect typechecker errors + *boolFieldAddr(&conf, "trace") = manual && testing.Verbose() if imp == nil { imp = importer.Default() } @@ -299,10 +300,11 @@ func readCode(err Error) int { return int(v.FieldByName("go116code").Int()) } -// addrOldComparableSemantics(conf) returns &conf.oldComparableSemantics (unexported field). -func addrOldComparableSemantics(conf *Config) *bool { +// boolFieldAddr(conf, name) returns the address of the boolean field conf.. +// For accessing unexported fields. +func boolFieldAddr(conf *Config, name string) *bool { v := reflect.Indirect(reflect.ValueOf(conf)) - return (*bool)(v.FieldByName("oldComparableSemantics").Addr().UnsafePointer()) + return (*bool)(v.FieldByName(name).Addr().UnsafePointer()) } // TestManual is for manual testing of a package - either provided diff --git a/src/go/types/decl.go b/src/go/types/decl.go index adc485c400..018ff7f38e 100644 --- a/src/go/types/decl.go +++ b/src/go/types/decl.go @@ -54,7 +54,7 @@ func pathString(path []Object) string { // objDecl type-checks the declaration of obj in its respective (file) environment. // For the meaning of def, see Checker.definedType, in typexpr.go. func (check *Checker) objDecl(obj Object, def *Named) { - if trace && obj.Type() == nil { + if check.conf.trace && obj.Type() == nil { if check.indent == 0 { fmt.Println() // empty line between top-level objects for readability } @@ -264,7 +264,7 @@ loop: } } - if trace { + if check.conf.trace { check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle)) if tparCycle { check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list") @@ -707,7 +707,7 @@ func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident tparams = append(tparams, tpar) } - if trace && len(names) > 0 { + if check.conf.trace && len(names) > 0 { check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):]) } diff --git a/src/go/types/errors.go b/src/go/types/errors.go index b52019ddf5..4c4cd03814 100644 --- a/src/go/types/errors.go +++ b/src/go/types/errors.go @@ -266,7 +266,7 @@ func (check *Checker) report(errp *error_) { check.firstErr = err } - if trace { + if check.conf.trace { pos := e.Pos msg := e.Msg check.trace(pos, "ERROR: %s", msg) diff --git a/src/go/types/expr.go b/src/go/types/expr.go index aa90145b36..adf3d21fce 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1224,7 +1224,7 @@ const ( // If allowGeneric is set, the operand type may be an uninstantiated // parameterized type or function value. func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind { - if trace { + if check.conf.trace { check.trace(e.Pos(), "-- expr %s", e) check.indent++ defer func() { diff --git a/src/go/types/named.go b/src/go/types/named.go index c08997aa77..04638abbdc 100644 --- a/src/go/types/named.go +++ b/src/go/types/named.go @@ -581,7 +581,7 @@ func (check *Checker) context() *Context { // returning the result. Returns Typ[Invalid] if there was an error. func (n *Named) expandUnderlying() Type { check := n.check - if check != nil && trace { + if check != nil && check.conf.trace { check.trace(n.obj.pos, "-- Named.expandUnderlying %s", n) check.indent++ defer func() { diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go index ac6255d42a..1a4c58888a 100644 --- a/src/go/types/stmt.go +++ b/src/go/types/stmt.go @@ -19,7 +19,7 @@ func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body panic("function body not ignored") } - if trace { + if check.conf.trace { check.trace(body.Pos(), "-- %s: %s", name, sig) } diff --git a/src/go/types/subst.go b/src/go/types/subst.go index 5a49c0447f..5876b61edf 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -204,7 +204,7 @@ func (subst *subster) typ(typ Type) Type { case *Named: // dump is for debugging dump := func(string, ...any) {} - if subst.check != nil && trace { + if subst.check != nil && subst.check.conf.trace { subst.check.indent++ defer func() { subst.check.indent-- diff --git a/src/go/types/typeset.go b/src/go/types/typeset.go index d68446df66..35fb155bfa 100644 --- a/src/go/types/typeset.go +++ b/src/go/types/typeset.go @@ -170,7 +170,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T return &topTypeSet } - if check != nil && trace { + if check != nil && check.conf.trace { // Types don't generally have position information. // If we don't have a valid pos provided, try to use // one close enough. diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 03817dded1..6a92dcb9b7 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -214,7 +214,7 @@ func goTypeName(typ Type) string { // typInternal drives type checking of types. // Must only be called by definedType or genericType. func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) { - if trace { + if check.conf.trace { check.trace(e0.Pos(), "-- type %s", e0) check.indent++ defer func() { @@ -395,7 +395,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) { } func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (res Type) { - if trace { + if check.conf.trace { check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices) check.indent++ defer func() {