add a `nested_visit_map` method
This allows you to enable *all* nested visits in a future-compatible sort of way. Moreover, if you choose to override the `visit_nested` methods yourself, you can "future-proof" against omissions by overriding `nested_visit_map` to panic.
This commit is contained in:
parent
4df5288971
commit
26d1500e13
|
@ -38,6 +38,7 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
|
|||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::Span;
|
||||
use hir::*;
|
||||
use hir::map::Map;
|
||||
use super::itemlikevisit::DeepVisitor;
|
||||
|
||||
use std::cmp;
|
||||
|
@ -85,23 +86,52 @@ pub trait Visitor<'v> : Sized {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Nested items.
|
||||
|
||||
/// Invoked when a nested item is encountered. By default, does
|
||||
/// nothing. If you want a deep walk, you need to override to
|
||||
/// fetch the item contents. But most of the time, it is easier to
|
||||
/// use either the "shallow" or "deep" visit patterns described on
|
||||
/// `itemlikevisit::ItemLikeVisitor`.
|
||||
#[allow(unused_variables)]
|
||||
fn visit_nested_item(&mut self, id: ItemId) {
|
||||
/// The default versions of the `visit_nested_XXX` routines invoke
|
||||
/// this method to get a map to use; if they get back `None`, they
|
||||
/// just skip nested things. Otherwise, they will lookup the
|
||||
/// nested item-like things in the map and visit it. So the best
|
||||
/// way to implement a nested visitor is to override this method
|
||||
/// to return a `Map`; one advantage of this is that if we add
|
||||
/// more types of nested things in the future, they will
|
||||
/// automatically work.
|
||||
///
|
||||
/// **If for some reason you want the nested behavior, but don't
|
||||
/// have a `Map` are 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.
|
||||
fn nested_visit_map(&mut self) -> Option<&Map<'v>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Invoked when a nested impl item is encountered. By default, does
|
||||
/// nothing. If you want a deep walk, you need to override to
|
||||
/// fetch the item contents. But most of the time, it is easier
|
||||
/// (and better) to invoke `Crate::visit_all_item_likes`, which visits
|
||||
/// all items in the crate in some order (but doesn't respect
|
||||
/// nesting).
|
||||
/// Invoked when a nested item is encountered. By default does
|
||||
/// nothing unless you override `nested_visit_map` to return
|
||||
/// `Some(_)`, 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.
|
||||
#[allow(unused_variables)]
|
||||
fn visit_nested_item(&mut self, id: ItemId) {
|
||||
let opt_item = self.nested_visit_map()
|
||||
.map(|map| map.expect_item(id.id));
|
||||
if let Some(item) = opt_item {
|
||||
self.visit_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `visit_nested_item()`, but for impl items. See
|
||||
/// `visit_nested_item()` for advice on when to override this
|
||||
/// method.
|
||||
#[allow(unused_variables)]
|
||||
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
|
||||
let opt_item = self.nested_visit_map()
|
||||
.map(|map| map.impl_item(id));
|
||||
if let Some(item) = opt_item {
|
||||
self.visit_impl_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit the top-level item and (optionally) nested items / impl items. See
|
||||
|
|
|
@ -92,6 +92,11 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
|||
/// Because we want to track parent items and so forth, enable
|
||||
/// deep walking so that we walk nested items in the context of
|
||||
/// their outer items.
|
||||
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> {
|
||||
panic!("visit_nested_xxx must be manually implemented in this visitor")
|
||||
}
|
||||
|
||||
fn visit_nested_item(&mut self, item: ItemId) {
|
||||
debug!("visit_nested_item: {:?}", item);
|
||||
if !self.ignore_nested_items {
|
||||
|
|
|
@ -792,21 +792,15 @@ impl<'a> LintContext for EarlyContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
||||
impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||
/// Because lints are scoped lexically, we want to walk nested
|
||||
/// items in the context of the outer item, so enable
|
||||
/// deep-walking.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let item = self.tcx.map.expect_item(item.id);
|
||||
self.visit_item(item)
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, it: &hir::Item) {
|
||||
fn visit_item(&mut self, it: &'tcx hir::Item) {
|
||||
self.with_lint_attrs(&it.attrs, |cx| {
|
||||
run_lints!(cx, check_item, late_passes, it);
|
||||
cx.visit_ids(|v| v.visit_item(it));
|
||||
|
@ -815,7 +809,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, it: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
|
||||
self.with_lint_attrs(&it.attrs, |cx| {
|
||||
run_lints!(cx, check_foreign_item, late_passes, it);
|
||||
hir_visit::walk_foreign_item(cx, it);
|
||||
|
@ -823,19 +817,19 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &hir::Pat) {
|
||||
fn visit_pat(&mut self, p: &'tcx hir::Pat) {
|
||||
run_lints!(self, check_pat, late_passes, p);
|
||||
hir_visit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &hir::Expr) {
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
|
||||
self.with_lint_attrs(&e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, late_passes, e);
|
||||
hir_visit::walk_expr(cx, e);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &hir::Stmt) {
|
||||
fn visit_stmt(&mut self, s: &'tcx hir::Stmt) {
|
||||
// statement attributes are actually just attributes on one of
|
||||
// - item
|
||||
// - local
|
||||
|
@ -845,17 +839,17 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
hir_visit::walk_stmt(self, s);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: hir_visit::FnKind<'v>, decl: &'v hir::FnDecl,
|
||||
body: &'v hir::Expr, span: Span, id: ast::NodeId) {
|
||||
fn visit_fn(&mut self, fk: hir_visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl,
|
||||
body: &'tcx hir::Expr, span: Span, id: ast::NodeId) {
|
||||
run_lints!(self, check_fn, late_passes, fk, decl, body, span, id);
|
||||
hir_visit::walk_fn(self, fk, decl, body, span, id);
|
||||
run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id);
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self,
|
||||
s: &hir::VariantData,
|
||||
s: &'tcx hir::VariantData,
|
||||
name: ast::Name,
|
||||
g: &hir::Generics,
|
||||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId,
|
||||
_: Span) {
|
||||
run_lints!(self, check_struct_def, late_passes, s, name, g, item_id);
|
||||
|
@ -863,14 +857,17 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
run_lints!(self, check_struct_def_post, late_passes, s, name, g, item_id);
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &hir::StructField) {
|
||||
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
|
||||
self.with_lint_attrs(&s.attrs, |cx| {
|
||||
run_lints!(cx, check_struct_field, late_passes, s);
|
||||
hir_visit::walk_struct_field(cx, s);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics, item_id: ast::NodeId) {
|
||||
fn visit_variant(&mut self,
|
||||
v: &'tcx hir::Variant,
|
||||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId) {
|
||||
self.with_lint_attrs(&v.node.attrs, |cx| {
|
||||
run_lints!(cx, check_variant, late_passes, v, g);
|
||||
hir_visit::walk_variant(cx, v, g, item_id);
|
||||
|
@ -878,7 +875,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &hir::Ty) {
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty) {
|
||||
run_lints!(self, check_ty, late_passes, t);
|
||||
hir_visit::walk_ty(self, t);
|
||||
}
|
||||
|
@ -887,45 +884,45 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
run_lints!(self, check_name, late_passes, sp, name);
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &hir::Mod, s: Span, n: ast::NodeId) {
|
||||
fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: ast::NodeId) {
|
||||
run_lints!(self, check_mod, late_passes, m, s, n);
|
||||
hir_visit::walk_mod(self, m, n);
|
||||
run_lints!(self, check_mod_post, late_passes, m, s, n);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &hir::Local) {
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local) {
|
||||
self.with_lint_attrs(&l.attrs, |cx| {
|
||||
run_lints!(cx, check_local, late_passes, l);
|
||||
hir_visit::walk_local(cx, l);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &hir::Block) {
|
||||
fn visit_block(&mut self, b: &'tcx hir::Block) {
|
||||
run_lints!(self, check_block, late_passes, b);
|
||||
hir_visit::walk_block(self, b);
|
||||
run_lints!(self, check_block_post, late_passes, b);
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, a: &hir::Arm) {
|
||||
fn visit_arm(&mut self, a: &'tcx hir::Arm) {
|
||||
run_lints!(self, check_arm, late_passes, a);
|
||||
hir_visit::walk_arm(self, a);
|
||||
}
|
||||
|
||||
fn visit_decl(&mut self, d: &hir::Decl) {
|
||||
fn visit_decl(&mut self, d: &'tcx hir::Decl) {
|
||||
run_lints!(self, check_decl, late_passes, d);
|
||||
hir_visit::walk_decl(self, d);
|
||||
}
|
||||
|
||||
fn visit_expr_post(&mut self, e: &hir::Expr) {
|
||||
fn visit_expr_post(&mut self, e: &'tcx hir::Expr) {
|
||||
run_lints!(self, check_expr_post, late_passes, e);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &hir::Generics) {
|
||||
fn visit_generics(&mut self, g: &'tcx hir::Generics) {
|
||||
run_lints!(self, check_generics, late_passes, g);
|
||||
hir_visit::walk_generics(self, g);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
self.with_lint_attrs(&trait_item.attrs, |cx| {
|
||||
run_lints!(cx, check_trait_item, late_passes, trait_item);
|
||||
cx.visit_ids(|v| hir_visit::walk_trait_item(v, trait_item));
|
||||
|
@ -934,7 +931,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
|
||||
self.with_lint_attrs(&impl_item.attrs, |cx| {
|
||||
run_lints!(cx, check_impl_item, late_passes, impl_item);
|
||||
cx.visit_ids(|v| hir_visit::walk_impl_item(v, impl_item));
|
||||
|
@ -943,20 +940,20 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lt: &hir::Lifetime) {
|
||||
fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
|
||||
run_lints!(self, check_lifetime, late_passes, lt);
|
||||
}
|
||||
|
||||
fn visit_lifetime_def(&mut self, lt: &hir::LifetimeDef) {
|
||||
fn visit_lifetime_def(&mut self, lt: &'tcx hir::LifetimeDef) {
|
||||
run_lints!(self, check_lifetime_def, late_passes, lt);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, p: &hir::Path, id: ast::NodeId) {
|
||||
fn visit_path(&mut self, p: &'tcx hir::Path, id: ast::NodeId) {
|
||||
run_lints!(self, check_path, late_passes, p, id);
|
||||
hir_visit::walk_path(self, p);
|
||||
}
|
||||
|
||||
fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
|
||||
fn visit_path_list_item(&mut self, prefix: &'tcx hir::Path, item: &'tcx hir::PathListItem) {
|
||||
run_lints!(self, check_path_list_item, late_passes, item);
|
||||
hir_visit::walk_path_list_item(self, prefix, item);
|
||||
}
|
||||
|
@ -1121,7 +1118,6 @@ struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
|
|||
|
||||
// Output any lints that were previously added to the session.
|
||||
impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
|
||||
|
||||
fn visit_id(&mut self, id: ast::NodeId) {
|
||||
if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) {
|
||||
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
|
||||
|
|
|
@ -511,22 +511,16 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
|
||||
/// Walk nested items in place so that we don't report dead-code
|
||||
/// on inner functions when the outer function is already getting
|
||||
/// an error. We could do this also by checking the parents, but
|
||||
/// this is how the code is setup and it seems harmless enough.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let item = self.tcx.map.expect_item(item.id);
|
||||
self.visit_item(item)
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
if self.should_warn_about_item(item) {
|
||||
self.warn_dead_code(
|
||||
item.id,
|
||||
|
@ -540,7 +534,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, variant: &hir::Variant, g: &hir::Generics, id: ast::NodeId) {
|
||||
fn visit_variant(&mut self,
|
||||
variant: &'tcx hir::Variant,
|
||||
g: &'tcx hir::Generics,
|
||||
id: ast::NodeId) {
|
||||
if self.should_warn_about_variant(&variant.node) {
|
||||
self.warn_dead_code(variant.node.data.id(), variant.span,
|
||||
variant.node.name, "variant");
|
||||
|
@ -549,14 +546,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
|
||||
if !self.symbol_is_live(fi.id, None) {
|
||||
self.warn_dead_code(fi.id, fi.span, fi.name, fi.node.descriptive_variant());
|
||||
}
|
||||
intravisit::walk_foreign_item(self, fi);
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, field: &hir::StructField) {
|
||||
fn visit_struct_field(&mut self, field: &'tcx hir::StructField) {
|
||||
if self.should_warn_about_field(&field) {
|
||||
self.warn_dead_code(field.id, field.span,
|
||||
field.name, "field");
|
||||
|
@ -565,7 +562,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
intravisit::walk_struct_field(self, field);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
if !self.symbol_is_live(impl_item.id, None) {
|
||||
|
@ -586,7 +583,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Overwrite so that we don't warn the trait item itself.
|
||||
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
match trait_item.node {
|
||||
hir::ConstTraitItem(_, Some(ref body))|
|
||||
hir::MethodTraitItem(_, Some(ref body)) => {
|
||||
|
|
|
@ -132,21 +132,14 @@ pub fn krate(sess: &Session,
|
|||
Ok(map)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// Override the nested functions -- lifetimes follow lexical scope,
|
||||
// so it's convenient to walk the tree in lexical order.
|
||||
|
||||
fn visit_nested_item(&mut self, id: hir::ItemId) {
|
||||
let item = self.hir_map.expect_item(id.id);
|
||||
self.visit_item(item)
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.hir_map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, id: hir::ImplItemId) {
|
||||
let impl_item = self.hir_map.impl_item(id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
// Save labels for nested items.
|
||||
let saved_labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
||||
|
@ -192,7 +185,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
self.labels_in_fn = saved_labels_in_fn;
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
|
||||
// Items save/restore the set of labels. This way inner items
|
||||
// can freely reuse names, be they loop labels or lifetimes.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
@ -215,8 +208,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
replace(&mut self.labels_in_fn, saved);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v hir::FnDecl,
|
||||
b: &'v hir::Expr, s: Span, fn_id: ast::NodeId) {
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl,
|
||||
b: &'tcx hir::Expr, s: Span, fn_id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(_, generics, ..) => {
|
||||
self.visit_early_late(fn_id,decl, generics, |this| {
|
||||
|
@ -241,7 +234,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
||||
match ty.node {
|
||||
hir::TyBareFn(ref c) => {
|
||||
self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {
|
||||
|
@ -271,7 +264,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
// We reset the labels on every trait item, so that different
|
||||
// methods in an impl can reuse label names.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
@ -288,7 +281,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
replace(&mut self.labels_in_fn, saved);
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
if lifetime_ref.name == keywords::StaticLifetime.name() {
|
||||
self.insert_lifetime(lifetime_ref, DefStaticRegion);
|
||||
return;
|
||||
|
@ -296,7 +289,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
self.resolve_lifetime_ref(lifetime_ref);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &hir::Generics) {
|
||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||
for ty_param in generics.ty_params.iter() {
|
||||
walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
|
||||
if let Some(ref ty) = ty_param.default {
|
||||
|
@ -345,8 +338,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self,
|
||||
trait_ref: &hir::PolyTraitRef,
|
||||
_modifier: &hir::TraitBoundModifier) {
|
||||
trait_ref: &'tcx hir::PolyTraitRef,
|
||||
_modifier: &'tcx hir::TraitBoundModifier) {
|
||||
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
|
||||
|
||||
if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
|
||||
|
@ -504,13 +497,12 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Expr) {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
fn add_scope_and_walk_fn<'b>(&mut self,
|
||||
fk: FnKind,
|
||||
fd: &hir::FnDecl,
|
||||
fb: &'b hir::Expr,
|
||||
_span: Span,
|
||||
fn_id: ast::NodeId) {
|
||||
|
||||
fn add_scope_and_walk_fn(&mut self,
|
||||
fk: FnKind<'tcx>,
|
||||
fd: &'tcx hir::FnDecl,
|
||||
fb: &'tcx hir::Expr,
|
||||
_span: Span,
|
||||
fn_id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(_, generics, ..) => {
|
||||
intravisit::walk_fn_decl(self, fd);
|
||||
|
@ -533,8 +525,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
|_old_scope, this| this.visit_expr(fb))
|
||||
}
|
||||
|
||||
// FIXME(#37666) this works around a limitation in the region inferencer
|
||||
fn hack<F>(&mut self, f: F) where
|
||||
F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
|
||||
F: FnOnce(Scope, &mut LifetimeContext),
|
||||
F: for<'b> FnOnce(Scope, &mut LifetimeContext<'b, 'tcx>),
|
||||
{
|
||||
let LifetimeContext {sess, hir_map, ref mut map, ..} = *self;
|
||||
let mut this = LifetimeContext {
|
||||
|
@ -571,10 +570,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
/// ordering is not important there.
|
||||
fn visit_early_late<F>(&mut self,
|
||||
fn_id: ast::NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
generics: &hir::Generics,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
generics: &'tcx hir::Generics,
|
||||
walk: F) where
|
||||
F: FnOnce(&mut LifetimeContext),
|
||||
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
|
||||
{
|
||||
let fn_def_id = self.hir_map.local_def_id(fn_id);
|
||||
insert_late_bound_lifetimes(self.map,
|
||||
|
@ -604,11 +603,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let this = self;
|
||||
this.with(EarlyScope(&early, start as u32, this.scope), move |old_scope, this| {
|
||||
self.with(EarlyScope(&early, start as u32, self.scope), move |old_scope, this| {
|
||||
this.with(LateScope(&late, this.scope), move |_, this| {
|
||||
this.check_lifetime_defs(old_scope, &generics.lifetimes);
|
||||
walk(this);
|
||||
this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
// stability. The stability is recorded in the index and used as the parent.
|
||||
fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
|
||||
item_sp: Span, kind: AnnotationKind, visit_children: F)
|
||||
where F: FnOnce(&mut Annotator)
|
||||
where F: FnOnce(&mut Self)
|
||||
{
|
||||
if self.index.staged_api[&LOCAL_CRATE] && self.tcx.sess.features.borrow().staged_api {
|
||||
debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
|
||||
|
@ -234,21 +234,15 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||
/// Because stability levels are scoped lexically, we want to walk
|
||||
/// nested items in the context of the outer item, so enable
|
||||
/// deep-walking.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let item = self.tcx.map.expect_item(item.id);
|
||||
self.visit_item(item)
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &Item) {
|
||||
fn visit_item(&mut self, i: &'tcx Item) {
|
||||
let orig_in_trait_impl = self.in_trait_impl;
|
||||
let mut kind = AnnotationKind::Required;
|
||||
match i.node {
|
||||
|
@ -277,13 +271,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
|
|||
self.in_trait_impl = orig_in_trait_impl;
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
|
||||
self.annotate(ti.id, &ti.attrs, ti.span, AnnotationKind::Required, |v| {
|
||||
intravisit::walk_trait_item(v, ti);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
|
||||
let kind = if self.in_trait_impl {
|
||||
AnnotationKind::Prohibited
|
||||
} else {
|
||||
|
@ -294,25 +288,25 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, var: &Variant, g: &'v Generics, item_id: NodeId) {
|
||||
fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: NodeId) {
|
||||
self.annotate(var.node.data.id(), &var.node.attrs, var.span, AnnotationKind::Required, |v| {
|
||||
intravisit::walk_variant(v, var, g, item_id);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &StructField) {
|
||||
fn visit_struct_field(&mut self, s: &'tcx StructField) {
|
||||
self.annotate(s.id, &s.attrs, s.span, AnnotationKind::Required, |v| {
|
||||
intravisit::walk_struct_field(v, s);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) {
|
||||
self.annotate(i.id, &i.attrs, i.span, AnnotationKind::Required, |v| {
|
||||
intravisit::walk_foreign_item(v, i);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_macro_def(&mut self, md: &'v hir::MacroDef) {
|
||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
|
||||
if md.imported_from.is_none() {
|
||||
self.annotate(md.id, &md.attrs, md.span, AnnotationKind::Required, |_| {});
|
||||
}
|
||||
|
@ -449,21 +443,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||
/// Because stability levels are scoped lexically, we want to walk
|
||||
/// nested items in the context of the outer item, so enable
|
||||
/// deep-walking.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let item = self.tcx.map.expect_item(item.id);
|
||||
self.visit_item(item)
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
// When compiling with --test we don't enforce stability on the
|
||||
// compiler-generated test module, demarcated with `DUMMY_SP` plus the
|
||||
// name `__test`
|
||||
|
@ -474,31 +462,31 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
|
|||
intravisit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &hir::Expr) {
|
||||
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
|
||||
check_expr(self.tcx, ex,
|
||||
&mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
|
||||
intravisit::walk_expr(self, ex);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
|
||||
fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) {
|
||||
check_path(self.tcx, path, id,
|
||||
&mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
|
||||
intravisit::walk_path(self, path)
|
||||
}
|
||||
|
||||
fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
|
||||
fn visit_path_list_item(&mut self, prefix: &'tcx hir::Path, item: &'tcx hir::PathListItem) {
|
||||
check_path_list_item(self.tcx, item,
|
||||
&mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
|
||||
intravisit::walk_path_list_item(self, prefix, item)
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &hir::Pat) {
|
||||
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
|
||||
check_pat(self.tcx, pat,
|
||||
&mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
|
||||
intravisit::walk_pat(self, pat)
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &hir::Block) {
|
||||
fn visit_block(&mut self, b: &'tcx hir::Block) {
|
||||
let old_skip_count = self.in_skip_block;
|
||||
match b.rules {
|
||||
hir::BlockCheckMode::PushUnstableBlock => {
|
||||
|
|
|
@ -499,14 +499,6 @@ macro_rules! hash_span {
|
|||
}
|
||||
|
||||
impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
|
||||
fn visit_nested_item(&mut self, _: ItemId) {
|
||||
// Each item is hashed independently; ignore nested items.
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, _: ImplItemId) {
|
||||
// Impl items are hashed independently; ignore nested impl items.
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self,
|
||||
s: &'tcx VariantData,
|
||||
name: Name,
|
||||
|
|
|
@ -106,12 +106,20 @@ impl<'k> StatCollector<'k> {
|
|||
}
|
||||
|
||||
impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> {
|
||||
panic!("visit_nested_xxx must be manually implemented in this visitor")
|
||||
}
|
||||
|
||||
fn visit_nested_item(&mut self, id: hir::ItemId) {
|
||||
let nested_item = self.krate.unwrap().item(id.id);
|
||||
self.visit_item(nested_item)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, impl_item_id: hir::ImplItemId) {
|
||||
let nested_impl_item = self.krate.unwrap().impl_item(impl_item_id);
|
||||
self.visit_impl_item(nested_impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &'v hir::Item) {
|
||||
self.record("Item", Id::Node(i.id), i);
|
||||
hir_visit::walk_item(self, i)
|
||||
|
|
|
@ -116,20 +116,14 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
/// We want to visit items in the context of their containing
|
||||
/// module and so forth, so supply a crate for doing a deep walk.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let tcx = self.tcx;
|
||||
self.visit_item(tcx.map.expect_item(item.id))
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
let inherited_item_level = match item.node {
|
||||
// Impls inherit level from their types and traits
|
||||
hir::ItemImpl(.., None, ref ty, _) => {
|
||||
|
@ -278,7 +272,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
self.prev_level = orig_level;
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'v hir::Block) {
|
||||
fn visit_block(&mut self, b: &'tcx hir::Block) {
|
||||
let orig_level = replace(&mut self.prev_level, None);
|
||||
|
||||
// Blocks can have public items, for example impls, but they always
|
||||
|
@ -289,7 +283,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
self.prev_level = orig_level;
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &hir::Mod, _sp: Span, id: ast::NodeId) {
|
||||
fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: ast::NodeId) {
|
||||
// This code is here instead of in visit_item so that the
|
||||
// crate module gets processed as well.
|
||||
if self.prev_level.is_some() {
|
||||
|
@ -305,14 +299,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
intravisit::walk_mod(self, m, id);
|
||||
}
|
||||
|
||||
fn visit_macro_def(&mut self, md: &'v hir::MacroDef) {
|
||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
|
||||
self.update(md.id, Some(AccessLevel::Public));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx: 'a> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
// Make the type hidden under a type alias reachable
|
||||
fn reach_aliased_type(&mut self, item: &hir::Item, path: &hir::Path) {
|
||||
fn reach_aliased_type(&mut self, item: &'tcx hir::Item, path: &'tcx hir::Path) {
|
||||
if let hir::ItemTy(ref ty, ref generics) = item.node {
|
||||
// See `fn is_public_type_alias` for details
|
||||
self.visit_ty(ty);
|
||||
|
@ -326,14 +320,14 @@ impl<'b, 'a, 'tcx: 'a> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
impl<'b, 'a, 'tcx: 'a> Visitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
// when we visit an impl, its methods and items are part of its "interface"
|
||||
let impl_item = self.ev.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
||||
if let hir::TyPath(_, ref path) = ty.node {
|
||||
let def = self.ev.tcx.expect_def(ty.id);
|
||||
match def {
|
||||
|
@ -365,7 +359,7 @@ impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<
|
|||
intravisit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) {
|
||||
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef) {
|
||||
let def_id = self.ev.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
if let Some(node_id) = self.ev.tcx.map.as_local_node_id(def_id) {
|
||||
let item = self.ev.tcx.map.expect_item(node_id);
|
||||
|
@ -427,26 +421,20 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> {
|
||||
/// We want to visit items in the context of their containing
|
||||
/// module and so forth, so supply a crate for doing a deep walk.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let tcx = self.tcx;
|
||||
self.visit_item(tcx.map.expect_item(item.id))
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
let orig_curitem = replace(&mut self.curitem, item.id);
|
||||
intravisit::walk_item(self, item);
|
||||
self.curitem = orig_curitem;
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &hir::Expr) {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprMethodCall(..) => {
|
||||
let method_call = ty::MethodCall::expr(expr.id);
|
||||
|
@ -506,7 +494,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
|||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pattern: &hir::Pat) {
|
||||
fn visit_pat(&mut self, pattern: &'tcx hir::Pat) {
|
||||
// Foreign functions do not have their patterns mapped in the def_map,
|
||||
// and there's nothing really relevant there anyway, so don't bother
|
||||
// checking privacy. If you can name the type then you can pass it to an
|
||||
|
@ -542,7 +530,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
|||
intravisit::walk_pat(self, pattern);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
|
||||
self.in_foreign = true;
|
||||
intravisit::walk_foreign_item(self, fi);
|
||||
self.in_foreign = false;
|
||||
|
@ -636,20 +624,14 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a
|
|||
fn visit_expr(&mut self, _: &hir::Expr) {}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
/// We want to visit items in the context of their containing
|
||||
/// module and so forth, so supply a crate for doing a deep walk.
|
||||
fn visit_nested_item(&mut self, item: hir::ItemId) {
|
||||
let tcx = self.tcx;
|
||||
self.visit_item(tcx.map.expect_item(item.id))
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
|
||||
Some(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: hir::ImplItemId) {
|
||||
let impl_item = self.tcx.map.impl_item(item_id);
|
||||
self.visit_impl_item(impl_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
match item.node {
|
||||
// contents of a private mod can be reexported, so we need
|
||||
// to check internals.
|
||||
|
@ -834,7 +816,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
|||
intravisit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &hir::Generics) {
|
||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||
for ty_param in generics.ty_params.iter() {
|
||||
for bound in ty_param.bounds.iter() {
|
||||
self.check_ty_param_bound(bound)
|
||||
|
@ -855,13 +837,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
|
||||
if self.access_levels.is_reachable(item.id) {
|
||||
intravisit::walk_foreign_item(self, item)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &hir::Ty) {
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty) {
|
||||
if let hir::TyPath(..) = t.node {
|
||||
if self.path_is_private_type(t.id) {
|
||||
self.old_error_set.insert(t.id);
|
||||
|
@ -870,7 +852,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
|||
intravisit::walk_ty(self, t)
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics, item_id: ast::NodeId) {
|
||||
fn visit_variant(&mut self,
|
||||
v: &'tcx hir::Variant,
|
||||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId) {
|
||||
if self.access_levels.is_reachable(v.node.data.id()) {
|
||||
self.in_variant = true;
|
||||
intravisit::walk_variant(self, v, g, item_id);
|
||||
|
@ -878,7 +863,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &hir::StructField) {
|
||||
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
|
||||
if s.vis == hir::Public || self.in_variant {
|
||||
intravisit::walk_struct_field(self, s);
|
||||
}
|
||||
|
@ -888,8 +873,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
|||
// expression/block context can't possibly contain exported things.
|
||||
// (Making them no-ops stops us from traversing the whole AST without
|
||||
// having to be super careful about our `walk_...` calls above.)
|
||||
fn visit_block(&mut self, _: &hir::Block) {}
|
||||
fn visit_expr(&mut self, _: &hir::Expr) {}
|
||||
fn visit_block(&mut self, _: &'tcx hir::Block) {}
|
||||
fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue