mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-06 08:36:52 -04:00
Move HashStableContext trait to rustc_data_structures.
This puts it in the same crate as the `HashStable` and `ToStableHasher` traits. This requires introducing three types `RawSpan`, `RawDefId` and `RawDefPathHash` to work around the fact that `rustc_data_structures` is upstream of `rustc_span` and so doesn't have access to `Span`, `DefId`, and `DefPathHash`. This is a bit ugly but is worth it because moving `HashStableContext` enables big cleanups across many crates in subsequent commits.
This commit is contained in:
@@ -25,14 +25,13 @@ pub use GenericArgs::*;
|
||||
pub use UnsafeSource::*;
|
||||
pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, HashStableContext, StableHasher};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::tagged_ptr::Tag;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
|
||||
pub use rustc_span::AttrId;
|
||||
use rustc_span::{
|
||||
ByteSymbol, DUMMY_SP, ErrorGuaranteed, HashStableContext, Ident, Span, Spanned, Symbol, kw,
|
||||
respan, sym,
|
||||
ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, respan, sym,
|
||||
};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ use std::ops::Range;
|
||||
use std::sync::Arc;
|
||||
use std::{cmp, fmt, iter, mem};
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, HashStableContext, StableHasher};
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, Symbol, sym};
|
||||
use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::ast::AttrStyle;
|
||||
|
||||
@@ -15,6 +15,34 @@ pub use rustc_stable_hash::{
|
||||
FromStableHash, SipHasher128Hash as StableHasherHash, StableSipHasher128 as StableHasher,
|
||||
};
|
||||
|
||||
/// This trait lets `HashStable` and `derive(HashStable_Generic)` be used in
|
||||
/// this crate (and other crates upstream of `rustc_middle`), while leaving
|
||||
/// certain operations to be defined in `rustc_middle` where more things are
|
||||
/// visible.
|
||||
pub trait HashStableContext {
|
||||
/// The main event: stable hashing of a span.
|
||||
fn span_hash_stable(&mut self, span: RawSpan, hasher: &mut StableHasher);
|
||||
|
||||
/// Compute a `DefPathHash`.
|
||||
fn def_path_hash(&self, def_id: RawDefId) -> RawDefPathHash;
|
||||
|
||||
/// Assert that the provided `HashStableContext` is configured with the default
|
||||
/// `HashingControls`. We should always have bailed out before getting to here with a
|
||||
fn assert_default_hashing_controls(&self, msg: &str);
|
||||
}
|
||||
|
||||
// A type used to work around `Span` not being visible in this crate. It is the same layout as
|
||||
// `Span`.
|
||||
pub struct RawSpan(pub u32, pub u16, pub u16);
|
||||
|
||||
// A type used to work around `DefId` not being visible in this crate. It is the same size as
|
||||
// `DefId`.
|
||||
pub struct RawDefId(pub u32, pub u32);
|
||||
|
||||
// A type used to work around `DefPathHash` not being visible in this crate. It is the same size as
|
||||
// `DefPathHash`.
|
||||
pub struct RawDefPathHash(pub [u8; 16]);
|
||||
|
||||
/// Something that implements `HashStable<Hcx>` can be hashed in a way that is
|
||||
/// stable across multiple compilation sessions.
|
||||
///
|
||||
|
||||
@@ -4,13 +4,13 @@ use std::fmt::Debug;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::stable_hasher::ToStableHashKey;
|
||||
use rustc_data_structures::stable_hasher::{HashStableContext, ToStableHashKey};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::{HashStableContext, Symbol};
|
||||
|
||||
use crate::definitions::DefPathData;
|
||||
use crate::hir;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_span::HashStableContext;
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, HashStableContext, StableHasher, ToStableHashKey,
|
||||
};
|
||||
use rustc_span::def_id::DefPathHash;
|
||||
|
||||
use crate::HashIgnoredAttrId;
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
|
||||
use std::fmt::{self, Debug};
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, HashStableContext, StableHasher, StableOrd, ToStableHashKey,
|
||||
};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::HashStableContext;
|
||||
use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
|
||||
@@ -5,14 +5,14 @@ use rustc_ast::AttrId;
|
||||
use rustc_ast::attr::AttributeExt;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, StableCompare, StableHasher, ToStableHashKey,
|
||||
HashStable, HashStableContext, StableCompare, StableHasher, ToStableHashKey,
|
||||
};
|
||||
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_hir_id::{HirId, ItemLocalId};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::def_id::DefPathHash;
|
||||
pub use rustc_span::edition::Edition;
|
||||
use rustc_span::{HashStableContext, Ident, Symbol, sym};
|
||||
use rustc_span::{Ident, Symbol, sym};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use self::Level::*;
|
||||
|
||||
@@ -84,7 +84,9 @@ fn hash_stable_derive_with_mode(
|
||||
match mode {
|
||||
HashStableMode::Normal => {}
|
||||
HashStableMode::Generic => {
|
||||
s.add_where_predicate(parse_quote! { __CTX: ::rustc_span::HashStableContext });
|
||||
s.add_where_predicate(parse_quote! {
|
||||
__CTX: ::rustc_data_structures::stable_hasher::HashStableContext
|
||||
});
|
||||
}
|
||||
HashStableMode::NoContext => {}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use rustc_ast::{self as ast};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, HashStableContext, StableHasher};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@@ -20,7 +20,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::*;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||
use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span};
|
||||
use rustc_span::{ErrorGuaranteed, ExpnId, Span};
|
||||
|
||||
use crate::query::Providers;
|
||||
use crate::ty::{ResolverAstLowering, TyCtxt};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use std::hash::Hash;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, HashStableContext, HashingControls, RawDefId, RawDefPathHash, RawSpan, StableHasher,
|
||||
};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::cstore::Untracked;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{CachingSourceMapView, DUMMY_SP, HashStableContext, Pos, Span};
|
||||
use rustc_span::{CachingSourceMapView, DUMMY_SP, Pos, Span};
|
||||
|
||||
// Very often, we are hashing something that does not need the `CachingSourceMapView`, so we
|
||||
// initialize it lazily.
|
||||
@@ -84,7 +85,7 @@ impl<'a> HashStableContext for StableHashingContext<'a> {
|
||||
///
|
||||
/// IMPORTANT: changes to this method should be reflected in implementations of `SpanEncoder`.
|
||||
#[inline]
|
||||
fn span_hash_stable(&mut self, span: Span, hasher: &mut StableHasher) {
|
||||
fn span_hash_stable(&mut self, raw_span: RawSpan, hasher: &mut StableHasher) {
|
||||
const TAG_VALID_SPAN: u8 = 0;
|
||||
const TAG_INVALID_SPAN: u8 = 1;
|
||||
const TAG_RELATIVE_SPAN: u8 = 2;
|
||||
@@ -93,6 +94,7 @@ impl<'a> HashStableContext for StableHashingContext<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
let span = Span::from_raw_span(raw_span);
|
||||
let span = span.data_untracked();
|
||||
span.ctxt.hash_stable(self, hasher);
|
||||
span.parent.hash_stable(self, hasher);
|
||||
@@ -157,12 +159,14 @@ impl<'a> HashStableContext for StableHashingContext<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||
fn def_path_hash(&self, raw_def_id: RawDefId) -> RawDefPathHash {
|
||||
let def_id = DefId::from_raw_def_id(raw_def_id);
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
self.untracked.definitions.read().def_path_hash(def_id)
|
||||
} else {
|
||||
self.untracked.cstore.read().def_path_hash(def_id)
|
||||
}
|
||||
.to_raw_def_path_hash()
|
||||
}
|
||||
|
||||
/// Assert that the provided `HashStableContext` is configured with the default
|
||||
|
||||
@@ -14,7 +14,9 @@ use std::{cmp, fs, iter};
|
||||
|
||||
use externs::{ExternOpt, split_extern_opt};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStableContext, StableHasher, StableOrd, ToStableHashKey,
|
||||
};
|
||||
use rustc_errors::emitter::HumanReadableErrorType;
|
||||
use rustc_errors::{ColorConfig, DiagCtxtFlags};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
@@ -23,8 +25,7 @@ use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
|
||||
use rustc_span::source_map::FilePathMapping;
|
||||
use rustc_span::{
|
||||
FileName, HashStableContext, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm,
|
||||
Symbol, sym,
|
||||
FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym,
|
||||
};
|
||||
use rustc_target::spec::{
|
||||
FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
|
||||
|
||||
@@ -3,14 +3,17 @@ use std::hash::{BuildHasherDefault, Hash, Hasher};
|
||||
|
||||
use rustc_data_structures::AtomicRef;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, HashStableContext, RawDefId, RawDefPathHash, StableHasher, StableOrd,
|
||||
ToStableHashKey,
|
||||
};
|
||||
use rustc_data_structures::unhash::Unhasher;
|
||||
use rustc_hashes::Hash64;
|
||||
use rustc_index::Idx;
|
||||
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
|
||||
use crate::{HashStableContext, SpanDecoder, SpanEncoder, Symbol};
|
||||
use crate::{SpanDecoder, SpanEncoder, Symbol};
|
||||
|
||||
pub type StableCrateIdMap =
|
||||
indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
|
||||
@@ -114,6 +117,16 @@ impl DefPathHash {
|
||||
pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
|
||||
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_raw_def_path_hash(self) -> RawDefPathHash {
|
||||
RawDefPathHash(self.0.to_le_bytes())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_raw_def_path_hash(RawDefPathHash(a): RawDefPathHash) -> DefPathHash {
|
||||
DefPathHash(Fingerprint::from_le_bytes(a))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DefPathHash {
|
||||
@@ -312,6 +325,18 @@ impl DefId {
|
||||
pub fn is_top_level_module(self) -> bool {
|
||||
self.is_local() && self.is_crate_root()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_raw_def_id(self) -> RawDefId {
|
||||
// Field order must match `from_raw_def_id`.
|
||||
RawDefId(self.krate.as_u32(), self.index.as_u32())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_raw_def_id(RawDefId(a, b): RawDefId) -> DefId {
|
||||
// Field order must match `to_raw_def_id`.
|
||||
DefId { krate: a.into(), index: b.into() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LocalDefId> for DefId {
|
||||
@@ -428,7 +453,7 @@ impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for DefId {
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, hcx: &mut Hcx) -> DefPathHash {
|
||||
hcx.def_path_hash(*self)
|
||||
DefPathHash::from_raw_def_path_hash(hcx.def_path_hash(self.to_raw_def_id()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@ use std::{fmt, iter, mem};
|
||||
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
HashStable, HashStableContext, StableHasher, ToStableHashKey,
|
||||
};
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_hashes::Hash64;
|
||||
@@ -43,7 +45,7 @@ use crate::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, StableCrateId};
|
||||
use crate::edition::Edition;
|
||||
use crate::source_map::SourceMap;
|
||||
use crate::symbol::{Symbol, kw, sym};
|
||||
use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals};
|
||||
use crate::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, with_session_globals};
|
||||
|
||||
/// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
|
||||
///
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
extern crate self as rustc_span;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_data_structures::stable_hasher::HashStableContext;
|
||||
use rustc_data_structures::{AtomicRef, outline};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
|
||||
@@ -53,7 +54,7 @@ pub use hygiene::{
|
||||
DesugaringKind, ExpnData, ExpnHash, ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext,
|
||||
};
|
||||
pub mod def_id;
|
||||
use def_id::{CrateNum, DefId, DefIndex, DefPathHash, LOCAL_CRATE, LocalDefId, StableCrateId};
|
||||
use def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, StableCrateId};
|
||||
pub mod edit_distance;
|
||||
mod span_encoding;
|
||||
pub use span_encoding::{DUMMY_SP, Span};
|
||||
@@ -2796,29 +2797,13 @@ impl InnerSpan {
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait lets `HashStable` and `derive(HashStable_Generic)` be used in
|
||||
/// this crate (and other crates upstream of `rustc_middle`), while leaving
|
||||
/// certain operations to be defined in `rustc_middle` where more things are
|
||||
/// visible.
|
||||
pub trait HashStableContext {
|
||||
/// The main event: stable hashing of a span.
|
||||
fn span_hash_stable(&mut self, span: Span, hasher: &mut StableHasher);
|
||||
|
||||
/// Compute a `DefPathHash`.
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
|
||||
|
||||
/// Assert that the provided `HashStableContext` is configured with the default
|
||||
/// `HashingControls`. We should always have bailed out before getting to here with a
|
||||
fn assert_default_hashing_controls(&self, msg: &str);
|
||||
}
|
||||
|
||||
impl<Hcx> HashStable<Hcx> for Span
|
||||
where
|
||||
Hcx: HashStableContext,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
|
||||
// `span_hash_stable` does all the work.
|
||||
hcx.span_hash_stable(*self, hasher)
|
||||
hcx.span_hash_stable(self.to_raw_span(), hasher)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::stable_hasher::RawSpan;
|
||||
// This code is very hot and uses lots of arithmetic, avoid overflow checks for performance.
|
||||
// See https://github.com/rust-lang/rust/pull/119440#issuecomment-1874255727
|
||||
use rustc_serialize::int_overflow::DebugStrictAdd;
|
||||
@@ -441,6 +442,18 @@ impl Span {
|
||||
Interned(span) => interned_parent(span.index),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_raw_span(self) -> RawSpan {
|
||||
// Field order must match `from_raw_span`.
|
||||
RawSpan(self.lo_or_index, self.len_with_tag_or_marker, self.ctxt_or_parent_or_marker)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_raw_span(RawSpan(a, b, c): RawSpan) -> Span {
|
||||
// Field order must match `to_raw_span`.
|
||||
Span { lo_or_index: a, len_with_tag_or_marker: b, ctxt_or_parent_or_marker: c }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
||||
Reference in New Issue
Block a user