Should AST node validation be tri-state?

It appears that the generic signature builder resolves types twice because the availability of the generic environment can influence diagnostics (see revertGenericFuncSignature() and its uses). This seems unfortunate and inefficient. Should AST node validation be tri-state? For example, default to "unknown", and allow one-way transitions to either "valid" or "invalid". Finally, assert in the AST verifier that all nodes are either valid or invalid. What do people think about this added level of discipline? Being "known valid" would let us bypass the redundant type resolving.

CC: @Douglas_Gregor

The need to have ‘revertGenericFuncSignature’ is really unfortunate. The problem stems from the fact that we record not-completely-type-checked types in the AST, then have to undo that to put the correct types in place. It can cause problems particularly when there are cyclic dependencies almost declarations.

I don’t think the right answer is to make the “validated” state tri-state, though. Instead, we should port this code path over to the request-evaluator, which has different queries depending on the level of information that’s required: “structural” type information that’s only about the shape of the types but is otherwise unchecked, “interface” type information that’s a fully-checked interface type, or “contextual” type information that describes the archetypes. The request-evaluator can keep these pieces of information separate, so there’s no need to “revert”.

5 Likes

Interesting. Good to know. What then is the preferred way to avoid redundant diagnostics in this scenario? Right now, my "resolveType()" changes assume that the code will be reinvoked if a GenericTypeParamType is involved AND the generic environment is null. Is this okay, or is there a better way?