Skip to content

Rework HIR API to make invocations of the hir_crate query harder. #88880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -698,52 +697,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 @@ -1660,18 +1658,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