From 54ff9a2290cca64550d8fa5692f9d3d91ef174ba Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 23 Jul 2026 12:26:19 +0200 Subject: [PATCH] Optimize crate resolution By keeping a map from hash to crate number. --- compiler/rustc_metadata/src/creader.rs | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index bb91d855feaeb..8879c175da2f9 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -34,7 +34,7 @@ use rustc_span::def_id::DefId; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; use rustc_target::spec::{PanicStrategy, Target}; -use tracing::{debug, info, trace}; +use tracing::{debug, info}; use crate::diagnostics; use crate::locator::{CrateError, CrateLocator, CratePaths, CrateRejections}; @@ -69,6 +69,9 @@ pub struct CStore { /// This crate has a `#[alloc_error_handler]` item. has_alloc_error_handler: bool, + /// Cached map from hash to CrateNum, to avoid scanning metas during crate resolution. + hash_to_cnum: UnordMap, + /// Names that were used to load the crates via `extern crate` or paths. resolved_externs: UnordMap, @@ -237,6 +240,7 @@ impl CStore { fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry"); + self.hash_to_cnum.insert(data.hash(), cnum); self.metas[cnum] = Some(Box::new(data)); } @@ -546,6 +550,7 @@ impl CStore { alloc_error_handler_kind: None, has_global_allocator: false, has_alloc_error_handler: false, + hash_to_cnum: UnordMap::default(), resolved_externs: UnordMap::default(), unused_externs: Vec::new(), used_extern_options: Default::default(), @@ -555,21 +560,9 @@ impl CStore { fn existing_match(&self, name: Symbol, hash: Option) -> Option { let hash = hash?; - - for (cnum, data) in self.iter_crate_data() { - if data.name() != name { - trace!("{} did not match {}", data.name(), name); - continue; - } - - if hash == data.hash() { - return Some(cnum); - } else { - debug!("actual hash {} did not match expected {}", hash, data.hash()); - } - } - - None + let cnum = *self.hash_to_cnum.get(&hash)?; + debug_assert_eq!(self.get_crate_data(cnum).name(), name); + Some(cnum) } /// Determine whether a dependency should be considered private.