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 <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2023-01-09 13:02:08 -08:00 committed by Gopher Robot
parent 839c842550
commit 4210ebcd08
12 changed files with 25 additions and 23 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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()
}
}

View File

@ -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.<name>.
// 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

View File

@ -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):])
}

View File

@ -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)

View File

@ -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() {

View File

@ -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() {

View File

@ -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)
}

View File

@ -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--

View File

@ -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.

View File

@ -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() {