1
Fork 0

Update intravisit docs

This commit is contained in:
Cameron Steffen 2022-04-30 12:27:01 -05:00
parent d201c812d4
commit 61ba32b768
2 changed files with 35 additions and 35 deletions

View file

@ -163,10 +163,15 @@ impl<'hir> Map<'hir> for ! {
pub mod nested_filter { pub mod nested_filter {
use super::Map; use super::Map;
/// Specifies what nested things a visitor wants to visit. The most /// Specifies what nested things a visitor wants to visit. By "nested
/// common choice is `OnlyBodies`, which will cause the visitor to /// things", we are referring to bits of HIR that are not directly embedded
/// visit fn bodies for fns that it encounters, but skip over nested /// within one another but rather indirectly, through a table in the crate.
/// item-like things. /// This is done to control dependencies during incremental compilation: the
/// non-inline bits of HIR can be tracked and hashed separately.
///
/// The most common choice is `OnlyBodies`, which will cause the visitor to
/// visit fn bodies for fns that it encounters, and closure bodies, but
/// skip over nested item-like things.
/// ///
/// See the comments on `ItemLikeVisitor` for more details on the overall /// See the comments on `ItemLikeVisitor` for more details on the overall
/// visit strategy. /// visit strategy.
@ -217,27 +222,23 @@ use nested_filter::NestedFilter;
pub trait Visitor<'v>: Sized { pub trait Visitor<'v>: Sized {
// this type should not be overridden, it exists for convenient usage as `Self::Map` // this type should not be overridden, it exists for convenient usage as `Self::Map`
type Map: Map<'v> = <Self::NestedFilter as NestedFilter<'v>>::Map; type Map: Map<'v> = <Self::NestedFilter as NestedFilter<'v>>::Map;
type NestedFilter: NestedFilter<'v> = nested_filter::None;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Nested items. // Nested items.
/// The default versions of the `visit_nested_XXX` routines invoke /// Override this type to control which nested HIR are visited; see
/// this method to get a map to use. By selecting an enum variant, /// [`NestedFilter`] for details. If you override this type, you
/// you control which kinds of nested HIR are visited; see /// must also override [`nested_visit_map`](Self::nested_visit_map).
/// `NestedVisitorMap` for details. By "nested HIR", we are
/// referring to bits of HIR that are not directly embedded within
/// one another but rather indirectly, through a table in the
/// crate. This is done to control dependencies during incremental
/// compilation: the non-inline bits of HIR can be tracked and
/// hashed separately.
/// ///
/// **If for some reason you want the nested behavior, but don't /// **If for some reason you want the nested behavior, but don't
/// have a `Map` at your disposal:** then you should override the /// have a `Map` at your disposal:** then override the
/// `visit_nested_XXX` methods, and override this method to /// `visit_nested_XXX` methods. If a new `visit_nested_XXX` variant is
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is /// added in the future, it will cause a panic which can be detected
/// added in the future, we will see the panic in your code and /// and fixed appropriately.
/// fix it appropriately. type NestedFilter: NestedFilter<'v> = nested_filter::None;
/// If `type NestedFilter` is set to visit nested items, this method
/// must also be overridden to provide a map to retrieve nested items.
fn nested_visit_map(&mut self) -> Self::Map { fn nested_visit_map(&mut self) -> Self::Map {
panic!( panic!(
"nested_visit_map must be implemented or consider using \ "nested_visit_map must be implemented or consider using \
@ -245,14 +246,14 @@ pub trait Visitor<'v>: Sized {
); );
} }
/// Invoked when a nested item is encountered. By default does /// Invoked when a nested item is encountered. By default, when
/// nothing unless you override `nested_visit_map` to return other than /// `Self::NestedFilter` is `nested_filter::None`, this method does
/// `None`, in which case it will walk the item. **You probably /// nothing. **You probably don't want to override this method** --
/// don't want to override this method** -- instead, override /// instead, override [`Self::NestedFilter`] or use the "shallow" or
/// `nested_visit_map` or use the "shallow" or "deep" visit /// "deep" visit patterns described on
/// patterns described on `itemlikevisit::ItemLikeVisitor`. The only /// `itemlikevisit::ItemLikeVisitor`. The only reason to override
/// reason to override this method is if you want a nested pattern /// this method is if you want a nested pattern but cannot supply a
/// but cannot supply a `Map`; see `nested_visit_map` for advice. /// [`Map`]; see `nested_visit_map` for advice.
fn visit_nested_item(&mut self, id: ItemId) { fn visit_nested_item(&mut self, id: ItemId) {
if Self::NestedFilter::INTER { if Self::NestedFilter::INTER {
let item = self.nested_visit_map().item(id); let item = self.nested_visit_map().item(id);
@ -291,9 +292,8 @@ pub trait Visitor<'v>: Sized {
} }
/// Invoked to visit the body of a function, method or closure. Like /// Invoked to visit the body of a function, method or closure. Like
/// visit_nested_item, does nothing by default unless you override /// `visit_nested_item`, does nothing by default unless you override
/// `nested_visit_map` to return other than `None`, in which case it will walk /// `Self::NestedFilter`.
/// the body.
fn visit_nested_body(&mut self, id: BodyId) { fn visit_nested_body(&mut self, id: BodyId) {
if Self::NestedFilter::INTRA { if Self::NestedFilter::INTRA {
let body = self.nested_visit_map().body(id); let body = self.nested_visit_map().body(id);

View file

@ -17,8 +17,8 @@ use super::{ForeignItem, ImplItem, Item, TraitItem};
/// an item, but don't care about how item-like things are nested /// an item, but don't care about how item-like things are nested
/// within one another. /// within one another.
/// - Example: Examine each expression to look for its type and do some check or other. /// - Example: Examine each expression to look for its type and do some check or other.
/// - How: Implement `intravisit::Visitor` and override the `nested_visit_map()` method /// - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
/// to return `NestedVisitorMap::OnlyBodies` and use /// `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
/// `tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within your /// `tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within your
/// `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke /// `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
/// `intravisit::walk_expr()` to keep walking the subparts). /// `intravisit::walk_expr()` to keep walking the subparts).
@ -29,9 +29,9 @@ use super::{ForeignItem, ImplItem, Item, TraitItem};
/// item-like things. /// item-like things.
/// - Example: Lifetime resolution, which wants to bring lifetimes declared on the /// - Example: Lifetime resolution, which wants to bring lifetimes declared on the
/// impl into scope while visiting the impl-items, and then back out again. /// impl into scope while visiting the impl-items, and then back out again.
/// - How: Implement `intravisit::Visitor` and override the `nested_visit_map()` method /// - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
/// to return `NestedVisitorMap::All`. Walk your crate with `intravisit::walk_crate()` /// `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
/// invoked on `tcx.hir().krate()`. /// `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: Visitor methods for any kind of HIR node, not just item-like things.
/// - Pro: Preserves nesting information /// - Pro: Preserves nesting information
/// - Con: Does not integrate well into dependency tracking. /// - Con: Does not integrate well into dependency tracking.