Description
The type checker go/types
records various facts about well-typed trees. For example, Uses
records the relationship between each "using" (non-defining) identifier and the object to which it refers. However, when the type checker detects certain kinds of errors, it does not attempt to record facts about the errant subtree. This issue is a request that it work harder to record facts about errant subtrees.
By way of motivation, consider a tool for generating completions in an IDE. The input to such a tool is an unsaved editor buffer that usually fails to type-check, but the tool must nonetheless extract type information from the partial tree. Consider the following fragment of a Go program in an unsaved editor buffer, with the current insertion point marked by a caret:
func _() {
fmt.⁁
test := 0
}
A completion tool should generate a list of qualified identifiers such as fmt.Print, fmt.Fprintf, and so on. The parser ignores the newline and generates a tree containing fmt.test := 0
, for which the type checker emits an error because each operand on the left of :=
must be an identifier, not a qualified identifier (*ast.SelectorExpr). Having emitted the error, the type checker does not then visit the LHS subtree, so no Uses
fact is recorded for fmt
. As a result, the completion tool simply doesn't work on programs of this form, which are fairly common.
The fix in this specific example is for the type checker, once it has reported the error, to visit the left subtree for side effects (facts) only, and ignore the resulting type. The more general problem is to find any other places in the type checker that skip visitation of a subtree after an error.