diff --git a/compiler/rustc_middle/src/ich.rs b/compiler/rustc_middle/src/ich.rs index 80db9a95c918a..21ff78a54fb2d 100644 --- a/compiler/rustc_middle/src/ich.rs +++ b/compiler/rustc_middle/src/ich.rs @@ -22,9 +22,9 @@ enum CachingSourceMap<'a> { /// things (e.g., each `DefId`/`DefPath` is only hashed once). pub struct StableHashState<'a> { untracked: &'a Untracked, - // The value of `-Z incremental-ignore-spans`. - // This field should only be used by `unstable_opts_incremental_ignore_span` - incremental_ignore_spans: bool, + // The session-wide default for `hash_spans`, computed in `Self::new`. Only + // used by `assert_default_stable_hash_controls`. + default_hash_spans: bool, caching_source_map: CachingSourceMap<'a>, stable_hash_controls: StableHashControls, } @@ -32,11 +32,15 @@ pub struct StableHashState<'a> { impl<'a> StableHashState<'a> { #[inline] pub fn new(sess: &'a Session, untracked: &'a Untracked) -> Self { - let hash_spans_initial = !sess.opts.unstable_opts.incremental_ignore_spans; + // Only hash spans for incremental and coverage, where hashes must react to + // code moving around; otherwise skip them and their source map lookups. + // Spans are also skipped if `-Z incremental-ignore-spans` is set. + let hash_spans_initial = (sess.opts.incremental.is_some() || sess.instrument_coverage()) + && !sess.opts.unstable_opts.incremental_ignore_spans; StableHashState { untracked, - incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans, + default_hash_spans: hash_spans_initial, caching_source_map: CachingSourceMap::Unused(sess.source_map()), stable_hash_controls: StableHashControls { hash_spans: hash_spans_initial }, } @@ -178,15 +182,11 @@ impl<'a> StableHashCtxt for StableHashState<'a> { let stable_hash_controls = self.stable_hash_controls; let StableHashControls { hash_spans } = stable_hash_controls; - // Note that we require that `hash_spans` be the inverse of the global `-Z - // incremental-ignore-spans` option. Normally, this option is disabled, in which case - // `hash_spans` must be true. - // - // Span hashing can also be disabled without `-Z incremental-ignore-spans`. This is the - // case for instance when building a hash for name mangling. Such configuration must not be - // used for metadata. + // `hash_spans` must match the session-wide default from `StableHashState::new`, so the + // per-session `ExpnData` hash caches stay consistent. It can be overridden locally via + // `while_hashing_spans` (e.g. for name mangling), but that must not be used for metadata. assert_eq!( - hash_spans, !self.incremental_ignore_spans, + hash_spans, self.default_hash_spans, "Attempted hashing of {msg} with non-default StableHashControls: {stable_hash_controls:?}" ); } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 8b7a2ccb232d0..4e21e4e14b8f5 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -100,7 +100,12 @@ fn encode_query_values_inner<'a, 'tcx, C, V>( } pub(crate) fn verify_query_key_hashes<'tcx>(tcx: TyCtxt<'tcx>) { - if tcx.sess.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) { + // Only run this if the dep graph is enabled. Otherwise there are no `DepNode`s + // to collide, and non-incremental builds skip span hashing, so keys differing + // only in spans collide by design. + if tcx.dep_graph.is_fully_enabled() + && (tcx.sess.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions)) + { tcx.sess.time("verify_query_key_hashes", || { for_each_query_vtable!(ALL, tcx, |query| { verify_query_key_hashes_inner(query, tcx); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 5015741f10c5f..05095a0d99404 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1983,8 +1983,9 @@ impl Encodable for SourceFile { self.normalized_source_len.encode(s); self.unnormalized_source_len.encode(s); - // We are always in `Lines` form by the time we reach here. - assert!(self.lines.read().is_lines()); + // Imported files may still be in compressed `Diffs` form if nothing needed + // their line table (non-incremental builds do not force the conversion by + // hashing spans). `lines()` converts on demand. let lines = self.lines(); // Store the length. s.emit_u32(lines.len() as u32);