Skip to content

Commit 41e3aee

Browse files
authored
Auto merge of #36370 - michaelwoerister:incr-comp-metadata-hashes-check, r=nikomatsakis
ICH: Add ability to test the ICH of exported metadata items. Also adds an example test case for ICH testing. r? @nikomatsakis
2 parents 5a71fb3 + 6a2666d commit 41e3aee

File tree

13 files changed

+622
-115
lines changed

13 files changed

+622
-115
lines changed

src/librustc_incremental/assert_dep_graph.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ use std::io::Write;
5959
use syntax::ast;
6060
use syntax::parse::token::InternedString;
6161
use syntax_pos::Span;
62-
63-
const IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
64-
const THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
62+
use {ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
6563

6664
pub fn assert_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
6765
let _ignore = tcx.dep_graph.in_ignore();
@@ -91,7 +89,7 @@ pub fn assert_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
9189
assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
9290
"cannot use the `#[{}]` or `#[{}]` annotations \
9391
without supplying `-Z query-dep-graph`",
94-
IF_THIS_CHANGED, THEN_THIS_WOULD_NEED);
92+
ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
9593
}
9694

9795
// Check paths.
@@ -125,7 +123,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
125123
fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
126124
let def_id = self.tcx.map.local_def_id(node_id);
127125
for attr in attrs {
128-
if attr.check_name(IF_THIS_CHANGED) {
126+
if attr.check_name(ATTR_IF_THIS_CHANGED) {
129127
let dep_node_interned = self.argument(attr);
130128
let dep_node = match dep_node_interned {
131129
None => DepNode::Hir(def_id),
@@ -141,7 +139,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
141139
}
142140
};
143141
self.if_this_changed.push((attr.span, def_id, dep_node));
144-
} else if attr.check_name(THEN_THIS_WOULD_NEED) {
142+
} else if attr.check_name(ATTR_THEN_THIS_WOULD_NEED) {
145143
let dep_node_interned = self.argument(attr);
146144
let dep_node = match dep_node_interned {
147145
Some(ref n) => {

src/librustc_incremental/calculate_svh/mod.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
//! at the beginning.
2929
3030
use syntax::ast;
31+
use std::cell::RefCell;
3132
use std::hash::{Hash, SipHasher, Hasher};
3233
use rustc::dep_graph::DepNode;
3334
use rustc::hir;
@@ -46,7 +47,42 @@ mod def_path_hash;
4647
mod svh_visitor;
4748
mod caching_codemap_view;
4849

49-
pub type IncrementalHashesMap = FnvHashMap<DepNode<DefId>, u64>;
50+
pub struct IncrementalHashesMap {
51+
hashes: FnvHashMap<DepNode<DefId>, u64>,
52+
53+
// These are the metadata hashes for the current crate as they were stored
54+
// during the last compilation session. They are only loaded if
55+
// -Z query-dep-graph was specified and are needed for auto-tests using
56+
// the #[rustc_metadata_dirty] and #[rustc_metadata_clean] attributes to
57+
// check whether some metadata hash has changed in between two revisions.
58+
pub prev_metadata_hashes: RefCell<FnvHashMap<DefId, u64>>,
59+
}
60+
61+
impl IncrementalHashesMap {
62+
pub fn new() -> IncrementalHashesMap {
63+
IncrementalHashesMap {
64+
hashes: FnvHashMap(),
65+
prev_metadata_hashes: RefCell::new(FnvHashMap()),
66+
}
67+
}
68+
69+
pub fn insert(&mut self, k: DepNode<DefId>, v: u64) -> Option<u64> {
70+
self.hashes.insert(k, v)
71+
}
72+
73+
pub fn iter<'a>(&'a self) -> ::std::collections::hash_map::Iter<'a, DepNode<DefId>, u64> {
74+
self.hashes.iter()
75+
}
76+
}
77+
78+
impl<'a> ::std::ops::Index<&'a DepNode<DefId>> for IncrementalHashesMap {
79+
type Output = u64;
80+
81+
fn index(&self, index: &'a DepNode<DefId>) -> &u64 {
82+
&self.hashes[index]
83+
}
84+
}
85+
5086

5187
pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
5288
-> IncrementalHashesMap {
@@ -55,7 +91,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
5591
let hash_spans = tcx.sess.opts.debuginfo != NoDebugInfo;
5692
let mut visitor = HashItemsVisitor {
5793
tcx: tcx,
58-
hashes: FnvHashMap(),
94+
hashes: IncrementalHashesMap::new(),
5995
def_path_hashes: DefPathHashes::new(tcx),
6096
codemap: CachingCodemapView::new(tcx),
6197
hash_spans: hash_spans,

src/librustc_incremental/calculate_svh/svh_visitor.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,15 @@ use std::hash::{Hash, SipHasher};
3030
use super::def_path_hash::DefPathHashes;
3131
use super::caching_codemap_view::CachingCodemapView;
3232

33-
const IGNORED_ATTRIBUTES: &'static [&'static str] = &["cfg",
34-
"rustc_clean",
35-
"rustc_dirty"];
33+
const IGNORED_ATTRIBUTES: &'static [&'static str] = &[
34+
"cfg",
35+
::ATTR_IF_THIS_CHANGED,
36+
::ATTR_THEN_THIS_WOULD_NEED,
37+
::ATTR_DIRTY,
38+
::ATTR_CLEAN,
39+
::ATTR_DIRTY_METADATA,
40+
::ATTR_CLEAN_METADATA
41+
];
3642

3743
pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
3844
pub tcx: TyCtxt<'hash, 'tcx, 'tcx>,

src/librustc_incremental/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ extern crate serialize as rustc_serialize;
3535
#[macro_use] extern crate syntax;
3636
extern crate syntax_pos;
3737

38+
const ATTR_DIRTY: &'static str = "rustc_dirty";
39+
const ATTR_CLEAN: &'static str = "rustc_clean";
40+
const ATTR_DIRTY_METADATA: &'static str = "rustc_metadata_dirty";
41+
const ATTR_CLEAN_METADATA: &'static str = "rustc_metadata_clean";
42+
const ATTR_IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
43+
const ATTR_THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
44+
3845
mod assert_dep_graph;
3946
mod calculate_svh;
4047
mod persist;

src/librustc_incremental/persist/data.rs

+13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use rustc::dep_graph::{DepNode, WorkProduct, WorkProductId};
1414
use rustc::hir::def_id::DefIndex;
1515
use std::sync::Arc;
16+
use rustc_data_structures::fnv::FnvHashMap;
1617

1718
use super::directory::DefPathIndex;
1819

@@ -93,6 +94,18 @@ pub struct SerializedMetadataHashes {
9394
/// a `DefPathIndex` that gets retracted to the current `DefId`
9495
/// (matching the one found in this structure).
9596
pub hashes: Vec<SerializedMetadataHash>,
97+
98+
/// For each DefIndex (as it occurs in SerializedMetadataHash), this
99+
/// map stores the DefPathIndex (as it occurs in DefIdDirectory), so
100+
/// that we can find the new DefId for a SerializedMetadataHash in a
101+
/// subsequent compilation session.
102+
///
103+
/// This map is only needed for running auto-tests using the
104+
/// #[rustc_metadata_dirty] and #[rustc_metadata_clean] attributes, and
105+
/// is only populated if -Z query-dep-graph is specified. It will be
106+
/// empty otherwise. Importing crates are perfectly happy with just having
107+
/// the DefIndex.
108+
pub index_map: FnvHashMap<DefIndex, DefPathIndex>
96109
}
97110

98111
/// The hash for some metadata that (when saving) will be exported

src/librustc_incremental/persist/directory.rs

-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> {
178178
&self.directory.paths[id.index as usize]
179179
}
180180

181-
182181
pub fn map(&mut self, node: &DepNode<DefId>) -> DepNode<DefPathIndex> {
183182
node.map_def(|&def_id| Some(self.add(def_id))).unwrap()
184183
}

0 commit comments

Comments
 (0)