New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
go/types, x/tools/gopls: improve the positioning of type checker errors #42290
Comments
Change https://golang.org/cl/264179 mentions this issue: |
Tools using go/types sometimes need to implement special handling for certain errors produced by the type-checker. They can offer suggested fixes, expand the error position to surrounding syntax, highlight related syntax (for example in the case of a declaration cycle), link to additional documentation, group errors by category, or correlate errors with signals produced by other static analysis tools. All these require a notion of error identity. Tools need to be able to reliably determine the nature of an error without re-implementing type checking logic or parsing error messages. This CL is a first-pass at adding such an identifier to types.Error: a (for the moment unexported) field containing one of many declared errorCode constants. A wide variety of error code constants are defined, and assigned to type checker errors according to their 'functional equivalence', meaning that they should be ideally be stable under refactoring. With few exceptions, each error code is documented with an example that produces it. This is enforced by tests. When error codes are exported they will represent quite a large API surface. For this reason, as well as the likelihood that error codes will change at the start, both the code field and the codes themselves are initially unexported. gopls will read these fields using reflection during this experimental phase. Others can obviously do the same, provided they accept the lack of forward compatibility. For #42290 Change-Id: I15e3c2bffd2046c20297b1857057d421f633098a Reviewed-on: https://go-review.googlesource.com/c/go/+/264179 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Robert Griesemer <gri@golang.org> Trust: Robert Findley <rfindley@google.com>
Change https://golang.org/cl/266637 mentions this issue: |
In CL 264179, some reorganization of error codes was deferred in order to minimize diffs between patch-sets. This CL reorganizes the error codes as discussed. It is a pure reordering, with no material changes other than the changing of internal const values. For #42290 Change-Id: I0e9b421a92e96b19e53039652f8de898c5255290 Reviewed-on: https://go-review.googlesource.com/c/go/+/266637 Run-TryBot: Robert Findley <rfindley@google.com> Trust: Robert Findley <rfindley@google.com> Trust: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Change https://golang.org/cl/265250 mentions this issue: |
Tools often need to associate errors not with a single position, but with a span of source code. For example, gopls currently estimates diagnostic spans using heuristics to expand the positions reported by the type checker to surrounding source code. Unfortunately this is often inaccurate. This CL lays the groundwork to solve this within go/types by adding a start and end position to type checker errors. This is an experimental API, both because we are uncertain of the ideal representation for these spans and because their initial positioning is naive. In most cases this CL simply expands errors to the surrounding ast.Node being typechecked, if available. This might not be the best error span to present to the user. For these reasons the API is unexported -- gopls can read these positions using reflection, allowing us to gain experience and improve them during the next development cycle. For #42290 Change-Id: I39a04d70ea2bb2134b4d4c937f32b2ddb4456430 Reviewed-on: https://go-review.googlesource.com/c/go/+/265250 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Robert Findley <rfindley@google.com> Trust: Robert Griesemer <gri@golang.org>
Change https://golang.org/cl/267939 mentions this issue: |
Change https://golang.org/cl/268539 mentions this issue: |
This CL adds a copy of the internal error codes added to go/types in https://golang.org/cl/264179. In a subsequent CL, we will use these to extract the unexported error code from go/types errors via reflection. A generated String method is added to provide a human-readable code for the user. For golang/go#42290 Change-Id: I280c9b111598426dce4eef38b9979919ed590068 Reviewed-on: https://go-review.googlesource.com/c/tools/+/267939 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
In Go 1.16 error codes as well as start and end positions are added for go/types errors. This information is temporarily stored in unexported fields, until we're more confident in the correctness of both the API and the underlying data. Read this information using reflection and, if available, use it to set the corresponding field in compiler diagnostics. This establishes a positive feedback loop: in most cases this should improve the gopls diagnostic, and wherever it doesn't we can make a note and fall back on the old heuristics for that error code. For golang/go#42290 Change-Id: I37475189cbd14a0a5bcfde163f599c9a7b957372 Reviewed-on: https://go-review.googlesource.com/c/tools/+/268539 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> Trust: Robert Findley <rfindley@google.com> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
In Go 1.16 error codes as well as start and end positions are added for go/types errors. This information is temporarily stored in unexported fields, until we're more confident in the correctness of both the API and the underlying data. Read this information using reflection and, if available, use it to set the corresponding field in compiler diagnostics. This establishes a positive feedback loop: in most cases this should improve the gopls diagnostic, and wherever it doesn't we can make a note and fall back on the old heuristics for that error code. For golang/go#42290 Change-Id: I37475189cbd14a0a5bcfde163f599c9a7b957372 Reviewed-on: https://go-review.googlesource.com/c/tools/+/268539 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> Trust: Robert Findley <rfindley@google.com> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
I'm going to close this as the main requirement has been met, and follow-on work should be tracked in separate issues: go/types records both error code and span, and gopls reads this information to provide better context for errors. Two issues are still unresolved:
|
This issue tracks work in both go/types and gopls to improve the position information associated with type checker errors.
Errors produced by go/types currently consist (mostly) of an error message and a position in the source. Related errors are grouped by prefixing continuation errors with
\t
. This works well for command-line applications, but causes problems for gopls when presenting these errors as diagnostics in the editor.Specifically:
var _ = int(1) + int64(1)
, gopls will put the error under justint(1)
, even though the problem is that the entire RHS expression has mismatching types.\tT2 refers to
, which gopls sends to the editor as diagnostics. Absent context, these are nonsensical.func f() int {}
, the error is on the ‘}’, as that is the first token where a ‘missing return’ error is known. But for the user it might be clearer to position this error on the function signature -- the mistake could equally well be an extraneous result parameter.There are two limitations of
types.Error
preventing gopls from addressing these problems in a robust way. First, a single position is not sufficient to accurately determine the span of syntax that led to an error. Second, with only a plain-text message gopls cannot reliably identify the error, and therefore cannot implement an optimal UX for each error kind.After discussing with @griesemer the tentative plan is to
types.Error
, identifying its kind.types.Error
, defining its syntactic extent.We’re still not sure what the correct API is for these, but we’d like to at least start defining error codes internally for 1.16 (CL 264179).
I'm opening this issue to track that work, as well as any progress we make on defining the API.
The text was updated successfully, but these errors were encountered: