From f3a94e2a994048bf85db315702fced0b0bd5194f Mon Sep 17 00:00:00 2001 From: Krisna Pranav <68631244+krishpranav@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:52:13 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Enhance=20Rust=20Compiler:=20Add?= =?UTF-8?q?=20reachable=5Fsymbols=20API=20for=20Retrieving=20All=20Reachab?= =?UTF-8?q?le=20Items=20in=20Crates=20=F0=9F=8C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_middle/src/query/plumbing.rs | 8 ++++ compiler/rustc_middle/src/ty/context.rs | 41 +++++++++++++++++++++ compiler/rustc_middle/src/ty/mod.rs | 7 ++++ 3 files changed, 56 insertions(+) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 3337f7ceee7d7..b66e0d066cbb7 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -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) +} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 24f10b4fbe784..ba5c80c35d24d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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, + visited: &mut FxHashSet, + ) { + // 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( diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index bf0ccdc0f1013..db140b2a7ce58 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2235,3 +2235,10 @@ mod size_asserts { static_assert_size!(WithCachedTypeInfo>, 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) } + } +} \ No newline at end of file