Skip to content

Refactor HIR item-like traversal (part 1) #95655

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 18 commits into from
Apr 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b73b4de
Refactor HIR item-like traversal (part 1)
kckeiks Apr 3, 2022
0baf85e
remove some uses of visit_all_item_likes in incremental, metadata and…
kckeiks Apr 6, 2022
28aa2dd
remove some uses of visit_all_item_likes in typeck, symbol_mangling a…
kckeiks Apr 7, 2022
0d01ee9
remove ItemLikeVisitor impls in incremental, interface, metadata and …
kckeiks Apr 7, 2022
3d6f4c8
remove ItemLikeVisitor impls and add fast paths using DefKind
kckeiks Apr 7, 2022
df10715
remove CheckVisitor, CollectExternCrateVisitor and ItemLikeVisitor impls
kckeiks Apr 7, 2022
d2840d2
add mapping from DefKind to Target and remove more ItemLikeVisitor impls
kckeiks Apr 7, 2022
f9781fd
remove ItemLikeVisitor impls from monomorphize and rustc_typeck crates
kckeiks Apr 7, 2022
cb10a9a
replace tcx.hir().item with tcx.def_span query
kckeiks Apr 9, 2022
e2512f7
avoid creating vec in methods in ModuleItems
kckeiks Apr 9, 2022
1c9ddd2
move item query inside if stmt
kckeiks Apr 9, 2022
7ea034a
restrict access to span only when we emit diagnostic
kckeiks Apr 9, 2022
51ee3d4
avoid accessing the interner by comparing the Symbol directly
kckeiks Apr 9, 2022
f983d26
use copied() and avoid creating a vector in items and par_items
kckeiks Apr 9, 2022
0b38596
use ItemId.def_id and avoid fetching Item
kckeiks Apr 9, 2022
a349fc4
update Finder to store LocalDefId
kckeiks Apr 9, 2022
a31632b
rename to par_for_each_item
kckeiks Apr 9, 2022
88108bd
add comment about restriction of Target::from_def_kind
kckeiks Apr 9, 2022
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
25 changes: 25 additions & 0 deletions compiler/rustc_hir/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use crate::hir;
use crate::{Item, ItemKind, TraitItem, TraitItemKind};

use crate::def::DefKind;
use std::fmt::{self, Display};

#[derive(Copy, Clone, PartialEq, Debug)]
Expand Down Expand Up @@ -130,6 +131,30 @@ impl Target {
}
}

// FIXME: For now, should only be used with def_kinds from ItemIds
pub fn from_def_kind(def_kind: DefKind) -> Target {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great idea! I wonder if we should somehow merge DefKind and Target in a follow-up PR.

match def_kind {
DefKind::ExternCrate => Target::ExternCrate,
DefKind::Use => Target::Use,
DefKind::Static(..) => Target::Static,
DefKind::Const => Target::Const,
DefKind::Fn => Target::Fn,
DefKind::Macro(..) => Target::MacroDef,
DefKind::Mod => Target::Mod,
DefKind::ForeignMod => Target::ForeignMod,
DefKind::GlobalAsm => Target::GlobalAsm,
DefKind::TyAlias => Target::TyAlias,
DefKind::OpaqueTy => Target::OpaqueTy,
DefKind::Enum => Target::Enum,
DefKind::Struct => Target::Struct,
DefKind::Union => Target::Union,
DefKind::Trait => Target::Trait,
DefKind::TraitAlias => Target::TraitAlias,
DefKind::Impl => Target::Impl,
_ => panic!("impossible case reached"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it impossible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, this is an oversight. If this is used with DefKinds derived from ItemIds then I think it is not possible to see the other variants of DefKind here but I am not sure about DefKinds from ImplItemId, TraitItemId, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment so that users are aware of this until we merge Target and DefKind.

}
}

pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
match trait_item.kind {
TraitItemKind::Const(..) => Target::AssocConst,
Expand Down
41 changes: 20 additions & 21 deletions compiler/rustc_incremental/src/persist/dirty_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::Node as HirNode;
use rustc_hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind};
use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeExt};
Expand Down Expand Up @@ -147,7 +146,24 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {

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

let crate_items = tcx.hir_crate_items(());

for id in crate_items.items() {
dirty_clean_visitor.check_item(id.def_id);
}

for id in crate_items.trait_items() {
dirty_clean_visitor.check_item(id.def_id);
}

for id in crate_items.impl_items() {
dirty_clean_visitor.check_item(id.def_id);
}

for id in crate_items.foreign_items() {
dirty_clean_visitor.check_item(id.def_id);
}

let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
tcx.hir().walk_attributes(&mut all_attrs);
Expand Down Expand Up @@ -365,7 +381,8 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
}
}

fn check_item(&mut self, item_id: LocalDefId, item_span: Span) {
fn check_item(&mut self, item_id: LocalDefId) {
let item_span = self.tcx.def_span(item_id.to_def_id());
let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id());
for attr in self.tcx.get_attrs(item_id.to_def_id()).iter() {
let Some(assertion) = self.assertion_maybe(item_id, attr) else {
Expand All @@ -388,24 +405,6 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
}
}

impl<'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
self.check_item(item.def_id, item.span);
}

fn visit_trait_item(&mut self, item: &hir::TraitItem<'_>) {
self.check_item(item.def_id, item.span);
}

fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) {
self.check_item(item.def_id, item.span);
}

fn visit_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
self.check_item(item.def_id, item.span);
}
}

/// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have
/// a cfg flag called `foo`.
fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
Expand Down
28 changes: 9 additions & 19 deletions compiler/rustc_interface/src/proc_macro_decls.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;

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

finder.decls.map(|id| tcx.hir().local_def_id(id))
}

struct Finder<'tcx> {
tcx: TyCtxt<'tcx>,
decls: Option<hir::HirId>,
}

impl<'v> ItemLikeVisitor<'v> for Finder<'_> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
let attrs = self.tcx.hir().attrs(item.hir_id());
if self.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
self.decls = Some(item.hir_id());
for id in tcx.hir().items() {
let attrs = finder.tcx.hir().attrs(id.hir_id());
if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
finder.decls = Some(id.def_id);
}
}

fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}

fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
finder.decls
}

fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
struct Finder<'tcx> {
tcx: TyCtxt<'tcx>,
decls: Option<hir::def_id::LocalDefId>,
}

pub(crate) fn provide(providers: &mut Providers) {
Expand Down
34 changes: 12 additions & 22 deletions compiler/rustc_metadata/src/foreign_modules.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::def::DefKind;
use rustc_middle::ty::TyCtxt;
use rustc_session::cstore::ForeignModule;

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

struct Collector {
modules: Vec<ForeignModule>,
}

impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let hir::ItemKind::ForeignMod { items, .. } = it.kind else {
return;
};

let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
self.modules.push(ForeignModule { foreign_items, def_id: it.def_id.to_def_id() });
let mut modules = Vec::new();
for id in tcx.hir().items() {
if !matches!(tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) {
continue;
}
let item = tcx.hir().item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
modules.push(ForeignModule { foreign_items, def_id: id.def_id.to_def_id() });
}
}

fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
modules
}
21 changes: 11 additions & 10 deletions compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::def::DefKind;
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib};
use rustc_session::parse::feature_err;
Expand All @@ -15,7 +15,9 @@ use rustc_target::spec::abi::Abi;

crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
let mut collector = Collector { tcx, libs: Vec::new() };
tcx.hir().visit_all_item_likes(&mut collector);
for id in tcx.hir().items() {
collector.process_item(id);
}
collector.process_command_line();
collector.libs
}
Expand All @@ -32,8 +34,13 @@ struct Collector<'tcx> {
libs: Vec<NativeLib>,
}

impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
impl<'tcx> Collector<'tcx> {
fn process_item(&mut self, id: rustc_hir::ItemId) {
if !matches!(self.tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) {
return;
}

let it = self.tcx.hir().item(id);
let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
return;
};
Expand Down Expand Up @@ -252,12 +259,6 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
}
}

fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
}

impl Collector<'_> {
fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLib) {
if lib.name.as_ref().map_or(false, |&s| s == kw::Empty) {
match span {
Expand Down
58 changes: 20 additions & 38 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1783,10 +1783,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
debug!("EncodeContext::encode_traits_and_impls()");
empty_proc_macro!(self);
let tcx = self.tcx;
let mut visitor = ImplsVisitor { tcx, impls: FxHashMap::default() };
tcx.hir().visit_all_item_likes(&mut visitor);
let mut fx_hash_map: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> =
FxHashMap::default();

let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
for id in tcx.hir().items() {
if matches!(tcx.hir().def_kind(id.def_id), DefKind::Impl) {
if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) {
let simplified_self_ty = fast_reject::simplify_type(
self.tcx,
trait_ref.self_ty(),
TreatParams::AsPlaceholders,
);

fx_hash_map
.entry(trait_ref.def_id)
.or_default()
.push((id.def_id.local_def_index, simplified_self_ty));
}
}
}

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

// Bring everything into deterministic order for hashing
all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
Expand Down Expand Up @@ -2049,41 +2066,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}

struct ImplsVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
impls: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>>,
}

impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
match item.kind {
hir::ItemKind::Impl(..) => {
if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
let simplified_self_ty = fast_reject::simplify_type(
self.tcx,
trait_ref.self_ty(),
TreatParams::AsPlaceholders,
);

self.impls
.entry(trait_ref.def_id)
.or_default()
.push((item.def_id.local_def_index, simplified_self_ty));
}
}
_ => {}
}
}

fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem<'v>) {}

fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem<'v>) {
// handled in `visit_item` above
}

fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
}

/// Used to prefetch queries which will be needed later by metadata encoding.
/// Only a subset of the queries are actually prefetched to keep this code smaller.
fn prefetch_mir(tcx: TyCtxt<'_>) {
Expand Down
Loading