#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
- ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>),
+ ItemFn(Ident, &'a Generics<'a>, FnHeader),
/// `fn foo(&self)`
- Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>),
+ Method(Ident, &'a FnSig<'a>),
/// `|x, y| {}`
Closure,
impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&FnHeader> {
match *self {
- FnKind::ItemFn(_, _, ref header, _) => Some(header),
- FnKind::Method(_, ref sig, _) => Some(&sig.header),
+ FnKind::ItemFn(_, _, ref header) => Some(header),
+ FnKind::Method(_, ref sig) => Some(&sig.header),
FnKind::Closure => None,
}
}
pub mod nested_filter {
use super::Map;
- /// Specifies what nested things a visitor wants to visit. The most
- /// common choice is `OnlyBodies`, which will cause the visitor to
- /// visit fn bodies for fns that it encounters, but skip over nested
- /// item-like things.
+ /// Specifies what nested things a visitor wants to visit. By "nested
+ /// things", 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.
+ ///
+ /// 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
/// visit strategy.
pub trait Visitor<'v>: Sized {
// 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 NestedFilter: NestedFilter<'v> = nested_filter::None;
///////////////////////////////////////////////////////////////////////////
// Nested items.
- /// The default versions of the `visit_nested_XXX` routines invoke
- /// this method to get a map to use. By selecting an enum variant,
- /// you control which kinds of nested HIR are visited; see
- /// `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.
+ /// Override this type to control which nested HIR are visited; see
+ /// [`NestedFilter`] for details. If you override this type, you
+ /// must also override [`nested_visit_map`](Self::nested_visit_map).
///
/// **If for some reason you want the nested behavior, but don't
- /// have a `Map` at your disposal:** then you should override the
- /// `visit_nested_XXX` methods, and override this method to
- /// `panic!()`. This way, if a new `visit_nested_XXX` variant is
- /// added in the future, we will see the panic in your code and
- /// fix it appropriately.
+ /// have a `Map` at your disposal:** then override the
+ /// `visit_nested_XXX` methods. If a new `visit_nested_XXX` variant is
+ /// added in the future, it will cause a panic which can be detected
+ /// and fixed 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 {
panic!(
"nested_visit_map must be implemented or consider using \
);
}
- /// Invoked when a nested item is encountered. By default does
- /// nothing unless you override `nested_visit_map` to return other than
- /// `None`, in which case it will walk the item. **You probably
- /// don't want to override this method** -- instead, override
- /// `nested_visit_map` or use the "shallow" or "deep" visit
- /// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
- /// reason to override this method is if you want a nested pattern
- /// but cannot supply a `Map`; see `nested_visit_map` for advice.
+ /// Invoked when a nested item is encountered. By default, when
+ /// `Self::NestedFilter` is `nested_filter::None`, this method does
+ /// nothing. **You probably don't want to override this method** --
+ /// instead, override [`Self::NestedFilter`] or use the "shallow" or
+ /// "deep" visit patterns described on
+ /// `itemlikevisit::ItemLikeVisitor`. The only reason to override
+ /// this method is if you want a nested pattern but cannot supply a
+ /// [`Map`]; see `nested_visit_map` for advice.
fn visit_nested_item(&mut self, id: ItemId) {
if Self::NestedFilter::INTER {
let item = self.nested_visit_map().item(id);
}
/// Invoked to visit the body of a function, method or closure. Like
- /// visit_nested_item, does nothing by default unless you override
- /// `nested_visit_map` to return other than `None`, in which case it will walk
- /// the body.
+ /// `visit_nested_item`, does nothing by default unless you override
+ /// `Self::NestedFilter`.
fn visit_nested_body(&mut self, id: BodyId) {
if Self::NestedFilter::INTRA {
let body = self.nested_visit_map().body(id);
walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, _id: HirId, _attr: &'v Attribute) {}
- fn visit_vis(&mut self, vis: &'v Visibility<'v>) {
- walk_vis(self, vis)
- }
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) {
walk_associated_item_kind(self, kind);
}
}
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
- visitor.visit_vis(&item.vis);
visitor.visit_ident(item.ident);
match item.kind {
ItemKind::ExternCrate(orig_name) => {
visitor.visit_nested_body(body);
}
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
- FnKind::ItemFn(item.ident, generics, sig.header, &item.vis),
+ FnKind::ItemFn(item.ident, generics, sig.header),
&sig.decl,
body_id,
item.span,
visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait);
visitor.visit_ty(self_ty);
- walk_list!(visitor, visit_impl_item_ref, items);
+ walk_list!(visitor, visit_impl_item_ref, *items);
}
ItemKind::Struct(ref struct_definition, ref generics)
| ItemKind::Union(ref struct_definition, ref generics) => {
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
visitor.visit_id(foreign_item.hir_id());
- visitor.visit_vis(&foreign_item.vis);
visitor.visit_ident(foreign_item.ident);
match foreign_item.kind {
}
}
}
- walk_list!(visitor, visit_param_bound, param.bounds);
}
pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v AnonConst) {
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
walk_list!(visitor, visit_generic_param, generics.params);
- walk_list!(visitor, visit_where_predicate, generics.where_clause.predicates);
+ walk_list!(visitor, visit_where_predicate, generics.predicates);
}
pub fn walk_where_predicate<'v, V: Visitor<'v>>(
}
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn(
- FnKind::Method(trait_item.ident, sig, None),
+ FnKind::Method(trait_item.ident, sig),
&sig.decl,
body_id,
trait_item.span,
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added.
- let ImplItem { def_id: _, ident, ref vis, ref generics, ref kind, span: _ } = *impl_item;
+ let ImplItem { def_id: _, ident, ref generics, ref kind, span: _, vis_span: _ } = *impl_item;
visitor.visit_ident(ident);
- visitor.visit_vis(vis);
visitor.visit_generics(generics);
match *kind {
ImplItemKind::Const(ref ty, body) => {
}
ImplItemKind::Fn(ref sig, body_id) => {
visitor.visit_fn(
- FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis)),
+ FnKind::Method(impl_item.ident, sig),
&sig.decl,
body_id,
impl_item.span,
pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) {
visitor.visit_id(field.hir_id);
- visitor.visit_vis(&field.vis);
visitor.visit_ident(field.ident);
visitor.visit_ty(&field.ty);
}
visitor.visit_expr(&arm.body);
}
-pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility<'v>) {
- if let VisibilityKind::Restricted { ref path, hir_id } = vis.node {
- visitor.visit_id(hir_id);
- visitor.visit_path(path, hir_id)
- }
-}
-
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) {
// No visitable content here: this fn exists so you can call it if
// the right thing to do, should content be added in the future,