Skip to content

Commit d47cf08

Browse files
committedMay 28, 2017
Auto merge of #42175 - michaelwoerister:filemap-hashing-fix-1, r=nikomatsakis
incr.comp.: Track expanded spans instead of FileMaps. This PR removes explicit tracking of FileMaps in response to #42101. The reasoning behind being able to just *not* track access to FileMaps is similar to why we don't track access to the `DefId->DefPath` map: 1. One can only get ahold of a `Span` value by accessing the HIR (for local things) or a `metadata::schema::Entry` (for things from external crates). 2. For both of these things we compute a hash that incorporates the *expanded spans*, that is, what we hash is in the (FileMap independent) format `filename:line:col`. 3. Consequently, everything that emits a span should already be tracked via its dependency to something that has the span included in its hash and changes would be detected via that hash. One caveat here is that we have to be conservative when exporting things in metadata. A crate can be built without debuginfo and would thus by default not incorporate most spans into the metadata hashes. However, a downstream crate can make an inline copy of things in the upstream crate and span changes in the upstream crate would then go undetected, even if the downstream uses them (e.g. by emitting debuginfo for an inlined function). For this reason, we always incorporate spans into metadata hashes for now (there might be more efficient ways to handle this safely when red-green tracking is implemented). r? @nikomatsakis
2 parents bcf9506 + 21dd71f commit d47cf08

File tree

12 files changed

+78
-139
lines changed

12 files changed

+78
-139
lines changed
 

‎src/librustc/dep_graph/dep_node.rs

-2
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ pub enum DepNode<D: Clone + Debug> {
176176
IsMirAvailable(D),
177177
ItemAttrs(D),
178178
FnArgNames(D),
179-
FileMap(D, Arc<String>),
180179
}
181180

182181
impl<D: Clone + Debug> DepNode<D> {
@@ -307,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
307306
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
308307
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
309308
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
310-
FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())),
311309
}
312310
}
313311
}

‎src/librustc/ich/caching_codemap_view.rs

+2-26
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use dep_graph::{DepGraph, DepNode};
12-
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
13-
use rustc_data_structures::bitvec::BitVector;
1411
use std::rc::Rc;
15-
use std::sync::Arc;
1612
use syntax::codemap::CodeMap;
1713
use syntax_pos::{BytePos, FileMap};
1814
use ty::TyCtxt;
@@ -31,14 +27,12 @@ pub struct CachingCodemapView<'tcx> {
3127
codemap: &'tcx CodeMap,
3228
line_cache: [CacheEntry; 3],
3329
time_stamp: usize,
34-
dep_graph: DepGraph,
35-
dep_tracking_reads: BitVector,
3630
}
3731

3832
impl<'tcx> CachingCodemapView<'tcx> {
3933
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
4034
let codemap = tcx.sess.codemap();
41-
let files = codemap.files_untracked();
35+
let files = codemap.files();
4236
let first_file = files[0].clone();
4337
let entry = CacheEntry {
4438
time_stamp: 0,
@@ -50,11 +44,9 @@ impl<'tcx> CachingCodemapView<'tcx> {
5044
};
5145

5246
CachingCodemapView {
53-
dep_graph: tcx.dep_graph.clone(),
5447
codemap: codemap,
5548
line_cache: [entry.clone(), entry.clone(), entry.clone()],
5649
time_stamp: 0,
57-
dep_tracking_reads: BitVector::new(files.len()),
5850
}
5951
}
6052

@@ -67,9 +59,6 @@ impl<'tcx> CachingCodemapView<'tcx> {
6759
for cache_entry in self.line_cache.iter_mut() {
6860
if pos >= cache_entry.line_start && pos < cache_entry.line_end {
6961
cache_entry.time_stamp = self.time_stamp;
70-
if self.dep_tracking_reads.insert(cache_entry.file_index) {
71-
self.dep_graph.read(dep_node(cache_entry));
72-
}
7362

7463
return Some((cache_entry.file.clone(),
7564
cache_entry.line_number,
@@ -90,7 +79,7 @@ impl<'tcx> CachingCodemapView<'tcx> {
9079
// If the entry doesn't point to the correct file, fix it up
9180
if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
9281
let file_valid;
93-
let files = self.codemap.files_untracked();
82+
let files = self.codemap.files();
9483

9584
if files.len() > 0 {
9685
let file_index = self.codemap.lookup_filemap_idx(pos);
@@ -120,21 +109,8 @@ impl<'tcx> CachingCodemapView<'tcx> {
120109
cache_entry.line_end = line_bounds.1;
121110
cache_entry.time_stamp = self.time_stamp;
122111

123-
if self.dep_tracking_reads.insert(cache_entry.file_index) {
124-
self.dep_graph.read(dep_node(cache_entry));
125-
}
126-
127112
return Some((cache_entry.file.clone(),
128113
cache_entry.line_number,
129114
pos - cache_entry.line_start));
130115
}
131116
}
132-
133-
fn dep_node(cache_entry: &CacheEntry) -> DepNode<DefId> {
134-
let def_id = DefId {
135-
krate: CrateNum::from_u32(cache_entry.file.crate_of_origin),
136-
index: CRATE_DEF_INDEX,
137-
};
138-
let name = Arc::new(cache_entry.file.name.clone());
139-
DepNode::FileMap(def_id, name)
140-
}

‎src/librustc/ich/hcx.rs

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
7474
}
7575
}
7676

77+
pub fn force_span_hashing(mut self) -> Self {
78+
self.hash_spans = true;
79+
self
80+
}
81+
7782
#[inline]
7883
pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self,
7984
hash_bodies: bool,

‎src/librustc/ich/impls_mir.rs

+47-3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,55 @@ impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
2222
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
2323
impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
2424
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
25-
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info,
26-
is_user_variable});
25+
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
26+
mutability,
27+
ty,
28+
name,
29+
source_info,
30+
is_user_variable
31+
});
2732
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
2833
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
29-
impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
34+
35+
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Terminator<'tcx> {
36+
#[inline]
37+
fn hash_stable<W: StableHasherResult>(&self,
38+
hcx: &mut StableHashingContext<'a, 'tcx>,
39+
hasher: &mut StableHasher<W>) {
40+
let mir::Terminator {
41+
ref kind,
42+
ref source_info,
43+
} = *self;
44+
45+
let hash_spans_unconditionally = match *kind {
46+
mir::TerminatorKind::Assert { .. } => {
47+
// Assert terminators generate a panic message that contains the
48+
// source location, so we always have to feed its span into the
49+
// ICH.
50+
true
51+
}
52+
mir::TerminatorKind::Goto { .. } |
53+
mir::TerminatorKind::SwitchInt { .. } |
54+
mir::TerminatorKind::Resume |
55+
mir::TerminatorKind::Return |
56+
mir::TerminatorKind::Unreachable |
57+
mir::TerminatorKind::Drop { .. } |
58+
mir::TerminatorKind::DropAndReplace { .. } |
59+
mir::TerminatorKind::Call { .. } => false,
60+
};
61+
62+
if hash_spans_unconditionally {
63+
hcx.while_hashing_spans(true, |hcx| {
64+
source_info.hash_stable(hcx, hasher);
65+
})
66+
} else {
67+
source_info.hash_stable(hcx, hasher);
68+
}
69+
70+
kind.hash_stable(hcx, hasher);
71+
}
72+
}
73+
3074

3175
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
3276
#[inline]

‎src/librustc/session/mod.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo};
1212
pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};
1313

14-
use dep_graph::{DepGraph, DepNode};
15-
use hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX};
14+
use dep_graph::DepGraph;
15+
use hir::def_id::{CrateNum, DefIndex};
16+
1617
use lint;
1718
use middle::cstore::CrateStore;
1819
use middle::dependency_format;
@@ -32,7 +33,7 @@ use syntax::parse::ParseSess;
3233
use syntax::symbol::Symbol;
3334
use syntax::{ast, codemap};
3435
use syntax::feature_gate::AttributeType;
35-
use syntax_pos::{Span, MultiSpan, FileMap};
36+
use syntax_pos::{Span, MultiSpan};
3637

3738
use rustc_back::{LinkerFlavor, PanicStrategy};
3839
use rustc_back::target::Target;
@@ -46,7 +47,6 @@ use std::io::Write;
4647
use std::rc::Rc;
4748
use std::fmt;
4849
use std::time::Duration;
49-
use std::sync::Arc;
5050

5151
mod code_stats;
5252
pub mod config;
@@ -626,21 +626,6 @@ pub fn build_session_(sopts: config::Options,
626626
};
627627
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
628628

629-
// Hook up the codemap with a callback that allows it to register FileMap
630-
// accesses with the dependency graph.
631-
let cm_depgraph = dep_graph.clone();
632-
let codemap_dep_tracking_callback = Box::new(move |filemap: &FileMap| {
633-
let def_id = DefId {
634-
krate: CrateNum::from_u32(filemap.crate_of_origin),
635-
index: CRATE_DEF_INDEX,
636-
};
637-
let name = Arc::new(filemap.name.clone());
638-
let dep_node = DepNode::FileMap(def_id, name);
639-
640-
cm_depgraph.read(dep_node);
641-
});
642-
codemap.set_dep_tracking_callback(codemap_dep_tracking_callback);
643-
644629
let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap);
645630
let default_sysroot = match sopts.maybe_sysroot {
646631
Some(_) => None,

‎src/librustc_incremental/calculate_svh/mod.rs

+1-25
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@
2929
3030
use std::cell::RefCell;
3131
use std::hash::Hash;
32-
use std::sync::Arc;
3332
use rustc::dep_graph::DepNode;
3433
use rustc::hir;
35-
use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId};
34+
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
3635
use rustc::hir::itemlikevisit::ItemLikeVisitor;
3736
use rustc::ich::{Fingerprint, StableHashingContext};
3837
use rustc::ty::TyCtxt;
@@ -155,11 +154,6 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
155154
// We want to incoporate these into the
156155
// SVH.
157156
}
158-
DepNode::FileMap(..) => {
159-
// These don't make a semantic
160-
// difference, filter them out.
161-
return None
162-
}
163157
DepNode::AllLocalTraitImpls => {
164158
// These are already covered by hashing
165159
// the HIR.
@@ -306,24 +300,6 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
306300
visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
307301
}
308302

309-
for filemap in tcx.sess
310-
.codemap()
311-
.files_untracked()
312-
.iter()
313-
.filter(|fm| !fm.is_imported()) {
314-
assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin);
315-
let def_id = DefId {
316-
krate: LOCAL_CRATE,
317-
index: CRATE_DEF_INDEX,
318-
};
319-
let name = Arc::new(filemap.name.clone());
320-
let dep_node = DepNode::FileMap(def_id, name);
321-
let mut hasher = IchHasher::new();
322-
filemap.hash_stable(&mut visitor.hcx, &mut hasher);
323-
let fingerprint = hasher.finish();
324-
visitor.hashes.insert(dep_node, fingerprint);
325-
}
326-
327303
visitor.compute_and_store_ich_for_trait_impls(krate);
328304
});
329305

‎src/librustc_incremental/persist/hash.rs

+1-17
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
5151
match *dep_node {
5252
DepNode::Krate |
5353
DepNode::Hir(_) |
54-
DepNode::HirBody(_) |
55-
DepNode::FileMap(..) =>
54+
DepNode::HirBody(_) =>
5655
true,
5756
DepNode::MetaData(def_id) |
5857
DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(),
@@ -77,20 +76,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
7776
Some(self.incremental_hashes_map[dep_node])
7877
}
7978

80-
DepNode::FileMap(def_id, ref name) => {
81-
if def_id.is_local() {
82-
// We will have been able to retrace the DefId (which is
83-
// always the local CRATE_DEF_INDEX), but the file with the
84-
// given name might have been removed, so we use get() in
85-
// order to allow for that case.
86-
self.incremental_hashes_map.get(dep_node).map(|x| *x)
87-
} else {
88-
Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()),
89-
def_id.krate,
90-
|this| &mut this.global_metadata_hashes))
91-
}
92-
}
93-
9479
// MetaData from other crates is an *input* to us.
9580
// MetaData nodes from *our* crates are an *output*; we
9681
// don't hash them, but we do compute a hash for them and
@@ -242,7 +227,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
242227
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
243228
let dep_node = match dep_node {
244229
DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind),
245-
DepNode::FileMap(_, name) => DepNode::FileMap(def_id, name),
246230
other => {
247231
bug!("unexpected DepNode variant: {:?}", other)
248232
}

‎src/librustc_metadata/encoder.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
1818
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
1919
use rustc::hir::map::definitions::DefPathTable;
2020
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
21-
use rustc::ich::{StableHashingContext, Fingerprint};
21+
use rustc::ich::Fingerprint;
2222
use rustc::middle::dependency_format::Linkage;
2323
use rustc::middle::lang_items;
2424
use rustc::mir;
@@ -29,15 +29,13 @@ use rustc::session::config::{self, CrateTypeProcMacro};
2929
use rustc::util::nodemap::{FxHashMap, NodeSet};
3030

3131
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
32-
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
3332

3433
use std::hash::Hash;
3534
use std::intrinsics;
3635
use std::io::prelude::*;
3736
use std::io::Cursor;
3837
use std::path::Path;
3938
use std::rc::Rc;
40-
use std::sync::Arc;
4139
use std::u32;
4240
use syntax::ast::{self, CRATE_NODE_ID};
4341
use syntax::codemap::Spanned;
@@ -284,7 +282,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
284282
let codemap = self.tcx.sess.codemap();
285283
let all_filemaps = codemap.files();
286284

287-
let hcx = &mut StableHashingContext::new(self.tcx);
288285
let (working_dir, working_dir_was_remapped) = self.tcx.sess.working_dir.clone();
289286

290287
let adapted = all_filemaps.iter()
@@ -316,21 +313,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
316313
adapted.name = abs_path;
317314
Rc::new(adapted)
318315
}
319-
});
320-
321-
let filemaps: Vec<_> = if self.compute_ich {
322-
adapted.inspect(|filemap| {
323-
let mut hasher = StableHasher::new();
324-
filemap.hash_stable(hcx, &mut hasher);
325-
let fingerprint = hasher.finish();
326-
let dep_node = DepNode::FileMap((), Arc::new(filemap.name.clone()));
327-
self.metadata_hashes.global_hashes.push((dep_node, fingerprint));
328-
}).collect()
329-
} else {
330-
adapted.collect()
331-
};
316+
})
317+
.collect::<Vec<_>>();
332318

333-
self.lazy_seq_ref(filemaps.iter().map(|fm| &**fm))
319+
self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
334320
}
335321

336322
fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {

‎src/librustc_metadata/isolated_encoder.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,17 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
3535
tcx: tcx,
3636
ecx: ecx,
3737
hcx: if compute_ich {
38-
Some((StableHashingContext::new(tcx), StableHasher::new()))
38+
// We are always hashing spans for things in metadata because
39+
// don't know if a downstream crate will use them or not.
40+
// Except when -Zquery-dep-graph is specified because we don't
41+
// want to mess up our tests.
42+
let hcx = if tcx.sess.opts.debugging_opts.query_dep_graph {
43+
StableHashingContext::new(tcx)
44+
} else {
45+
StableHashingContext::new(tcx).force_span_hashing()
46+
};
47+
48+
Some((hcx, StableHasher::new()))
3949
} else {
4050
None
4151
}

0 commit comments

Comments
 (0)
Please sign in to comment.