Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 98 additions & 2 deletions compiler/rustc_data_structures/src/stable_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::num::NonZero;

use rustc_index::bit_set::{self, DenseBitSet};
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::StableHash;
use smallvec::SmallVec;
use thin_vec::ThinVec;

Expand Down Expand Up @@ -37,6 +38,25 @@ pub trait StableHashCtxt {
fn assert_default_stable_hash_controls(&self, msg: &str);
}

/// Dummy impl of [`StableHashCtxt`], for code that can't provide a real context,
/// and only wants to compute stable hashes for types that don't rely on the context.
pub struct DummyStableHashCtxt;

impl StableHashCtxt for DummyStableHashCtxt {
fn stable_hash_span(&mut self, _span: RawSpan, _hasher: &mut StableHasher) {
unimplemented!()
}
fn def_path_hash(&self, _def_id: RawDefId) -> Fingerprint {
unimplemented!()
}
fn stable_hash_controls(&self) -> StableHashControls {
unimplemented!()
}
fn assert_default_stable_hash_controls(&self, _msg: &str) {
unimplemented!()
}
}

// A type used to work around `Span` not being visible in this crate. It is the same size as
// `Span` but has a different alignment.
pub struct RawSpan(pub u64);
Expand Down Expand Up @@ -575,8 +595,84 @@ impl<R: Idx, C: Idx> StableHash for bit_set::BitMatrix<R, C> {

impl_stable_traits_for_trivial_type!(::std::ffi::OsStr);

impl_stable_traits_for_trivial_type!(::std::path::Path);
impl_stable_traits_for_trivial_type!(::std::path::PathBuf);
impl StableHash for std::path::Path {
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
use std::path::{Component, Prefix};

#[derive(StableHash)]
enum Tag {
PrefixVerbatim,
PrefixVerbatimUNC,
PrefixVerbatimDisk,
PrefixDeviceNS,
PrefixUNC,
PrefixDisk,
RootDir,
CurDir,
ParentDir,
Normal,
}

for component in self.components() {
match component {
Component::Prefix(prefix) => match prefix.kind() {
Prefix::Verbatim(os_str) => {
Tag::PrefixVerbatim.stable_hash(hcx, hasher);
os_str.stable_hash(hcx, hasher);
}
Prefix::VerbatimUNC(host, share) => {
Tag::PrefixVerbatimUNC.stable_hash(hcx, hasher);
host.stable_hash(hcx, hasher);
share.stable_hash(hcx, hasher);
}
Prefix::VerbatimDisk(letter) => {
Tag::PrefixVerbatimDisk.stable_hash(hcx, hasher);
letter.stable_hash(hcx, hasher);
}
Prefix::DeviceNS(os_str) => {
Tag::PrefixDeviceNS.stable_hash(hcx, hasher);
os_str.stable_hash(hcx, hasher);
}
Prefix::UNC(host, share) => {
Tag::PrefixUNC.stable_hash(hcx, hasher);
host.stable_hash(hcx, hasher);
share.stable_hash(hcx, hasher);
}
Prefix::Disk(letter) => {
Tag::PrefixDisk.stable_hash(hcx, hasher);
letter.stable_hash(hcx, hasher);
}
},
Component::RootDir => Tag::RootDir.stable_hash(hcx, hasher),
Component::CurDir => Tag::CurDir.stable_hash(hcx, hasher),
Component::ParentDir => Tag::ParentDir.stable_hash(hcx, hasher),
Component::Normal(os_str) => {
Tag::Normal.stable_hash(hcx, hasher);
os_str.stable_hash(hcx, hasher);
}
}
}
}
}

impl StableOrd for std::path::Path {
/// FIXME(Zalathar): Unstably sorting paths is pre-existing behavior, but potentially wrong.
const CAN_USE_UNSTABLE_SORT: bool = true;
/// Stdlib path sorting should (hopefully) not change.
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}

impl StableHash for std::path::PathBuf {
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
self.as_path().stable_hash(hcx, hasher);
}
}

impl StableOrd for std::path::PathBuf {
const CAN_USE_UNSTABLE_SORT: bool = <std::path::Path as StableOrd>::CAN_USE_UNSTABLE_SORT;
/// Stdlib path sorting should (hopefully) not change.
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}

// It is not safe to implement StableHash for HashSet, HashMap or any other collection type
// with unstable but observable iteration order.
Expand Down
120 changes: 71 additions & 49 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3370,7 +3370,7 @@ pub(crate) mod dep_tracking {
use rustc_abi::Align;
use rustc_ast::attr::version::RustcVersion;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hash::StableHasher;
use rustc_data_structures::stable_hash::{DummyStableHashCtxt, StableHash, StableHasher};
use rustc_errors::LanguageIdentifier;
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
Expand Down Expand Up @@ -3433,73 +3433,73 @@ pub(crate) mod dep_tracking {
}

impl_dep_tracking_hash_via_hash!(
// tidy-alphabetical-start
(),
Align,
AnnotateMoves,
AutoDiff,
Offload,
bool,
usize,
NonZero<usize>,
u64,
Hash64,
String,
PathBuf,
lint::Level,
WasiExecModel,
u32,
FramePointer,
RelocModel,
BranchProtection,
CFGuard,
CFProtection,
CodeModel,
TlsModel,
InstrumentCoverage,
CodegenRetagOptions,
CollapseMacroDebuginfo,
CoverageOptions,
CrateType,
DebugInfo,
DebugInfoCompression,
Edition,
FmtDebug,
FramePointer,
FunctionReturn,
Hash64,
InliningThreshold,
InstrumentCoverage,
InstrumentMcount,
InstrumentMcountOpts,
InstrumentXRay,
CrateType,
LanguageIdentifier,
LinkerPluginLto,
LocationDetail,
LtoCli,
MergeFunctions,
MirStripDebugInfo,
NativeLib,
NextSolverConfig,
NonZero<usize>,
Offload,
OnBrokenPipe,
OptLevel,
OutFileName,
OutputType,
PanicStrategy,
PatchableFunctionEntry,
PointerAuthOption,
Polonius,
RelocModel,
RelroLevel,
OptLevel,
LtoCli,
DebugInfo,
DebugInfoCompression,
MirStripDebugInfo,
CollapseMacroDebuginfo,
UnstableFeatures,
NativeLib,
SanitizerSet,
CFGuard,
CFProtection,
TargetTuple,
Edition,
LinkerPluginLto,
RemapPathScopeComponents,
ResolveDocLinks,
RustcVersion,
SanitizerSet,
SourceFileHashAlgorithm,
SplitDebuginfo,
SplitDwarfKind,
StackProtector,
String,
SwitchWithOptPath,
SymbolManglingVersion,
SymbolVisibility,
RemapPathScopeComponents,
SourceFileHashAlgorithm,
OutFileName,
OutputType,
RealFileName,
LocationDetail,
FmtDebug,
BranchProtection,
LanguageIdentifier,
NextSolverConfig,
PatchableFunctionEntry,
Polonius,
InliningThreshold,
FunctionReturn,
Align,
CodegenRetagOptions,
RustcVersion,
PointerAuthOption,
TargetTuple,
TlsModel,
UnstableFeatures,
WasiExecModel,
bool,
lint::Level,
u32,
u64,
usize,
// tidy-alphabetical-end
);

impl<T1, T2> DepTrackingHash for (T1, T2)
Expand Down Expand Up @@ -3588,6 +3588,28 @@ pub(crate) mod dep_tracking {
}
}

impl DepTrackingHash for PathBuf {
fn hash(
&self,
hasher: &mut StableHasher,
_error_format: ErrorOutputType,
_for_crate_hash: bool,
) {
self.stable_hash(&mut DummyStableHashCtxt, hasher);
}
}

impl DepTrackingHash for RealFileName {
fn hash(
&self,
hasher: &mut StableHasher,
_error_format: ErrorOutputType,
_for_crate_hash: bool,
) {
self.stable_hash(&mut DummyStableHashCtxt, hasher);
}
}

// This is a stable hash because BTreeMap is a sorted container
pub(crate) fn stable_hash(
sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
Expand Down
22 changes: 11 additions & 11 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
// this crate without this line making `rustc_span` available.
extern crate self as rustc_span;

use rustc_data_structures::stable_hash::StableHashCtxt;
use rustc_data_structures::stable_hash::{DummyStableHashCtxt, StableHashCtxt};
use rustc_data_structures::{AtomicRef, outline};
use rustc_macros::{Decodable, Encodable, StableHash};
use rustc_serialize::opaque::mem_encoder::MemEncoder;
Expand Down Expand Up @@ -315,7 +315,7 @@ pub struct RealFileName {
/// The inner workings of `RealFileName`.
///
/// It contains the `name`, `working_directory` and `embeddable_name` components.
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable, Hash)]
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, StableHash, Decodable, Encodable)]
struct InnerRealFileName {
/// The name.
name: PathBuf,
Expand All @@ -325,18 +325,18 @@ struct InnerRealFileName {
embeddable_name: PathBuf,
}

impl Hash for RealFileName {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
impl StableHash for RealFileName {
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
let RealFileName { local, maybe_remapped, scopes } = self;
// To prevent #70924 from happening again we should only hash the
// remapped path if that exists. This is because remapped paths to
// sysroot crates (/rust/$hash or /rust/$version) remain stable even
// if the corresponding local path changes.
if !self.was_fully_remapped() {
self.local.hash(state);
local.stable_hash(hcx, hasher);
}
self.maybe_remapped.hash(state);
self.scopes.bits().hash(state);
maybe_remapped.stable_hash(hcx, hasher);
scopes.bits().stable_hash(hcx, hasher);
}
}

Expand Down Expand Up @@ -505,7 +505,7 @@ impl RealFileName {
}

/// Differentiates between real files and common virtual files.
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, Decodable, Encodable)]
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, StableHash, Decodable, Encodable)]
pub enum FileName {
Real(RealFileName),
/// Strings provided as `--cfg [cfgspec]`.
Expand Down Expand Up @@ -2160,8 +2160,8 @@ impl StableSourceFileId {
stable_crate_id: Option<StableCrateId>,
) -> Self {
let mut hasher = StableHasher::new();
filename.hash(&mut hasher);
stable_crate_id.hash(&mut hasher);
filename.stable_hash(&mut DummyStableHashCtxt, &mut hasher);
stable_crate_id.stable_hash(&mut DummyStableHashCtxt, &mut hasher);
StableSourceFileId(hasher.finish())
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/tools/clippy/clippy_lints/src/inherent_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::{LocalDefId, LocalModId};
use rustc_hir::{Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass, impl_lint_pass};
use rustc_span::{FileName, Span};
use rustc_span::{Span, StableSourceFileId};
use std::collections::hash_map::Entry;

declare_clippy_lint! {
Expand Down Expand Up @@ -63,7 +63,7 @@ impl MultipleInherentImpl {
#[derive(Hash, Eq, PartialEq, Clone)]
enum Criterion {
Module(LocalModId),
File(FileName),
File(StableSourceFileId),
Crate,
}

Expand Down Expand Up @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
InherentImplLintScope::Module => Criterion::Module(cx.tcx.parent_module(hir_id)),
InherentImplLintScope::File => {
let span = cx.tcx.hir_span(hir_id);
Criterion::File(cx.tcx.sess.source_map().lookup_source_file(span.lo()).name.clone())
Criterion::File(cx.tcx.sess.source_map().lookup_source_file(span.lo()).stable_id)
},
InherentImplLintScope::Crate => Criterion::Crate,
};
Expand Down
Loading