Description
For the AST (but also other visitors in the compiler), visitor functions typically come in two flavors:
visit_X
- Overrideable part of the trait invocation. If you override it, you should callwalk_X
if you want to recurse or dovisit_Y
calls on the sub-components (for some otherY
) you want to walk into, skipping the rest.walk_X
- Non-overrideable, free function which actually recurses on the structure by callingvisit_Y
on all of the sub-components (for some otherY
) of the thing. Sometimes this is calledsuper_visit_X
.
It is typically a bug to call walk_Y
on a sub-component within a visit_X
invocation. For example, see:
Which fixed a bug where we called walk_expr
on the async closure's body when visiting the async closure in visit_fn
. This should've been a visit_expr
, since visit_expr
had meaningful side-effects (collecting macro invocations).
We should have some sort of lint to prevent this pattern outside of regular visit_X
-> walk_X
situation, and compiler devs who need to do something special can do #[allow(whatever_lint_name_for_sketchy_visitor_pattern)]
to justify that what they're doing is okay. We already have some comments that document when this happens (I think, I feel like I've seen them around), but it can be done by accident which causes bugs!