Skip to content

Commit

Permalink
Auto merge of #88880 - cjgillot:no-krate, r=oli-obk
Browse files Browse the repository at this point in the history
Rework HIR API to make invocations of the hir_crate query harder.

`hir_crate` forces the recomputation of queries that depend on it.

This PR aims at avoiding useless invocations of `hir_crate` by making dependent code go through `tcx.hir()`.
  • Loading branch information
bors committed Oct 1, 2021
2 parents b6057bf + 77c3002 commit c02371c
Show file tree
Hide file tree
Showing 64 changed files with 193 additions and 209 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_driver/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ fn print_with_analysis(
let mut out = String::new();
abort_on_err(rustc_typeck::check_crate(tcx), tcx.sess);
debug!("pretty printing THIR tree");
for did in tcx.body_owners() {
for did in tcx.hir().body_owners() {
let _ = writeln!(
out,
"{:?}:\n{}\n",
Expand Down
49 changes: 1 addition & 48 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::def::{CtorKind, DefKind, Res};
use crate::def_id::{DefId, CRATE_DEF_ID};
crate use crate::hir_id::{HirId, ItemLocalId};
use crate::{itemlikevisit, LangItem};
use crate::LangItem;

use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
Expand All @@ -10,7 +10,6 @@ pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable_Generic;
use rustc_span::source_map::Spanned;
Expand Down Expand Up @@ -708,52 +707,6 @@ impl Crate<'hir> {
}
}

impl Crate<'_> {
/// Visits all items in the crate in some deterministic (but
/// unspecified) order. If you just need to process every item,
/// but don't care about nesting, this method is the best choice.
///
/// If you do care about nesting -- usually because your algorithm
/// follows lexical scoping rules -- then you want a different
/// approach. You should override `visit_nested_item` in your
/// visitor and then call `intravisit::walk_crate` instead.
pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
where
V: itemlikevisit::ItemLikeVisitor<'hir>,
{
for owner in self.owners.iter().filter_map(Option::as_ref) {
match owner {
OwnerNode::Item(item) => visitor.visit_item(item),
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
OwnerNode::TraitItem(item) => visitor.visit_trait_item(item),
OwnerNode::Crate(_) => {}
}
}
}

/// A parallel version of `visit_all_item_likes`.
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
where
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
{
par_for_each_in(&self.owners.raw, |owner| match owner {
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
Some(OwnerNode::Crate(_)) | None => {}
})
}

pub fn items<'hir>(&'hir self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
self.owners.iter().filter_map(|owner| match owner {
Some(OwnerNode::Item(item)) => Some(*item),
_ => None,
})
}
}

/// A block of statements `{ .. }`, which may have a label (in this case the
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
/// the `rules` being anything but `DefaultBlock`.
Expand Down
13 changes: 0 additions & 13 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,6 @@ pub struct NoAnn;
impl PpAnn for NoAnn {}
pub const NO_ANN: &dyn PpAnn = &NoAnn;

impl PpAnn for hir::Crate<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
Nested::Body(id) => state.print_expr(&self.body(id).value),
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
}
}
}

/// Identical to the `PpAnn` implementation for `hir::Crate`,
/// except it avoids creating a dependency on the whole crate.
impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
let mut visitor =
IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] };
visitor.process_attrs(hir::CRATE_HIR_ID);
tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
tcx.hir().visit_all_item_likes(&mut visitor.as_deep_visitor());
(visitor.if_this_changed, visitor.then_this_would_need)
};

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_incremental/src/persist/dirty_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
}

tcx.dep_graph.with_ignore(|| {
let krate = tcx.hir().krate();
let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() };
krate.visit_all_item_likes(&mut dirty_clean_visitor);
tcx.hir().visit_all_item_likes(&mut dirty_clean_visitor);

let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
tcx.hir().walk_attributes(&mut all_attrs);
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
parallel!(
{
sess.time("match_checking", || {
tcx.par_body_owners(|def_id| {
tcx.ensure().check_match(def_id.to_def_id());
});
tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id.to_def_id()))
});
},
{
Expand All @@ -907,11 +905,11 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
});

sess.time("MIR_borrow_checking", || {
tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
tcx.hir().par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
});

sess.time("MIR_effect_checking", || {
for def_id in tcx.body_owners() {
for def_id in tcx.hir().body_owners() {
tcx.ensure().thir_check_unsafety(def_id);
if !tcx.sess.opts.debugging_opts.thir_unsafeck {
rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/proc_macro_decls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_span::symbol::sym;

fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
let mut finder = Finder { tcx, decls: None };
tcx.hir().krate().visit_all_item_likes(&mut finder);
tcx.hir().visit_all_item_likes(&mut finder);

finder.decls.map(|id| tcx.hir().local_def_id(id))
}
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
}

fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) {
self.check_missing_docs_attrs(cx, CRATE_DEF_ID, krate.module().inner, "the", "crate");
fn check_crate(&mut self, cx: &LateContext<'_>) {
self.check_missing_docs_attrs(
cx,
CRATE_DEF_ID,
cx.tcx.def_span(CRATE_DEF_ID),
"the",
"crate",
);
}

fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
let access_levels = &tcx.privacy_access_levels(());

let krate = tcx.hir().krate();

let context = LateContext {
tcx,
enclosing_body: None,
Expand All @@ -450,10 +448,10 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
cx.with_lint_attrs(hir::CRATE_HIR_ID, |cx| {
// since the root module isn't visited as an item (because it isn't an
// item), warn for it here.
lint_callback!(cx, check_crate, krate);
lint_callback!(cx, check_crate,);
tcx.hir().walk_toplevel_module(cx);
tcx.hir().walk_attributes(cx);
lint_callback!(cx, check_crate_post, krate);
lint_callback!(cx, check_crate_post,);
})
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ macro_rules! late_lint_methods {
fn check_body(a: &$hir hir::Body<$hir>);
fn check_body_post(a: &$hir hir::Body<$hir>);
fn check_name(a: Span, b: Symbol);
fn check_crate(a: &$hir hir::Crate<$hir>);
fn check_crate_post(a: &$hir hir::Crate<$hir>);
fn check_crate();
fn check_crate_post();
fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
fn check_mod_post(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/foreign_modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_middle::ty::TyCtxt;

crate fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
let mut collector = Collector { modules: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut collector);
tcx.hir().visit_all_item_likes(&mut collector);
collector.modules
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_target::spec::abi::Abi;

crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
let mut collector = Collector { tcx, libs: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut collector);
tcx.hir().visit_all_item_likes(&mut collector);
collector.process_command_line();
collector.libs
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,16 +440,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}

fn encode_info_for_items(&mut self) {
let krate = self.tcx.hir().krate();
self.encode_info_for_mod(CRATE_DEF_ID, krate.module());
self.encode_info_for_mod(CRATE_DEF_ID, self.tcx.hir().root_module());

// Proc-macro crates only export proc-macro items, which are looked
// up using `proc_macro_data`
if self.is_proc_macro {
return;
}

krate.visit_all_item_likes(&mut self.as_deep_visitor());
self.tcx.hir().visit_all_item_likes(&mut self.as_deep_visitor());
}

fn encode_def_path_table(&mut self) {
Expand Down Expand Up @@ -1782,7 +1781,7 @@ impl EncodeContext<'a, 'tcx> {
debug!("EncodeContext::encode_impls()");
let tcx = self.tcx;
let mut visitor = ImplVisitor { tcx, impls: FxHashMap::default() };
tcx.hir().krate().visit_all_item_likes(&mut visitor);
tcx.hir().visit_all_item_likes(&mut visitor);

let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();

Expand Down
66 changes: 66 additions & 0 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_ast as ast;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
Expand Down Expand Up @@ -156,6 +157,21 @@ impl<'hir> Map<'hir> {
self.tcx.hir_crate(())
}

pub fn root_module(&self) -> &'hir Mod<'hir> {
match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) {
Some(OwnerNode::Crate(item)) => item,
_ => bug!(),
}
}

pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
let krate = self.krate();
krate.owners.iter().filter_map(|owner| match owner.as_ref()? {
OwnerNode::Item(item) => Some(*item),
_ => None,
})
}

pub fn def_key(&self, def_id: LocalDefId) -> DefKey {
// Accessing the DefKey is ok, since it is part of DefPathHash.
self.tcx.untracked_resolutions.definitions.def_key(def_id)
Expand Down Expand Up @@ -475,6 +491,17 @@ impl<'hir> Map<'hir> {
Some(ccx)
}

/// Returns an iterator of the `DefId`s for all body-owners in this
/// crate. If you would prefer to iterate over the bodies
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
self.krate().bodies.keys().map(move |&body_id| self.body_owner_def_id(body_id))
}

pub fn par_body_owners<F: Fn(LocalDefId) + Sync + Send>(self, f: F) {
par_for_each_in(&self.krate().bodies, |(&body_id, _)| f(self.body_owner_def_id(body_id)));
}

pub fn ty_param_owner(&self, id: HirId) -> HirId {
match self.get(id) {
Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => id,
Expand Down Expand Up @@ -531,6 +558,45 @@ impl<'hir> Map<'hir> {
}
}

/// Visits all items in the crate in some deterministic (but
/// unspecified) order. If you just need to process every item,
/// but don't care about nesting, this method is the best choice.
///
/// If you do care about nesting -- usually because your algorithm
/// follows lexical scoping rules -- then you want a different
/// approach. You should override `visit_nested_item` in your
/// visitor and then call `intravisit::walk_crate` instead.
pub fn visit_all_item_likes<V>(&self, visitor: &mut V)
where
V: itemlikevisit::ItemLikeVisitor<'hir>,
{
let krate = self.krate();
for owner in krate.owners.iter().filter_map(Option::as_ref) {
match owner {
OwnerNode::Item(item) => visitor.visit_item(item),
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
OwnerNode::TraitItem(item) => visitor.visit_trait_item(item),
OwnerNode::Crate(_) => {}
}
}
}

/// A parallel version of `visit_all_item_likes`.
pub fn par_visit_all_item_likes<V>(&self, visitor: &V)
where
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
{
let krate = self.krate();
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref() {
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
Some(OwnerNode::Crate(_)) | None => {}
})
}

pub fn visit_item_likes_in_module<V>(&self, module: LocalDefId, visitor: &mut V)
where
V: ItemLikeVisitor<'hir>,
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::util::Discr;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{self, par_iter, ParallelIterator};
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
Expand Down Expand Up @@ -1696,18 +1694,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.typeck(self.hir().body_owner_def_id(body))
}

/// Returns an iterator of the `DefId`s for all body-owners in this
/// crate. If you would prefer to iterate over the bodies
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + Captures<'tcx> + 'tcx {
self.hir().krate().bodies.keys().map(move |&body_id| self.hir().body_owner_def_id(body_id))
}

pub fn par_body_owners<F: Fn(LocalDefId) + sync::Sync + sync::Send>(self, f: F) {
par_iter(&self.hir().krate().bodies)
.for_each(|(&body_id, _)| f(self.hir().body_owner_def_id(body_id)));
}

pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
self.associated_items(id)
.in_definition_order()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2340,7 +2340,7 @@ define_print_and_forward_display! {
fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
// Iterate all local crate items no matter where they are defined.
let hir = tcx.hir();
for item in hir.krate().items() {
for item in hir.items() {
if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) {
continue;
}
Expand Down
Loading

0 comments on commit c02371c

Please sign in to comment.