Module intravisit

Source
Expand description

HIR walker for walking the contents of nodes.

Here are the three available patterns for the visitor strategy, in roughly the order of desirability:

  1. Shallow visit: Get a simple callback for every item (or item-like thing) in the HIR.
    • Example: find all items with a #[foo] attribute on them.
    • How: Use the hir_crate_items or hir_module_items query to traverse over item-like ids (ItemId, TraitItemId, etc.) and use tcx.def_kind and tcx.hir().item*(id) to filter and access actual item-like thing, respectively.
    • Pro: Efficient; just walks the lists of item ids and gives users control whether to access the hir_owners themselves or not.
    • Con: Don’t get information about nesting
    • Con: Don’t have methods for specific bits of HIR, like “on every expr, do this”.
  2. Deep visit: Want to scan for specific kinds of HIR nodes within an item, but don’t care about how item-like things are nested within one another.
    • Example: Examine each expression to look for its type and do some check or other.
    • How: Implement intravisit::Visitor and override the NestedFilter type to nested_filter::OnlyBodies (and implement nested_visit_map), and use tcx.hir().visit_all_item_likes_in_crate(&mut visitor). Within your intravisit::Visitor impl, implement methods like visit_expr() (don’t forget to invoke intravisit::walk_expr() to keep walking the subparts).
    • Pro: Visitor methods for any kind of HIR node, not just item-like things.
    • Pro: Integrates well into dependency tracking.
    • Con: Don’t get information about nesting between items
  3. Nested visit: Want to visit the whole HIR and you care about the nesting between item-like things.
    • Example: Lifetime resolution, which wants to bring lifetimes declared on the impl into scope while visiting the impl-items, and then back out again.
    • How: Implement intravisit::Visitor and override the NestedFilter type to nested_filter::All (and implement nested_visit_map). Walk your crate with tcx.hir().walk_toplevel_module(visitor) invoked on tcx.hir().krate().
    • Pro: Visitor methods for any kind of HIR node, not just item-like things.
    • Pro: Preserves nesting information
    • Con: Does not integrate well into dependency tracking.

If you have decided to use this visitor, here are some general notes on how to do so:

Each overridden visit method has full control over what happens with its node, it can do its own traversal of the node’s children, call intravisit::walk_* to apply the default traversal algorithm, or prevent deeper traversal by doing nothing.

When visiting the HIR, the contents of nested items are NOT visited by default. This is different from the AST visitor, which does a deep walk. Hence this module is called intravisit; see the method visit_nested_item for more details.

Note: it is an important invariant that the default visitor walks the body of a function in “execution order” - more concretely, if we consider the reverse post-order (RPO) of the CFG implied by the HIR, then a pre-order traversal of the HIR is consistent with the CFG RPO on the initial CFG point of each HIR node, while a post-order traversal of the HIR is consistent with the CFG RPO on each final CFG point of each CFG node.

One thing that follows is that if HIR node A always starts/ends executing before HIR node B, then A appears in traversal pre/postorder before B, respectively. (This follows from RPO respecting CFG domination).

This order consistency is required in a few places in rustc, for example coroutine inference, and possibly also HIR borrowck.

Modules§

nested_filter

Enums§

FnKind
InferKind
We track whether an infer var is from a Ty, ConstArg, or GenericArg so that HIR visitors overriding Visitor::visit_infer can determine what kind of infer is being visited

Traits§

IntoVisitor
Map
An abstract representation of the HIR rustc_middle::hir::map::Map.
Visitor
Each method of the Visitor trait is a hook to be potentially overridden. Each method’s default implementation recursively visits the substructure of the input via the corresponding walk method; e.g., the visit_mod method by default calls intravisit::walk_mod.
VisitorExt

Functions§

walk_ambig_const_arg
walk_anon_const
walk_arm
walk_assoc_item_constraint
walk_associated_item_kind
walk_block
walk_body
walk_const_arg
walk_const_param_default
walk_defaultness
walk_enum_def
walk_expr
walk_expr_field
walk_field_def
walk_fn
walk_fn_decl
walk_fn_kind
walk_fn_ret_ty
walk_foreign_item
walk_foreign_item_ref
walk_generic_arg
walk_generic_args
walk_generic_param
walk_generics
walk_ident
walk_impl_item
walk_impl_item_ref
walk_inf
walk_inline_asm
walk_inline_const
walk_item
walk_label
walk_lifetime
walk_local
walk_mod
walk_opaque_ty
walk_param
walk_param_bound
walk_pat
walk_pat_expr
walk_pat_field
walk_path
walk_path_segment
walk_poly_trait_ref
walk_precise_capturing_arg
walk_qpath
walk_stmt
walk_struct_def
walk_trait_item
walk_trait_item_ref
walk_trait_ref
walk_ty
walk_ty_pat
walk_unambig_ty
walk_use
walk_variant
walk_where_predicate