Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7355d97

Browse files
committedMay 17, 2022
Auto merge of rust-lang#96825 - kckeiks:remove-item-like-visitor-trait, r=cjgillot
Retire `ItemLikeVisitor` trait Issue rust-lang#95004 cc `@cjgillot`
2 parents 1e8cd63 + 48fd666 commit 7355d97

File tree

29 files changed

+640
-791
lines changed

29 files changed

+640
-791
lines changed
 

‎compiler/rustc_hir/src/intravisit.rs

+36-44
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
11
//! HIR walker for walking the contents of nodes.
22
//!
3-
//! **For an overview of the visitor strategy, see the docs on the
4-
//! `super::itemlikevisit::ItemLikeVisitor` trait.**
3+
//! Here are the three available patterns for the visitor strategy,
4+
//! in roughly the order of desirability:
5+
//!
6+
//! 1. **Shallow visit**: Get a simple callback for every item (or item-like thing) in the HIR.
7+
//! - Example: find all items with a `#[foo]` attribute on them.
8+
//! - How: Use the `hir_crate_items` or `hir_module_items` query to traverse over item-like ids
9+
//! (ItemId, TraitItemId, etc.) and use tcx.def_kind and `tcx.hir().item*(id)` to filter and
10+
//! access actual item-like thing, respectively.
11+
//! - Pro: Efficient; just walks the lists of item ids and gives users control whether to access
12+
//! the hir_owners themselves or not.
13+
//! - Con: Don't get information about nesting
14+
//! - Con: Don't have methods for specific bits of HIR, like "on
15+
//! every expr, do this".
16+
//! 2. **Deep visit**: Want to scan for specific kinds of HIR nodes within
17+
//! an item, but don't care about how item-like things are nested
18+
//! within one another.
19+
//! - Example: Examine each expression to look for its type and do some check or other.
20+
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
21+
//! `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
22+
//! `tcx.hir().deep_visit_all_item_likes(&mut visitor)`. Within your
23+
//! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
24+
//! `intravisit::walk_expr()` to keep walking the subparts).
25+
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
26+
//! - Pro: Integrates well into dependency tracking.
27+
//! - Con: Don't get information about nesting between items
28+
//! 3. **Nested visit**: Want to visit the whole HIR and you care about the nesting between
29+
//! item-like things.
30+
//! - Example: Lifetime resolution, which wants to bring lifetimes declared on the
31+
//! impl into scope while visiting the impl-items, and then back out again.
32+
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
33+
//! `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
34+
//! `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`.
35+
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
36+
//! - Pro: Preserves nesting information
37+
//! - Con: Does not integrate well into dependency tracking.
538
//!
639
//! If you have decided to use this visitor, here are some general
740
//! notes on how to do so:
@@ -32,43 +65,12 @@
3265
//! example generator inference, and possibly also HIR borrowck.
3366
3467
use crate::hir::*;
35-
use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
68+
use crate::itemlikevisit::ParItemLikeVisitor;
3669
use rustc_ast::walk_list;
3770
use rustc_ast::{Attribute, Label};
3871
use rustc_span::symbol::{Ident, Symbol};
3972
use rustc_span::Span;
4073

41-
pub struct DeepVisitor<'v, V> {
42-
visitor: &'v mut V,
43-
}
44-
45-
impl<'v, V> DeepVisitor<'v, V> {
46-
pub fn new(base: &'v mut V) -> Self {
47-
DeepVisitor { visitor: base }
48-
}
49-
}
50-
51-
impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
52-
where
53-
V: Visitor<'hir>,
54-
{
55-
fn visit_item(&mut self, item: &'hir Item<'hir>) {
56-
self.visitor.visit_item(item);
57-
}
58-
59-
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem<'hir>) {
60-
self.visitor.visit_trait_item(trait_item);
61-
}
62-
63-
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>) {
64-
self.visitor.visit_impl_item(impl_item);
65-
}
66-
67-
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
68-
self.visitor.visit_foreign_item(foreign_item);
69-
}
70-
}
71-
7274
pub trait IntoVisitor<'hir> {
7375
type Visitor: Visitor<'hir>;
7476
fn into_visitor(&self) -> Self::Visitor;
@@ -315,16 +317,6 @@ pub trait Visitor<'v>: Sized {
315317
walk_body(self, b);
316318
}
317319

318-
/// When invoking `visit_all_item_likes()`, you need to supply an
319-
/// item-like visitor. This method converts an "intra-visit"
320-
/// visitor into an item-like visitor that walks the entire tree.
321-
/// If you use this, you probably don't want to process the
322-
/// contents of nested item-like things, since the outer loop will
323-
/// visit them as well.
324-
fn as_deep_visitor(&mut self) -> DeepVisitor<'_, Self> {
325-
DeepVisitor::new(self)
326-
}
327-
328320
///////////////////////////////////////////////////////////////////////////
329321

330322
fn visit_id(&mut self, _hir_id: HirId) {

‎compiler/rustc_hir/src/itemlikevisit.rs

-50
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,5 @@
11
use super::{ForeignItem, ImplItem, Item, TraitItem};
22

3-
/// The "item-like visitor" defines only the top-level methods
4-
/// that can be invoked by `Crate::visit_all_item_likes()`. Whether
5-
/// this trait is the right one to implement will depend on the
6-
/// overall pattern you need. Here are the three available patterns,
7-
/// in roughly the order of desirability:
8-
///
9-
/// 1. **Shallow visit**: Get a simple callback for every item (or item-like thing) in the HIR.
10-
/// - Example: find all items with a `#[foo]` attribute on them.
11-
/// - How: Implement `ItemLikeVisitor` and call `tcx.hir().visit_all_item_likes()`.
12-
/// - Pro: Efficient; just walks the lists of item-like things, not the nodes themselves.
13-
/// - Con: Don't get information about nesting
14-
/// - Con: Don't have methods for specific bits of HIR, like "on
15-
/// every expr, do this".
16-
/// 2. **Deep visit**: Want to scan for specific kinds of HIR nodes within
17-
/// an item, but don't care about how item-like things are nested
18-
/// within one another.
19-
/// - Example: Examine each expression to look for its type and do some check or other.
20-
/// - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
21-
/// `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
22-
/// `tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within your
23-
/// `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
24-
/// `intravisit::walk_expr()` to keep walking the subparts).
25-
/// - Pro: Visitor methods for any kind of HIR node, not just item-like things.
26-
/// - Pro: Integrates well into dependency tracking.
27-
/// - Con: Don't get information about nesting between items
28-
/// 3. **Nested visit**: Want to visit the whole HIR and you care about the nesting between
29-
/// item-like things.
30-
/// - Example: Lifetime resolution, which wants to bring lifetimes declared on the
31-
/// impl into scope while visiting the impl-items, and then back out again.
32-
/// - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
33-
/// `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
34-
/// `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`.
35-
/// - Pro: Visitor methods for any kind of HIR node, not just item-like things.
36-
/// - Pro: Preserves nesting information
37-
/// - Con: Does not integrate well into dependency tracking.
38-
///
39-
/// Note: the methods of `ItemLikeVisitor` intentionally have no
40-
/// defaults, so that as we expand the list of item-like things, we
41-
/// revisit the various visitors to see if they need to change. This
42-
/// is harder to do with `intravisit::Visitor`, so when you add a new
43-
/// `visit_nested_foo()` method, it is recommended that you search for
44-
/// existing `fn visit_nested` methods to see where changes are
45-
/// needed.
46-
pub trait ItemLikeVisitor<'hir> {
47-
fn visit_item(&mut self, item: &'hir Item<'hir>);
48-
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem<'hir>);
49-
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>);
50-
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>);
51-
}
52-
533
/// A parallel variant of `ItemLikeVisitor`.
544
pub trait ParItemLikeVisitor<'hir> {
555
fn visit_item(&self, item: &'hir Item<'hir>);

‎compiler/rustc_incremental/src/assert_dep_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
7575
let mut visitor =
7676
IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] };
7777
visitor.process_attrs(hir::CRATE_HIR_ID);
78-
tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor());
78+
tcx.hir().deep_visit_all_item_likes(&mut visitor);
7979
(visitor.if_this_changed, visitor.then_this_would_need)
8080
};
8181

‎compiler/rustc_metadata/src/rmeta/encoder.rs

+7-18
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_hir::def_id::{
1414
};
1515
use rustc_hir::definitions::DefPathData;
1616
use rustc_hir::intravisit::{self, Visitor};
17-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1817
use rustc_hir::lang_items;
1918
use rustc_hir::{AnonConst, GenericParamKind};
2019
use rustc_index::bit_set::GrowableBitSet;
@@ -453,7 +452,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
453452
return;
454453
}
455454

456-
self.tcx.hir().visit_all_item_likes(&mut self.as_deep_visitor());
455+
self.tcx.hir().deep_visit_all_item_likes(self);
457456
}
458457

459458
fn encode_def_path_table(&mut self) {
@@ -2243,26 +2242,16 @@ pub fn provide(providers: &mut Providers) {
22432242
traits_in_crate: |tcx, cnum| {
22442243
assert_eq!(cnum, LOCAL_CRATE);
22452244

2246-
#[derive(Default)]
2247-
struct TraitsVisitor {
2248-
traits: Vec<DefId>,
2249-
}
2250-
impl ItemLikeVisitor<'_> for TraitsVisitor {
2251-
fn visit_item(&mut self, item: &hir::Item<'_>) {
2252-
if let hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) = item.kind {
2253-
self.traits.push(item.def_id.to_def_id());
2254-
}
2245+
let mut traits = Vec::new();
2246+
for id in tcx.hir().items() {
2247+
if matches!(tcx.def_kind(id.def_id), DefKind::Trait | DefKind::TraitAlias) {
2248+
traits.push(id.def_id.to_def_id())
22552249
}
2256-
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
2257-
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
2258-
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
22592250
}
22602251

2261-
let mut visitor = TraitsVisitor::default();
2262-
tcx.hir().visit_all_item_likes(&mut visitor);
22632252
// Bring everything into deterministic order.
2264-
visitor.traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
2265-
tcx.arena.alloc_slice(&visitor.traits)
2253+
traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
2254+
tcx.arena.alloc_slice(&traits)
22662255
},
22672256

22682257
..*providers

‎compiler/rustc_middle/src/hir/map/mod.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_hir::def::{DefKind, Res};
99
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
1010
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
1111
use rustc_hir::intravisit::{self, Visitor};
12-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1312
use rustc_hir::*;
1413
use rustc_index::vec::Idx;
1514
use rustc_middle::hir::nested_filter;
@@ -161,6 +160,10 @@ impl<'hir> Map<'hir> {
161160
self.tcx.hir_crate_items(()).items.iter().copied()
162161
}
163162

163+
pub fn module_items(self, module: LocalDefId) -> impl Iterator<Item = ItemId> + 'hir {
164+
self.tcx.hir_module_items(module).items()
165+
}
166+
164167
pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) {
165168
par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id));
166169
}
@@ -603,16 +606,16 @@ impl<'hir> Map<'hir> {
603606
}
604607

605608
/// Visits all items in the crate in some deterministic (but
606-
/// unspecified) order. If you just need to process every item,
607-
/// but don't care about nesting, this method is the best choice.
609+
/// unspecified) order. If you need to process every item,
610+
/// and care about nesting -- usually because your algorithm
611+
/// follows lexical scoping rules -- then this method is the best choice.
612+
/// If you don't care about nesting, you should use the `tcx.hir_crate_items()` query
613+
/// or `items()` instead.
608614
///
609-
/// If you do care about nesting -- usually because your algorithm
610-
/// follows lexical scoping rules -- then you want a different
611-
/// approach. You should override `visit_nested_item` in your
612-
/// visitor and then call `intravisit::walk_crate` instead.
613-
pub fn visit_all_item_likes<V>(self, visitor: &mut V)
615+
/// Please see the notes in `intravisit.rs` for more information.
616+
pub fn deep_visit_all_item_likes<V>(self, visitor: &mut V)
614617
where
615-
V: itemlikevisit::ItemLikeVisitor<'hir>,
618+
V: Visitor<'hir>,
616619
{
617620
let krate = self.krate();
618621
for owner in krate.owners.iter().filter_map(|i| i.as_owner()) {
@@ -643,9 +646,12 @@ impl<'hir> Map<'hir> {
643646
})
644647
}
645648

646-
pub fn visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
649+
/// If you don't care about nesting, you should use the
650+
/// `tcx.hir_module_items()` query or `module_items()` instead.
651+
/// Please see notes in `deep_visit_all_item_likes`.
652+
pub fn deep_visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
647653
where
648-
V: ItemLikeVisitor<'hir>,
654+
V: Visitor<'hir>,
649655
{
650656
let module = self.tcx.hir_module_items(module);
651657

@@ -666,7 +672,7 @@ impl<'hir> Map<'hir> {
666672
}
667673
}
668674

669-
pub fn for_each_module(self, f: impl Fn(LocalDefId)) {
675+
pub fn for_each_module(self, mut f: impl FnMut(LocalDefId)) {
670676
let crate_items = self.tcx.hir_crate_items(());
671677
for module in crate_items.submodules.iter() {
672678
f(*module)

‎compiler/rustc_middle/src/hir/nested_filter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::intravisit::nested_filter::NestedFilter;
88
/// constant arguments of types, e.g. in `let _: [(); /* HERE */];`.
99
///
1010
/// **This is the most common choice.** A very common pattern is
11-
/// to use `visit_all_item_likes()` as an outer loop,
11+
/// to use `deep_visit_all_item_likes()` as an outer loop,
1212
/// and to have the visitor that visits the contents of each item
1313
/// using this setting.
1414
pub struct OnlyBodies(());

‎compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,7 @@ impl<'tcx> TyCtxt<'tcx> {
19951995
}
19961996

19971997
/// Look up the name of a definition across crates. This does not look at HIR.
1998-
fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
1998+
pub fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
19991999
if let Some(cnum) = def_id.as_crate_root() {
20002000
Some(self.crate_name(cnum))
20012001
} else {

‎compiler/rustc_mir_transform/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
170170
intravisit::walk_struct_def(self, v)
171171
}
172172
}
173-
tcx.hir().visit_all_item_likes(&mut GatherCtors { tcx, set: &mut set }.as_deep_visitor());
173+
tcx.hir().deep_visit_all_item_likes(&mut GatherCtors { tcx, set: &mut set });
174174

175175
set
176176
}

‎compiler/rustc_passes/src/check_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,7 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>)
23902390

23912391
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
23922392
let check_attr_visitor = &mut CheckAttrVisitor { tcx };
2393-
tcx.hir().visit_item_likes_in_module(module_def_id, &mut check_attr_visitor.as_deep_visitor());
2393+
tcx.hir().deep_visit_item_likes_in_module(module_def_id, check_attr_visitor);
23942394
if module_def_id.is_top_level_module() {
23952395
check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None);
23962396
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.