Skip to content

Add reachable_symbols API for retrieving all reachable items in crates #135436

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

Closed
wants to merge 1 commit into from
Closed
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
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,3 +666,11 @@ pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
perhaps the `{name}` query was never assigned a provider function",
)
}

pub(crate) fn reachable_symbols<'tcx>(
tcx: TyCtxt<'tcx>,
crate_num: CrateNum,
) -> &'tcx [DefId] {
// Call the implementation defined in `context.rs`
tcx.reachable_symbols(crate_num)
}
41 changes: 41 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,47 @@ impl<'tcx> TyCtxtAt<'tcx> {
}
}

impl<'tcx> TyCtxt<'tcx> {
/// Returns all reachable symbols (DefIds) for the given crate.
pub fn reachable_symbols(self, crate_num: CrateNum) -> &'tcx [DefId] {
// Vector to store the DefIds of reachable items
let mut reachable_def_ids = Vec::new();
let mut visited = FxHashSet::default();

// Recursive function to traverse reachable items
fn collect_reachable_items<'tcx>(
tcx: TyCtxt<'tcx>,
module_def_id: DefId,
reachable_def_ids: &mut Vec<DefId>,
visited: &mut FxHashSet<DefId>,
) {
// Avoid revisiting modules
if !visited.insert(module_def_id) {
return;
}

// Add the current module to the list
reachable_def_ids.push(module_def_id);

// Fetch module children that are not reexports
if let Some(children) = tcx.module_children_non_reexports(module_def_id) {
for child in children {
// Recursively collect items for each child
collect_reachable_items(tcx, child.def_id, reachable_def_ids, visited);
}
}
}

// Start traversal from the root module of the given crate
let root_def_id = self.crate_root(crate_num);
collect_reachable_items(self, root_def_id, &mut reachable_def_ids, &mut visited);

// Cache the results using the query system
self.alloc_slice(reachable_def_ids)
}
}


impl<'tcx> TyCtxt<'tcx> {
/// `tcx`-dependent operations performed for every created definition.
pub fn create_def(
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2235,3 +2235,10 @@ mod size_asserts {
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
// tidy-alphabetical-end
}

define_queries! {
/// Query to return all reachable symbols (DefIds) for a given crate.
query reachable_symbols(key: CrateNum) -> &'tcx [DefId] {
desc { |tcx| format!("computing reachable symbols for crate `{}`", key) }
}
}
Loading