Skip to content

Commit 9e50544

Browse files
Add unit test to ensure that both parts of a DefPathHash depend on the defining crate's ID.
1 parent 97380e3 commit 9e50544

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

compiler/rustc_hir/src/definitions.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ impl DefPathTable {
5858
// being used.
5959
//
6060
// See the documentation for DefPathHash for more information.
61-
panic!("found DefPathHash collsion between {:?} and {:?}. \
62-
Compilation cannot continue.", def_path1, def_path2);
61+
panic!(
62+
"found DefPathHash collsion between {:?} and {:?}. \
63+
Compilation cannot continue.",
64+
def_path1, def_path2
65+
);
6366
}
6467

6568
// Assert that all DefPathHashes correctly contain the local crate's
@@ -138,7 +141,7 @@ pub struct DefKey {
138141
}
139142

140143
impl DefKey {
141-
fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash {
144+
pub(crate) fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash {
142145
let mut hasher = StableHasher::new();
143146

144147
parent.hash(&mut hasher);

compiler/rustc_hir/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ mod stable_hash_impls;
3131
mod target;
3232
pub mod weak_lang_items;
3333

34+
#[cfg(test)]
35+
mod tests;
36+
3437
pub use hir::*;
3538
pub use hir_id::*;
3639
pub use lang_items::{LangItem, LanguageItems};

compiler/rustc_hir/src/tests.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData};
2+
use rustc_data_structures::fingerprint::Fingerprint;
3+
use rustc_span::crate_disambiguator::CrateDisambiguator;
4+
use rustc_span::def_id::{DefPathHash, StableCrateId};
5+
6+
#[test]
7+
fn def_path_hash_depends_on_crate_id() {
8+
// This test makes sure that *both* halves of a DefPathHash depend on
9+
// the crate-id of the defining crate. This is a desirable property
10+
// because the crate-id can be more easily changed than the DefPath
11+
// of an item, so, in the case of a crate-local DefPathHash collision,
12+
// the user can simply "role the dice again" for all DefPathHashes in
13+
// the crate by changing the crate disambiguator (e.g. via bumping the
14+
// crate's version number).
15+
16+
let d0 = CrateDisambiguator::from(Fingerprint::new(12, 34));
17+
let d1 = CrateDisambiguator::from(Fingerprint::new(56, 78));
18+
19+
let h0 = mk_test_hash("foo", d0);
20+
let h1 = mk_test_hash("foo", d1);
21+
22+
assert_ne!(h0.stable_crate_id(), h1.stable_crate_id());
23+
assert_ne!(h0.local_hash(), h1.local_hash());
24+
25+
fn mk_test_hash(crate_name: &str, crate_disambiguator: CrateDisambiguator) -> DefPathHash {
26+
let stable_crate_id = StableCrateId::new(crate_name, crate_disambiguator);
27+
let parent_hash = DefPathHash::new(stable_crate_id, 0);
28+
29+
let key = DefKey {
30+
parent: None,
31+
disambiguated_data: DisambiguatedDefPathData {
32+
data: DefPathData::CrateRoot,
33+
disambiguator: 0,
34+
},
35+
};
36+
37+
key.compute_stable_hash(parent_hash)
38+
}
39+
}

compiler/rustc_span/src/def_id.rs

+6
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ impl DefPathHash {
159159
StableCrateId(self.0.as_value().0)
160160
}
161161

162+
/// Returns the crate-local part of the [DefPathHash].
163+
#[inline]
164+
pub fn local_hash(&self) -> u64 {
165+
self.0.as_value().1
166+
}
167+
162168
/// Builds a new [DefPathHash] with the given [StableCrateId] and
163169
/// `local_hash`, where `local_hash` must be unique within its crate.
164170
pub fn new(stable_crate_id: StableCrateId, local_hash: u64) -> DefPathHash {

0 commit comments

Comments
 (0)