// debugging/development support
const debug = false // leave on during development
+// position tracing for panics during type checking
+const tracePos = false // TODO(markfreeman): check performance implications
+
// _aliasAny changes the behavior of [Scope.Lookup] for "any" in the
// [Universe] scope.
//
environment
// debugging
- indent int // indentation for tracing
+ posStack []syntax.Pos // stack of source positions seen; used for panic tracing
+ indent int // indentation for tracing
}
// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
return b
}
+// pushPos pushes pos onto the pos stack.
+func (check *Checker) pushPos(pos syntax.Pos) {
+ check.posStack = append(check.posStack, pos)
+}
+
+// popPos pops from the pos stack.
+func (check *Checker) popPos() {
+ check.posStack = check.posStack[:len(check.posStack)-1]
+}
+
// A bailout panic is used for early termination.
type bailout struct{}
// normal return or early exit
*err = check.firstErr
default:
+ // TODO(markfreeman): dump posStack if available
// re-panic
panic(p)
}
// 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 *TypeName) {
+ if tracePos {
+ check.pushPos(obj.Pos())
+ defer func() {
+ // If we're panicking, keep stack of source positions.
+ if p := recover(); p != nil {
+ panic(p)
+ }
+ check.popPos()
+ }()
+ }
+
if check.conf.Trace && obj.Type() == nil {
if check.indent == 0 {
fmt.Println() // empty line between top-level objects for readability
// debugging/development support
const debug = false // leave on during development
+// position tracing for panics during type checking
+const tracePos = false // TODO(markfreeman): check performance implications
+
// gotypesalias controls the use of Alias types.
// As of Apr 16 2024 they are used by default.
// To disable their use, set GODEBUG to gotypesalias=0.
environment
// debugging
- indent int // indentation for tracing
+ posStack []positioner // stack of source positions seen; used for panic tracing
+ indent int // indentation for tracing
}
// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
return a
}
+// pushPos pushes pos onto the pos stack.
+func (check *Checker) pushPos(pos positioner) {
+ check.posStack = append(check.posStack, pos)
+}
+
+// popPos pops from the pos stack.
+func (check *Checker) popPos() {
+ check.posStack = check.posStack[:len(check.posStack)-1]
+}
+
// A bailout panic is used for early termination.
type bailout struct{}
// normal return or early exit
*err = check.firstErr
default:
+ // TODO(markfreeman): dump posStack if available
// re-panic
panic(p)
}
// 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 *TypeName) {
+ if tracePos {
+ check.pushPos(atPos(obj.Pos()))
+ defer func() {
+ // If we're panicking, keep stack of source positions.
+ if p := recover(); p != nil {
+ panic(p)
+ }
+ check.popPos()
+ }()
+ }
+
if check.conf._Trace && obj.Type() == nil {
if check.indent == 0 {
fmt.Println() // empty line between top-level objects for readability