Skip to content

Commit

Permalink
Change how smir iterate over all external crate defs
Browse files Browse the repository at this point in the history
Instead of trying to gather all definitions by walking the exported
modules, types and traits, add a query to expose the method to
retrieve the number of defs in a crate. Then, generate the `def_ids`
using this value.

For the local crate, we still use `hir_crate_items` query that provides
an iterator to all local definitions.
  • Loading branch information
celinval committed Nov 5, 2024
1 parent 987e1e0 commit 8f35ca5
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 31 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ provide! { tcx, def_id, other, cdata,
crate_hash => { cdata.root.header.hash }
crate_host_hash => { cdata.host_hash }
crate_name => { cdata.root.header.name }
num_def_ids => { cdata.num_def_ids() }

extra_filename => { cdata.root.extra_filename.clone() }

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,5 @@ pub fn provide(providers: &mut Providers) {
providers.in_scope_traits_map = |tcx, id| {
tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map)
};
providers.num_def_ids = |tcx, _| tcx.hir_crate_items(()).definitions().count();
}
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,16 @@ rustc_queries! {
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
}

/// Gets the number of definitions in this crate.
///
/// This allows external tools to iterate over all definitions in a crate.
/// For completeness, this also accepts `LOCAL_CRATE` as an argument, but consider using
/// `hir_crate_items(())` instead.
query num_def_ids(_: CrateNum) -> usize {
desc { "fetching the number of definitions in a crate" }
separate_provide_extern
}

query lib_features(_: CrateNum) -> &'tcx LibFeatures {
desc { "calculating the lib features defined in a crate" }
separate_provide_extern
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_smir/src/rustc_smir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
.filter_map(|local_id| tables.to_fn_def(tcx, local_id.to_def_id()))
.collect()
} else {
tables.filter_map_items(tcx, krate, |tables, tcx, def_id| tables.to_fn_def(tcx, def_id))
tables
.iter_external_def_id(tcx, krate)
.filter_map(|def_id| tables.to_fn_def(tcx, def_id))
.collect()
}
}

Expand All @@ -104,7 +107,10 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
.filter_map(|local_id| tables.to_static(tcx, local_id.to_def_id()))
.collect()
} else {
tables.filter_map_items(tcx, krate, |tables, tcx, def_id| tables.to_static(tcx, def_id))
tables
.iter_external_def_id(tcx, krate)
.filter_map(|def_id| tables.to_static(tcx, def_id))
.collect()
}
}

Expand Down
38 changes: 9 additions & 29 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use std::ops::RangeInclusive;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::ty::data_structures::HashSet;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use stable_mir::abi::Layout;
Expand Down Expand Up @@ -93,34 +92,15 @@ impl<'tcx> Tables<'tcx> {
matches!(tcx.def_kind(def_id), DefKind::Static { .. }).then(|| self.static_def(def_id))
}

fn filter_map_items<T, F>(&mut self, tcx: TyCtxt<'tcx>, krate: CrateNum, func: F) -> Vec<T>
where
F: Fn(&mut Tables<'tcx>, TyCtxt<'tcx>, DefId) -> Option<T>,
{
let crate_def = krate.as_def_id();
let mut queue = vec![crate_def];
queue.extend_from_slice(tcx.trait_impls_in_crate(krate));
let mut visited = HashSet::default();
let mut result = vec![];
while let Some(def_id) = queue.pop() {
if visited.insert(def_id) {
result.extend(func(self, tcx, def_id));
match tcx.def_kind(def_id) {
DefKind::Mod | DefKind::ForeignMod | DefKind::Trait => queue.extend(
tcx.module_children(def_id).iter().filter_map(|item| item.res.opt_def_id()),
),
DefKind::Impl { .. } => queue.extend(
tcx.associated_items(def_id).in_definition_order().map(|item| item.def_id),
),
DefKind::Struct | DefKind::Enum | DefKind::Union => {
queue.extend(tcx.inherent_impls(def_id));
}
_ => {}
}
}
}

result
/// Iterate over the definitions of the given crate.
pub fn iter_external_def_id(
&self,
tcx: TyCtxt<'tcx>,
krate: CrateNum,
) -> impl Iterator<Item = DefId> {
let num_definitions = tcx.num_def_ids(krate);
(0..num_definitions)
.map(move |i| DefId { krate, index: rustc_span::def_id::DefIndex::from_usize(i) })
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/ui-fulldeps/stable-mir/check_crate_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fn test_stable_mir() -> ControlFlow<()> {
"std::option::Option::<T>::is_some",
"std::ptr::swap",
"<std::slice::Iter<'a, T> as std::iter::Iterator>::next",
"core::num::<impl u8>::abs_diff",
],
);
// Ensure nothing crashes. There is no public static in core that we can test here.
Expand Down

0 comments on commit 8f35ca5

Please sign in to comment.