From 1899472647513e6a63a95481493c45c579ec0cd8 Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Mon, 18 Apr 2022 16:47:42 -0400 Subject: go/types: remove unnecessary indirection when reporting errors Checker.err was only called to report errors created with Checker.newError or Checker.newErrorf. Update the API to pass around *Error rather than error, eliminating unnecessary type assertions and handling. Change-Id: I995a120c7e87266e656b8ff3fd9ed3d368fd17fc Reviewed-on: https://go-review.googlesource.com/c/go/+/400823 Run-TryBot: Robert Findley TryBot-Result: Gopher Robot Reviewed-by: Robert Griesemer --- src/go/types/api.go | 6 +++--- src/go/types/errors.go | 51 +++++++++++++++++++++----------------------------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/go/types/api.go b/src/go/types/api.go index 4f63d627130..0915d6a6eee 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -414,9 +414,9 @@ func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, i // AssertableTo reports whether a value of type V can be asserted to have type T. // // The behavior of AssertableTo is undefined in two cases: -// - if V is a generalized interface; i.e., an interface that may only be used -// as a type constraint in Go code -// - if T is an uninstantiated generic type +// - if V is a generalized interface; i.e., an interface that may only be used +// as a type constraint in Go code +// - if T is an uninstantiated generic type func AssertableTo(V *Interface, T Type) bool { // Checker.newAssertableTo suppresses errors for invalid types, so we need special // handling here. diff --git a/src/go/types/errors.go b/src/go/types/errors.go index fade8630e09..c40a8436c51 100644 --- a/src/go/types/errors.go +++ b/src/go/types/errors.go @@ -8,7 +8,6 @@ package types import ( "bytes" - "errors" "fmt" "go/ast" "go/token" @@ -140,36 +139,32 @@ func (check *Checker) dump(format string, args ...any) { fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...)) } -func (check *Checker) err(err error) { - if err == nil { - return - } - var e Error - isInternal := errors.As(err, &e) +// Report records the error pointed to by errp, setting check.firstError if +// necessary. +func (check *Checker) report(errp *Error) { + e := *errp // Cheap trick: Don't report errors with messages containing // "invalid operand" or "invalid type" as those tend to be // follow-on errors which don't add useful information. Only // exclude them if these strings are not at the beginning, // and only if we have at least one error already reported. - isInvalidErr := isInternal && (strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0) + isInvalidErr := strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0 if check.firstErr != nil && isInvalidErr { return } - if isInternal { - e.Msg = stripAnnotations(e.Msg) - if check.errpos != nil { - // If we have an internal error and the errpos override is set, use it to - // augment our error positioning. - // TODO(rFindley) we may also want to augment the error message and refer - // to the position (pos) in the original expression. - span := spanOf(check.errpos) - e.Pos = span.pos - e.go116start = span.start - e.go116end = span.end - } - err = e + e.Msg = stripAnnotations(e.Msg) + if check.errpos != nil { + // If we have an internal error and the errpos override is set, use it to + // augment our error positioning. + // TODO(rFindley) we may also want to augment the error message and refer + // to the position (pos) in the original expression. + span := spanOf(check.errpos) + e.Pos = span.pos + e.go116start = span.start + e.go116end = span.end } + err := e if check.firstErr == nil { check.firstErr = err @@ -178,10 +173,6 @@ func (check *Checker) err(err error) { if trace { pos := e.Pos msg := e.Msg - if !isInternal { - msg = err.Error() - pos = token.NoPos - } check.trace(pos, "ERROR: %s", msg) } @@ -192,9 +183,9 @@ func (check *Checker) err(err error) { f(err) } -func (check *Checker) newError(at positioner, code errorCode, soft bool, msg string) error { +func (check *Checker) newError(at positioner, code errorCode, soft bool, msg string) *Error { span := spanOf(at) - return Error{ + return &Error{ Fset: check.fset, Pos: span.pos, Msg: msg, @@ -206,13 +197,13 @@ func (check *Checker) newError(at positioner, code errorCode, soft bool, msg str } // newErrorf creates a new Error, but does not handle it. -func (check *Checker) newErrorf(at positioner, code errorCode, soft bool, format string, args ...any) error { +func (check *Checker) newErrorf(at positioner, code errorCode, soft bool, format string, args ...any) *Error { msg := check.sprintf(format, args...) return check.newError(at, code, soft, msg) } func (check *Checker) error(at positioner, code errorCode, msg string) { - check.err(check.newError(at, code, false, msg)) + check.report(check.newError(at, code, false, msg)) } func (check *Checker) errorf(at positioner, code errorCode, format string, args ...any) { @@ -220,7 +211,7 @@ func (check *Checker) errorf(at positioner, code errorCode, format string, args } func (check *Checker) softErrorf(at positioner, code errorCode, format string, args ...any) { - check.err(check.newErrorf(at, code, true, format, args...)) + check.report(check.newErrorf(at, code, true, format, args...)) } func (check *Checker) invalidAST(at positioner, format string, args ...any) { -- cgit v1.2.3