Skip to content

Commit 7849e3e

Browse files
committed
Auto merge of #88435 - cjgillot:no-walk-crate, r=Aaron1011
Avoid invoking the hir_crate query to traverse the HIR Walking the HIR tree is done using the `hir_crate` query. However, this is unnecessary, since `hir_owner(CRATE_DEF_ID)` provides the same information. Since depending on `hir_crate` forces dependents to always be executed, this leads to unnecessary work. By splitting HIR and attributes visits, we can avoid an edge to `hir_crate` when trying to visit the HIR tree.
2 parents e30b683 + d119a13 commit 7849e3e

File tree

25 files changed

+118
-133
lines changed

25 files changed

+118
-133
lines changed

compiler/rustc_hir/src/intravisit.rs

-12
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
//! example generator inference, and possibly also HIR borrowck.
3333
3434
use crate::hir::*;
35-
use crate::hir_id::CRATE_HIR_ID;
3635
use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
3736
use rustc_ast::walk_list;
3837
use rustc_ast::{Attribute, Label};
@@ -477,17 +476,6 @@ pub trait Visitor<'v>: Sized {
477476
}
478477
}
479478

480-
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
481-
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
482-
let top_mod = krate.module();
483-
visitor.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
484-
for (&id, attrs) in krate.attrs.iter() {
485-
for a in *attrs {
486-
visitor.visit_attribute(id, a)
487-
}
488-
}
489-
}
490-
491479
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
492480
visitor.visit_id(mod_hir_id);
493481
for &item_id in module.item_ids {

compiler/rustc_incremental/src/persist/dirty_clean.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
142142
krate.visit_all_item_likes(&mut dirty_clean_visitor);
143143

144144
let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
145-
intravisit::walk_crate(&mut all_attrs, krate);
145+
tcx.hir().walk_attributes(&mut all_attrs);
146146

147147
// Note that we cannot use the existing "unused attribute"-infrastructure
148148
// here, since that is running before codegen. This is also the reason why

compiler/rustc_interface/src/passes.rs

-4
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,6 @@ pub fn lower_to_hir<'res, 'tcx>(
464464
arena,
465465
);
466466

467-
if sess.opts.debugging_opts.hir_stats {
468-
hir_stats::print_hir_stats(&hir_crate);
469-
}
470-
471467
sess.time("early_lint_checks", || {
472468
rustc_lint::check_ast_crate(
473469
sess,

compiler/rustc_lint/src/late.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,8 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
451451
// since the root module isn't visited as an item (because it isn't an
452452
// item), warn for it here.
453453
lint_callback!(cx, check_crate, krate);
454-
455-
hir_visit::walk_crate(cx, krate);
456-
454+
tcx.hir().walk_toplevel_module(cx);
455+
tcx.hir().walk_attributes(cx);
457456
lint_callback!(cx, check_crate_post, krate);
458457
})
459458
}

compiler/rustc_lint/src/levels.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
3737

3838
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true);
3939
builder.levels.register_id(hir::CRATE_HIR_ID);
40-
intravisit::walk_crate(&mut builder, krate);
40+
tcx.hir().walk_toplevel_module(&mut builder);
4141
builder.levels.pop(push);
4242

4343
builder.levels.build_map()

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

+20-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use rustc_data_structures::fingerprint::Fingerprint;
77
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
88
use rustc_data_structures::svh::Svh;
99
use rustc_hir::def::{DefKind, Res};
10-
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
10+
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
1111
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
12-
use rustc_hir::intravisit;
12+
use rustc_hir::intravisit::{self, Visitor};
1313
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1414
use rustc_hir::*;
1515
use rustc_index::vec::Idx;
@@ -519,6 +519,22 @@ impl<'hir> Map<'hir> {
519519
}
520520
}
521521

522+
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
523+
pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) {
524+
let (top_mod, span, hir_id) = self.get_module(CRATE_DEF_ID);
525+
visitor.visit_mod(top_mod, span, hir_id);
526+
}
527+
528+
/// Walks the attributes in a crate.
529+
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
530+
let krate = self.krate();
531+
for (&id, attrs) in krate.attrs.iter() {
532+
for a in *attrs {
533+
visitor.visit_attribute(id, a)
534+
}
535+
}
536+
}
537+
522538
pub fn visit_item_likes_in_module<V>(&self, module: LocalDefId, visitor: &mut V)
523539
where
524540
V: ItemLikeVisitor<'hir>,
@@ -934,7 +950,8 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tc
934950
&tcx.untracked_resolutions.definitions,
935951
hcx,
936952
);
937-
intravisit::walk_crate(&mut collector, tcx.untracked_crate);
953+
let top_mod = tcx.untracked_crate.module();
954+
collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
938955

939956
let map = collector.finalize_and_compute_crate_hash();
940957
tcx.arena.alloc(map)

compiler/rustc_passes/src/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -775,5 +775,5 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
775775
let krate = tcx.hir().krate();
776776
let live_symbols = find_live(tcx, access_levels, krate);
777777
let mut visitor = DeadVisitor { tcx, live_symbols };
778-
intravisit::walk_crate(&mut visitor, krate);
778+
tcx.hir().walk_toplevel_module(&mut visitor);
779779
}

compiler/rustc_passes/src/hir_id_validator.rs

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ use rustc_middle::ty::TyCtxt;
1111
pub fn check_crate(tcx: TyCtxt<'_>) {
1212
tcx.dep_graph.assert_ignored();
1313

14+
if tcx.sess.opts.debugging_opts.hir_stats {
15+
crate::hir_stats::print_hir_stats(tcx);
16+
}
17+
1418
let errors = Lock::new(Vec::new());
1519
let hir_map = tcx.hir();
1620

compiler/rustc_passes/src/hir_stats.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir as hir;
99
use rustc_hir::intravisit as hir_visit;
1010
use rustc_hir::HirId;
1111
use rustc_middle::hir::map::Map;
12+
use rustc_middle::ty::TyCtxt;
1213
use rustc_middle::util::common::to_readable_str;
1314
use rustc_span::Span;
1415

@@ -25,18 +26,19 @@ struct NodeData {
2526
}
2627

2728
struct StatCollector<'k> {
28-
krate: Option<&'k hir::Crate<'k>>,
29+
krate: Option<Map<'k>>,
2930
data: FxHashMap<&'static str, NodeData>,
3031
seen: FxHashSet<Id>,
3132
}
3233

33-
pub fn print_hir_stats(krate: &hir::Crate<'_>) {
34+
pub fn print_hir_stats(tcx: TyCtxt<'_>) {
3435
let mut collector = StatCollector {
35-
krate: Some(krate),
36+
krate: Some(tcx.hir()),
3637
data: FxHashMap::default(),
3738
seen: FxHashSet::default(),
3839
};
39-
hir_visit::walk_crate(&mut collector, krate);
40+
tcx.hir().walk_toplevel_module(&mut collector);
41+
tcx.hir().walk_attributes(&mut collector);
4042
collector.print("HIR STATS");
4143
}
4244

compiler/rustc_passes/src/lib_features.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use rustc_ast::{Attribute, MetaItem, MetaItemKind};
88
use rustc_errors::struct_span_err;
9-
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
9+
use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
1010
use rustc_middle::hir::map::Map;
1111
use rustc_middle::middle::lib_features::LibFeatures;
1212
use rustc_middle::ty::query::Providers;
@@ -126,9 +126,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
126126

127127
fn get_lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
128128
let mut collector = LibFeatureCollector::new(tcx);
129-
let krate = tcx.hir().krate();
130-
131-
intravisit::walk_crate(&mut collector, krate);
129+
tcx.hir().walk_attributes(&mut collector);
132130
collector.lib_features
133131
}
134132

compiler/rustc_passes/src/stability.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_errors::struct_span_err;
88
use rustc_hir as hir;
99
use rustc_hir::def::{DefKind, Res};
1010
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
11+
use rustc_hir::hir_id::CRATE_HIR_ID;
1112
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1213
use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
1314
use rustc_middle::hir::map::Map;
@@ -678,7 +679,6 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
678679
.collect();
679680

680681
{
681-
let krate = tcx.hir().krate();
682682
let mut annotator = Annotator {
683683
tcx,
684684
index: &mut index,
@@ -711,13 +711,13 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
711711

712712
annotator.annotate(
713713
CRATE_DEF_ID,
714-
krate.module().inner,
714+
tcx.hir().span(CRATE_HIR_ID),
715715
None,
716716
AnnotationKind::Required,
717717
InheritDeprecation::Yes,
718718
InheritConstStability::No,
719719
InheritStability::No,
720-
|v| intravisit::walk_crate(v, krate),
720+
|v| tcx.hir().walk_toplevel_module(v),
721721
);
722722
}
723723
index
@@ -908,8 +908,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
908908
if tcx.stability().staged_api[&LOCAL_CRATE] {
909909
let krate = tcx.hir().krate();
910910
let mut missing = MissingStabilityAnnotations { tcx, access_levels };
911-
missing.check_missing_stability(CRATE_DEF_ID, krate.module().inner);
912-
intravisit::walk_crate(&mut missing, krate);
911+
missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
912+
tcx.hir().walk_toplevel_module(&mut missing);
913913
krate.visit_all_item_likes(&mut missing.as_deep_visitor());
914914
}
915915

compiler/rustc_privacy/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
21692169
changed: false,
21702170
};
21712171
loop {
2172-
intravisit::walk_crate(&mut visitor, tcx.hir().krate());
2172+
tcx.hir().walk_toplevel_module(&mut visitor);
21732173
if visitor.changed {
21742174
visitor.changed = false;
21752175
} else {
@@ -2192,11 +2192,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
21922192
in_variant: false,
21932193
old_error_set: Default::default(),
21942194
};
2195-
intravisit::walk_crate(&mut visitor, krate);
2195+
tcx.hir().walk_toplevel_module(&mut visitor);
21962196

21972197
let has_pub_restricted = {
21982198
let mut pub_restricted_visitor = PubRestrictedVisitor { tcx, has_pub_restricted: false };
2199-
intravisit::walk_crate(&mut pub_restricted_visitor, krate);
2199+
tcx.hir().walk_toplevel_module(&mut pub_restricted_visitor);
22002200
pub_restricted_visitor.has_pub_restricted
22012201
};
22022202

compiler/rustc_save_analysis/src/dump_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ impl<'tcx> DumpVisitor<'tcx> {
11221122
attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt),
11231123
},
11241124
);
1125-
intravisit::walk_crate(self, krate);
1125+
self.tcx.hir().walk_toplevel_module(self);
11261126
}
11271127

11281128
fn process_bounds(&mut self, bounds: hir::GenericBounds<'tcx>) {

compiler/rustc_typeck/src/check/method/suggest.rs

+34-67
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
66
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
77
use rustc_hir as hir;
88
use rustc_hir::def::{DefKind, Namespace, Res};
9-
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
10-
use rustc_hir::intravisit;
9+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
1110
use rustc_hir::lang_items::LangItem;
1211
use rustc_hir::{ExprKind, Node, QPath};
1312
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1011,9 +1010,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10111010
candidates: Vec<DefId>,
10121011
) {
10131012
let module_did = self.tcx.parent_module(self.body_id);
1014-
let module_id = self.tcx.hir().local_def_id_to_hir_id(module_did);
1015-
let krate = self.tcx.hir().krate();
1016-
let (span, found_use) = UsePlacementFinder::check(self.tcx, krate, module_id);
1013+
let (span, found_use) = find_use_placement(self.tcx, module_did);
10171014
if let Some(span) = span {
10181015
let path_strings = candidates.iter().map(|did| {
10191016
// Produce an additional newline to separate the new use statement
@@ -1606,64 +1603,38 @@ pub fn provide(providers: &mut ty::query::Providers) {
16061603
providers.all_traits = compute_all_traits;
16071604
}
16081605

1609-
struct UsePlacementFinder<'tcx> {
1610-
target_module: hir::HirId,
1611-
span: Option<Span>,
1612-
found_use: bool,
1613-
tcx: TyCtxt<'tcx>,
1614-
}
1615-
1616-
impl UsePlacementFinder<'tcx> {
1617-
fn check(
1618-
tcx: TyCtxt<'tcx>,
1619-
krate: &'tcx hir::Crate<'tcx>,
1620-
target_module: hir::HirId,
1621-
) -> (Option<Span>, bool) {
1622-
let mut finder = UsePlacementFinder { target_module, span: None, found_use: false, tcx };
1623-
intravisit::walk_crate(&mut finder, krate);
1624-
(finder.span, finder.found_use)
1625-
}
1626-
}
1627-
1628-
impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
1629-
fn visit_mod(&mut self, module: &'tcx hir::Mod<'tcx>, _: Span, hir_id: hir::HirId) {
1630-
if self.span.is_some() {
1631-
return;
1632-
}
1633-
if hir_id != self.target_module {
1634-
intravisit::walk_mod(self, module, hir_id);
1635-
return;
1636-
}
1637-
// Find a `use` statement.
1638-
for &item_id in module.item_ids {
1639-
let item = self.tcx.hir().item(item_id);
1640-
match item.kind {
1641-
hir::ItemKind::Use(..) => {
1642-
// Don't suggest placing a `use` before the prelude
1643-
// import or other generated ones.
1644-
if !item.span.from_expansion() {
1645-
self.span = Some(item.span.shrink_to_lo());
1646-
self.found_use = true;
1647-
return;
1648-
}
1606+
fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
1607+
let mut span = None;
1608+
let mut found_use = false;
1609+
let (module, _, _) = tcx.hir().get_module(target_module);
1610+
1611+
// Find a `use` statement.
1612+
for &item_id in module.item_ids {
1613+
let item = tcx.hir().item(item_id);
1614+
match item.kind {
1615+
hir::ItemKind::Use(..) => {
1616+
// Don't suggest placing a `use` before the prelude
1617+
// import or other generated ones.
1618+
if !item.span.from_expansion() {
1619+
span = Some(item.span.shrink_to_lo());
1620+
found_use = true;
1621+
break;
16491622
}
1650-
// Don't place `use` before `extern crate`...
1651-
hir::ItemKind::ExternCrate(_) => {}
1652-
// ...but do place them before the first other item.
1653-
_ => {
1654-
if self.span.map_or(true, |span| item.span < span) {
1655-
if !item.span.from_expansion() {
1656-
self.span = Some(item.span.shrink_to_lo());
1657-
// Don't insert between attributes and an item.
1658-
let attrs = self.tcx.hir().attrs(item.hir_id());
1659-
// Find the first attribute on the item.
1660-
// FIXME: This is broken for active attributes.
1661-
for attr in attrs {
1662-
if !attr.span.is_dummy()
1663-
&& self.span.map_or(true, |span| attr.span < span)
1664-
{
1665-
self.span = Some(attr.span.shrink_to_lo());
1666-
}
1623+
}
1624+
// Don't place `use` before `extern crate`...
1625+
hir::ItemKind::ExternCrate(_) => {}
1626+
// ...but do place them before the first other item.
1627+
_ => {
1628+
if span.map_or(true, |span| item.span < span) {
1629+
if !item.span.from_expansion() {
1630+
span = Some(item.span.shrink_to_lo());
1631+
// Don't insert between attributes and an item.
1632+
let attrs = tcx.hir().attrs(item.hir_id());
1633+
// Find the first attribute on the item.
1634+
// FIXME: This is broken for active attributes.
1635+
for attr in attrs {
1636+
if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
1637+
span = Some(attr.span.shrink_to_lo());
16671638
}
16681639
}
16691640
}
@@ -1672,11 +1643,7 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
16721643
}
16731644
}
16741645

1675-
type Map = intravisit::ErasedMap<'tcx>;
1676-
1677-
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
1678-
intravisit::NestedVisitorMap::None
1679-
}
1646+
(span, found_use)
16801647
}
16811648

16821649
fn print_disambiguation_help(

compiler/rustc_typeck/src/collect/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
691691
debug!("find_opaque_ty_constraints: scope={:?}", scope);
692692

693693
if scope == hir::CRATE_HIR_ID {
694-
intravisit::walk_crate(&mut locator, tcx.hir().krate());
694+
tcx.hir().walk_toplevel_module(&mut locator);
695695
} else {
696696
debug!("find_opaque_ty_constraints: scope={:?}", tcx.hir().get(scope));
697697
match tcx.hir().get(scope) {

0 commit comments

Comments
 (0)