2020-02-07 18:25:36 +01:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
2020-01-02 05:18:45 +01:00
|
|
|
|
2020-02-07 11:14:47 +01:00
|
|
|
use crate::hir::{
|
2021-09-19 22:07:12 +02:00
|
|
|
AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item,
|
Remove special-cased stable hashing for HIR module
All other 'containers' (e.g. `impl` blocks) hashed their contents
in the normal, order-dependent way. However, `Mod` was hashing
its contents in a (sort-of) order-independent way. However, the
exact order is exposed to consumers through `Mod.item_ids`,
and through query results like `hir_module_items`. Therefore,
stable hashing needs to take the order of items into account,
to avoid fingerprint ICEs.
Unforuntately, I was unable to directly build a reproducer
for the ICE, due to the behavior of `Fingerprint::combine_commutative`.
This operation swaps the upper and lower `u64` when constructing the
result, which makes the function non-associative. Since we start
the hashing of module items by combining `Fingerprint::ZERO` with
the first item, it's difficult to actually build an example where
changing the order of module items leaves the final hash unchanged.
However, this appears to have been hit in practice in #92218
While we're not able to reproduce it, the fact that proc-macros
are involved (which can give an entire module the same span, preventing
any span-related invalidations) makes me confident that the root
cause of that issue is our method of hashing module items.
This PR removes all of the special handling for `Mod`, instead deriving
a `HashStable` implementation. This makes `Mod` consistent with other
'contains' like `Impl`, which hash their contents through the typical
derive of `HashStable`.
2021-12-24 12:38:29 -05:00
|
|
|
ItemId, OwnerNodes, TraitCandidate, TraitItem, TraitItemId, Ty, VisibilityKind,
|
2020-02-07 11:14:47 +01:00
|
|
|
};
|
2020-02-07 18:25:36 +01:00
|
|
|
use crate::hir_id::{HirId, ItemLocalId};
|
2021-04-19 22:27:49 +02:00
|
|
|
use rustc_span::def_id::DefPathHash;
|
2020-01-02 05:18:45 +01:00
|
|
|
|
|
|
|
/// Requirements for a `StableHashingContext` to be used in this crate.
|
|
|
|
/// This is a hack to allow using the `HashStable_Generic` derive macro
|
2021-04-07 14:47:01 -05:00
|
|
|
/// instead of implementing everything in `rustc_middle`.
|
2020-02-29 20:37:32 +03:00
|
|
|
pub trait HashStableContext:
|
|
|
|
rustc_ast::HashStableContext + rustc_target::HashStableContext
|
|
|
|
{
|
2020-01-02 05:18:45 +01:00
|
|
|
fn hash_hir_id(&mut self, _: HirId, hasher: &mut StableHasher);
|
|
|
|
fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
|
2020-02-05 11:11:34 +01:00
|
|
|
fn hash_reference_to_item(&mut self, _: HirId, hasher: &mut StableHasher);
|
2020-01-02 05:18:45 +01:00
|
|
|
fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
|
|
|
|
fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
|
|
|
|
fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
|
2020-02-07 11:14:47 +01:00
|
|
|
fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F);
|
2021-09-19 22:07:12 +02:00
|
|
|
fn hash_hir_trait_candidate(&mut self, _: &TraitCandidate, hasher: &mut StableHasher);
|
2020-02-07 18:25:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
|
|
|
|
type KeyType = (DefPathHash, ItemLocalId);
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
|
2021-04-19 22:27:49 +02:00
|
|
|
let def_path_hash = self.owner.to_stable_hash_key(hcx);
|
2020-02-07 18:25:36 +01:00
|
|
|
(def_path_hash, self.local_id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-19 23:03:21 +02:00
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemLocalId {
|
|
|
|
type KeyType = ItemLocalId;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn to_stable_hash_key(&self, _: &HirCtx) -> ItemLocalId {
|
|
|
|
*self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for BodyId {
|
|
|
|
type KeyType = (DefPathHash, ItemLocalId);
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
|
|
|
|
let BodyId { hir_id } = *self;
|
|
|
|
hir_id.to_stable_hash_key(hcx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-30 12:06:04 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
|
2021-01-30 17:47:51 +01:00
|
|
|
type KeyType = DefPathHash;
|
2021-01-30 12:06:04 +01:00
|
|
|
|
|
|
|
#[inline]
|
2021-01-30 17:47:51 +01:00
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
|
2021-04-19 22:27:49 +02:00
|
|
|
self.def_id.to_stable_hash_key(hcx)
|
2021-01-30 12:06:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-07 18:25:36 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
|
2021-01-30 20:46:50 +01:00
|
|
|
type KeyType = DefPathHash;
|
2020-02-07 18:25:36 +01:00
|
|
|
|
|
|
|
#[inline]
|
2021-01-30 20:46:50 +01:00
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
|
2021-04-19 22:27:49 +02:00
|
|
|
self.def_id.to_stable_hash_key(hcx)
|
2020-02-07 18:25:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
|
2021-01-30 23:25:03 +01:00
|
|
|
type KeyType = DefPathHash;
|
2020-02-07 18:25:36 +01:00
|
|
|
|
|
|
|
#[inline]
|
2021-01-30 23:25:03 +01:00
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
|
2021-04-19 22:27:49 +02:00
|
|
|
self.def_id.to_stable_hash_key(hcx)
|
2020-02-07 18:25:36 +01:00
|
|
|
}
|
2020-01-02 05:18:45 +01:00
|
|
|
}
|
|
|
|
|
2020-11-11 21:57:54 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
|
2021-02-01 00:33:38 +01:00
|
|
|
type KeyType = DefPathHash;
|
2020-11-11 21:57:54 +01:00
|
|
|
|
|
|
|
#[inline]
|
2021-02-01 00:33:38 +01:00
|
|
|
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
|
2021-04-19 22:27:49 +02:00
|
|
|
self.def_id.to_stable_hash_key(hcx)
|
2020-11-11 21:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-02 05:18:45 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HirId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_hir_id(*self, hasher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for BodyId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_body_id(*self, hasher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-05 11:29:07 +01:00
|
|
|
// The following implementations of HashStable for `ItemId`, `TraitItemId`, and
|
|
|
|
// `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
|
|
|
|
// the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
|
|
|
|
// are used when another item in the HIR is *referenced* and we certainly
|
|
|
|
// want to pick up on a reference changing its target, so we hash the NodeIds
|
|
|
|
// in "DefPath Mode".
|
|
|
|
|
2020-01-02 05:18:45 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ItemId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2021-01-30 17:47:51 +01:00
|
|
|
hcx.hash_reference_to_item(self.hir_id(), hasher)
|
2020-01-02 05:18:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-11 21:57:54 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItemId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2021-02-01 00:33:38 +01:00
|
|
|
hcx.hash_reference_to_item(self.hir_id(), hasher)
|
2020-11-11 21:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-02 05:18:45 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2021-01-30 23:25:03 +01:00
|
|
|
hcx.hash_reference_to_item(self.hir_id(), hasher)
|
2020-01-02 05:18:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItemId {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2021-01-30 20:46:50 +01:00
|
|
|
hcx.hash_reference_to_item(self.hir_id(), hasher)
|
2020-01-02 05:18:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_hir_expr(self, hasher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Ty<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_hir_ty(self, hasher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for VisibilityKind<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_hir_visibility_kind(self, hasher)
|
|
|
|
}
|
|
|
|
}
|
2020-02-07 11:14:47 +01:00
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItem<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2020-11-27 09:41:53 +01:00
|
|
|
let TraitItem { def_id: _, ident, ref generics, ref kind, span } = *self;
|
2020-02-07 11:14:47 +01:00
|
|
|
|
|
|
|
hcx.hash_hir_item_like(|hcx| {
|
|
|
|
ident.name.hash_stable(hcx, hasher);
|
|
|
|
generics.hash_stable(hcx, hasher);
|
|
|
|
kind.hash_stable(hcx, hasher);
|
|
|
|
span.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItem<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2020-11-27 09:55:10 +01:00
|
|
|
let ImplItem { def_id: _, ident, ref vis, defaultness, ref generics, ref kind, span } =
|
|
|
|
*self;
|
2020-02-07 11:14:47 +01:00
|
|
|
|
|
|
|
hcx.hash_hir_item_like(|hcx| {
|
|
|
|
ident.name.hash_stable(hcx, hasher);
|
|
|
|
vis.hash_stable(hcx, hasher);
|
|
|
|
defaultness.hash_stable(hcx, hasher);
|
|
|
|
generics.hash_stable(hcx, hasher);
|
|
|
|
kind.hash_stable(hcx, hasher);
|
|
|
|
span.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-01 00:33:38 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItem<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2020-11-27 00:35:22 +01:00
|
|
|
let ForeignItem { def_id: _, ident, ref kind, span, ref vis } = *self;
|
2021-02-01 00:33:38 +01:00
|
|
|
|
|
|
|
hcx.hash_hir_item_like(|hcx| {
|
|
|
|
ident.name.hash_stable(hcx, hasher);
|
|
|
|
kind.hash_stable(hcx, hasher);
|
|
|
|
span.hash_stable(hcx, hasher);
|
|
|
|
vis.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-07 11:14:47 +01:00
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
2021-01-24 13:17:54 +01:00
|
|
|
let Item { ident, def_id: _, ref kind, ref vis, span } = *self;
|
2020-02-07 11:14:47 +01:00
|
|
|
|
|
|
|
hcx.hash_hir_item_like(|hcx| {
|
|
|
|
ident.name.hash_stable(hcx, hasher);
|
|
|
|
kind.hash_stable(hcx, hasher);
|
|
|
|
vis.hash_stable(hcx, hasher);
|
|
|
|
span.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2021-09-12 03:19:18 +02:00
|
|
|
|
2021-12-13 21:33:53 -07:00
|
|
|
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
|
2021-09-12 03:19:18 +02:00
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
// We ignore the `nodes` and `bodies` fields since these refer to information included in
|
|
|
|
// `hash` which is hashed in the collector and used for the crate hash.
|
2021-11-21 19:04:47 +01:00
|
|
|
let OwnerNodes {
|
|
|
|
hash_including_bodies,
|
|
|
|
hash_without_bodies: _,
|
|
|
|
nodes: _,
|
|
|
|
bodies: _,
|
|
|
|
local_id_to_def_id: _,
|
|
|
|
} = *self;
|
2021-10-11 22:36:37 +02:00
|
|
|
hash_including_bodies.hash_stable(hcx, hasher);
|
2021-09-12 03:19:18 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-12 11:41:35 +02:00
|
|
|
|
2021-12-13 21:33:53 -07:00
|
|
|
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
|
2021-09-12 11:41:35 +02:00
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
// We ignore the `map` since it refers to information included in `hash` which is hashed in
|
|
|
|
// the collector and used for the crate hash.
|
|
|
|
let AttributeMap { hash, map: _ } = *self;
|
|
|
|
hash.hash_stable(hcx, hasher);
|
|
|
|
}
|
|
|
|
}
|
2021-09-19 22:07:12 +02:00
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
let Crate { owners: _, hir_hash } = self;
|
|
|
|
hir_hash.hash_stable(hcx, hasher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitCandidate {
|
|
|
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
|
|
hcx.hash_hir_trait_candidate(self, hasher)
|
|
|
|
}
|
|
|
|
}
|