Auto merge of #142903 - cjgillot:local-def-path-hash, r=compiler-errors
Only inherit local hash for paths `DefPathHash`, as the counterpart of `DefId` that is stable across compiler invocations, is comprised of 2 parts. The first one is the `StableCrateId`, stable form of `CrateNum`. The second is 64 complementary bits to identify the crate-local definition. The current implementation always hashes the full 128 bits when (1) trying to create a new child `DefPathHash` or (2) hashing a `CrateNum` or a `LocalDefId`. But we only need half that information: `LocalDefId` means that the `StableCrateId` is always the current crate's ; `CrateNum` means that we do not care about the local part. As stable hashing is very hot in the query system, in particular hashing definitions, this is a big deal. We still want the local part to change when the `StableCrateId` changes, to make incr-compilation errors less painful, ie. increase the likelihood that if will magically disappear by changing some code. This PR sprinkles some `#[inline]` attributes on small functions that appeared in profiles.
This commit is contained in:
@@ -140,7 +140,9 @@ impl DefKey {
|
|||||||
pub(crate) fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash {
|
pub(crate) fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
|
|
||||||
parent.hash(&mut hasher);
|
// The new path is in the same crate as `parent`, and will contain the stable_crate_id.
|
||||||
|
// Therefore, we only need to include information of the parent's local hash.
|
||||||
|
parent.local_hash().hash(&mut hasher);
|
||||||
|
|
||||||
let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data;
|
let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data;
|
||||||
|
|
||||||
@@ -355,8 +357,16 @@ impl Definitions {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
|
// We want *both* halves of a DefPathHash to depend on the crate-id of the defining crate.
|
||||||
let def_path_hash = key.compute_stable_hash(parent_hash);
|
// 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 "roll the dice again" for all
|
||||||
|
// DefPathHashes in the crate by changing the crate disambiguator (e.g. via bumping the
|
||||||
|
// crate's version number).
|
||||||
|
//
|
||||||
|
// Children paths will only hash the local portion, and still inherit the change to the
|
||||||
|
// root hash.
|
||||||
|
let def_path_hash =
|
||||||
|
DefPathHash::new(stable_crate_id, Hash64::new(stable_crate_id.as_u64()));
|
||||||
|
|
||||||
// Create the root definition.
|
// Create the root definition.
|
||||||
let mut table = DefPathTable::new(stable_crate_id);
|
let mut table = DefPathTable::new(stable_crate_id);
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ fn def_path_hash_depends_on_crate_id() {
|
|||||||
assert_ne!(h0.local_hash(), h1.local_hash());
|
assert_ne!(h0.local_hash(), h1.local_hash());
|
||||||
|
|
||||||
fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash {
|
fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash {
|
||||||
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
|
let parent_hash =
|
||||||
|
DefPathHash::new(stable_crate_id, Hash64::new(stable_crate_id.as_u64()));
|
||||||
|
|
||||||
let key = DefKey {
|
let key = DefKey {
|
||||||
parent: None,
|
parent: None,
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ impl DefPathHash {
|
|||||||
|
|
||||||
/// Builds a new [DefPathHash] with the given [StableCrateId] and
|
/// Builds a new [DefPathHash] with the given [StableCrateId] and
|
||||||
/// `local_hash`, where `local_hash` must be unique within its crate.
|
/// `local_hash`, where `local_hash` must be unique within its crate.
|
||||||
|
#[inline]
|
||||||
pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
|
pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
|
||||||
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
||||||
}
|
}
|
||||||
@@ -404,21 +405,21 @@ rustc_data_structures::define_id_collections!(
|
|||||||
impl<CTX: HashStableContext> HashStable<CTX> for DefId {
|
impl<CTX: HashStableContext> HashStable<CTX> for DefId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
|
hcx.def_path_hash(*self).hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CTX: HashStableContext> HashStable<CTX> for LocalDefId {
|
impl<CTX: HashStableContext> HashStable<CTX> for LocalDefId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
|
hcx.def_path_hash(self.to_def_id()).local_hash().hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CTX: HashStableContext> HashStable<CTX> for CrateNum {
|
impl<CTX: HashStableContext> HashStable<CTX> for CrateNum {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
|
self.as_def_id().to_stable_hash_key(hcx).stable_crate_id().hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,30 +465,36 @@ macro_rules! typed_def_id {
|
|||||||
pub struct $Name(DefId);
|
pub struct $Name(DefId);
|
||||||
|
|
||||||
impl $Name {
|
impl $Name {
|
||||||
|
#[inline]
|
||||||
pub const fn new_unchecked(def_id: DefId) -> Self {
|
pub const fn new_unchecked(def_id: DefId) -> Self {
|
||||||
Self(def_id)
|
Self(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_def_id(self) -> DefId {
|
pub fn to_def_id(self) -> DefId {
|
||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_local(self) -> bool {
|
pub fn is_local(self) -> bool {
|
||||||
self.0.is_local()
|
self.0.is_local()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn as_local(self) -> Option<$LocalName> {
|
pub fn as_local(self) -> Option<$LocalName> {
|
||||||
self.0.as_local().map($LocalName::new_unchecked)
|
self.0.as_local().map($LocalName::new_unchecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$LocalName> for $Name {
|
impl From<$LocalName> for $Name {
|
||||||
|
#[inline]
|
||||||
fn from(local: $LocalName) -> Self {
|
fn from(local: $LocalName) -> Self {
|
||||||
Self(local.0.to_def_id())
|
Self(local.0.to_def_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$Name> for DefId {
|
impl From<$Name> for DefId {
|
||||||
|
#[inline]
|
||||||
fn from(typed: $Name) -> Self {
|
fn from(typed: $Name) -> Self {
|
||||||
typed.0
|
typed.0
|
||||||
}
|
}
|
||||||
@@ -500,26 +507,31 @@ macro_rules! typed_def_id {
|
|||||||
impl !PartialOrd for $LocalName {}
|
impl !PartialOrd for $LocalName {}
|
||||||
|
|
||||||
impl $LocalName {
|
impl $LocalName {
|
||||||
|
#[inline]
|
||||||
pub const fn new_unchecked(def_id: LocalDefId) -> Self {
|
pub const fn new_unchecked(def_id: LocalDefId) -> Self {
|
||||||
Self(def_id)
|
Self(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_def_id(self) -> DefId {
|
pub fn to_def_id(self) -> DefId {
|
||||||
self.0.into()
|
self.0.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_local_def_id(self) -> LocalDefId {
|
pub fn to_local_def_id(self) -> LocalDefId {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$LocalName> for LocalDefId {
|
impl From<$LocalName> for LocalDefId {
|
||||||
|
#[inline]
|
||||||
fn from(typed: $LocalName) -> Self {
|
fn from(typed: $LocalName) -> Self {
|
||||||
typed.0
|
typed.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$LocalName> for DefId {
|
impl From<$LocalName> for DefId {
|
||||||
|
#[inline]
|
||||||
fn from(typed: $LocalName) -> Self {
|
fn from(typed: $LocalName) -> Self {
|
||||||
typed.0.into()
|
typed.0.into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fn f(g: impl Fn()) {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn g() {
|
fn g() {
|
||||||
// CHECK-LABEL: fn g(
|
// CHECK-LABEL: fn g(
|
||||||
// CHECK-NOT: (inlined f::<fn() {main}>)
|
// CHECK-NOT: inlined
|
||||||
f(main);
|
f(main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
error: symbol-name(_ZN5basic4main17hc88b9d80a69d119aE)
|
error: symbol-name(_ZN5basic4main17h1dddcfd03744167fE)
|
||||||
--> $DIR/basic.rs:8:1
|
--> $DIR/basic.rs:8:1
|
||||||
|
|
|
|
||||||
LL | #[rustc_symbol_name]
|
LL | #[rustc_symbol_name]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: demangling(basic::main::hc88b9d80a69d119a)
|
error: demangling(basic::main::h1dddcfd03744167f)
|
||||||
--> $DIR/basic.rs:8:1
|
--> $DIR/basic.rs:8:1
|
||||||
|
|
|
|
||||||
LL | #[rustc_symbol_name]
|
LL | #[rustc_symbol_name]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hbddb77d6f71afb32E)
|
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h4b3099ec5dc5d306E)
|
||||||
--> $DIR/issue-60925.rs:21:9
|
--> $DIR/issue-60925.rs:21:9
|
||||||
|
|
|
|
||||||
LL | #[rustc_symbol_name]
|
LL | #[rustc_symbol_name]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::hbddb77d6f71afb32)
|
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h4b3099ec5dc5d306)
|
||||||
--> $DIR/issue-60925.rs:21:9
|
--> $DIR/issue-60925.rs:21:9
|
||||||
|
|
|
|
||||||
LL | #[rustc_symbol_name]
|
LL | #[rustc_symbol_name]
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ body:
|
|||||||
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
||||||
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
||||||
flags: IS_ENUM
|
flags: IS_ENUM
|
||||||
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
|
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 }
|
||||||
args: []
|
args: []
|
||||||
variant_index: 0
|
variant_index: 0
|
||||||
subpatterns: [
|
subpatterns: [
|
||||||
@@ -108,7 +108,7 @@ body:
|
|||||||
did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar)
|
did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar)
|
||||||
variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }]
|
variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }]
|
||||||
flags: IS_ENUM
|
flags: IS_ENUM
|
||||||
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 10333377570083945360 }
|
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 7908585036048874241 }
|
||||||
args: []
|
args: []
|
||||||
variant_index: 0
|
variant_index: 0
|
||||||
subpatterns: []
|
subpatterns: []
|
||||||
@@ -156,7 +156,7 @@ body:
|
|||||||
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
||||||
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
||||||
flags: IS_ENUM
|
flags: IS_ENUM
|
||||||
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
|
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 }
|
||||||
args: []
|
args: []
|
||||||
variant_index: 0
|
variant_index: 0
|
||||||
subpatterns: [
|
subpatterns: [
|
||||||
@@ -208,7 +208,7 @@ body:
|
|||||||
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
|
||||||
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }]
|
||||||
flags: IS_ENUM
|
flags: IS_ENUM
|
||||||
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
|
repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 }
|
||||||
args: []
|
args: []
|
||||||
variant_index: 1
|
variant_index: 1
|
||||||
subpatterns: []
|
subpatterns: []
|
||||||
|
|||||||
Reference in New Issue
Block a user