diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 9210c744c5fec..ac6a359ee577d 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -58,8 +58,11 @@ impl DefPathTable { // being used. // // See the documentation for DefPathHash for more information. - panic!("found DefPathHash collsion between {:?} and {:?}. \ - Compilation cannot continue.", def_path1, def_path2); + panic!( + "found DefPathHash collsion between {:?} and {:?}. \ + Compilation cannot continue.", + def_path1, def_path2 + ); } // Assert that all DefPathHashes correctly contain the local crate's @@ -138,7 +141,7 @@ pub struct DefKey { } impl DefKey { - fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash { + pub(crate) fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash { let mut hasher = StableHasher::new(); parent.hash(&mut hasher); diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index efc516a662fb7..c65151cd1305d 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -31,6 +31,9 @@ mod stable_hash_impls; mod target; pub mod weak_lang_items; +#[cfg(test)] +mod tests; + pub use hir::*; pub use hir_id::*; pub use lang_items::{LangItem, LanguageItems}; diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs new file mode 100644 index 0000000000000..2aafc6afa236d --- /dev/null +++ b/compiler/rustc_hir/src/tests.rs @@ -0,0 +1,39 @@ +use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData}; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_span::crate_disambiguator::CrateDisambiguator; +use rustc_span::def_id::{DefPathHash, StableCrateId}; + +#[test] +fn def_path_hash_depends_on_crate_id() { + // This test makes sure that *both* halves of a DefPathHash depend on + // the crate-id of the defining crate. This is a desirable property + // because the crate-id can be more easily changed than the DefPath + // of an item, so, in the case of a crate-local DefPathHash collision, + // the user can simply "role the dice again" for all DefPathHashes in + // the crate by changing the crate disambiguator (e.g. via bumping the + // crate's version number). + + let d0 = CrateDisambiguator::from(Fingerprint::new(12, 34)); + let d1 = CrateDisambiguator::from(Fingerprint::new(56, 78)); + + let h0 = mk_test_hash("foo", d0); + let h1 = mk_test_hash("foo", d1); + + assert_ne!(h0.stable_crate_id(), h1.stable_crate_id()); + assert_ne!(h0.local_hash(), h1.local_hash()); + + fn mk_test_hash(crate_name: &str, crate_disambiguator: CrateDisambiguator) -> DefPathHash { + let stable_crate_id = StableCrateId::new(crate_name, crate_disambiguator); + let parent_hash = DefPathHash::new(stable_crate_id, 0); + + let key = DefKey { + parent: None, + disambiguated_data: DisambiguatedDefPathData { + data: DefPathData::CrateRoot, + disambiguator: 0, + }, + }; + + key.compute_stable_hash(parent_hash) + } +} diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 7c02056105e05..bd8c95fd66171 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -159,6 +159,12 @@ impl DefPathHash { StableCrateId(self.0.as_value().0) } + /// Returns the crate-local part of the [DefPathHash]. + #[inline] + pub fn local_hash(&self) -> u64 { + self.0.as_value().1 + } + /// Builds a new [DefPathHash] with the given [StableCrateId] and /// `local_hash`, where `local_hash` must be unique within its crate. pub fn new(stable_crate_id: StableCrateId, local_hash: u64) -> DefPathHash {