Skip to content

Commit 45a03f1

Browse files
incr.comp.: Make #[rustc_dirty/clean] test for fingerprint equality instead of DepNode existence.
1 parent 2a50d12 commit 45a03f1

File tree

6 files changed

+33
-88
lines changed

6 files changed

+33
-88
lines changed

src/librustc_incremental/persist/dirty_clean.rs

+25-80
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Debugging code to test the state of the dependency graph just
12-
//! after it is loaded from disk and just after it has been saved.
11+
//! Debugging code to test fingerprints computed for query results.
1312
//! For each node marked with `#[rustc_clean]` or `#[rustc_dirty]`,
14-
//! we will check that a suitable node for that item either appears
15-
//! or does not appear in the dep-graph, as appropriate:
13+
//! we will compare the fingerprint from the current and from the previous
14+
//! compilation session as appropriate:
1615
//!
1716
//! - `#[rustc_dirty(label="TypeckTables", cfg="rev2")]` if we are
18-
//! in `#[cfg(rev2)]`, then there MUST NOT be a node
19-
//! `DepNode::TypeckTables(X)` where `X` is the def-id of the
20-
//! current node.
17+
//! in `#[cfg(rev2)]`, then the fingerprints associated with
18+
//! `DepNode::TypeckTables(X)` must be DIFFERENT (`X` is the def-id of the
19+
//! current node).
2120
//! - `#[rustc_clean(label="TypeckTables", cfg="rev2")]` same as above,
22-
//! except that the node MUST exist.
21+
//! except that the fingerprints must be the SAME.
2322
//!
2423
//! Errors are reported if we are in the suitable configuration but
2524
//! the required condition is not met.
@@ -40,9 +39,7 @@
4039
//! previous revision to compare things to.
4140
//!
4241
43-
use super::data::DepNodeIndex;
44-
use super::load::DirtyNodes;
45-
use rustc::dep_graph::{DepGraphQuery, DepNode, DepKind};
42+
use rustc::dep_graph::DepNode;
4643
use rustc::hir;
4744
use rustc::hir::def_id::DefId;
4845
use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -51,41 +48,22 @@ use rustc::ich::{Fingerprint, ATTR_DIRTY, ATTR_CLEAN, ATTR_DIRTY_METADATA,
5148
ATTR_CLEAN_METADATA};
5249
use syntax::ast::{self, Attribute, NestedMetaItem};
5350
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
54-
use rustc_data_structures::indexed_vec::IndexVec;
5551
use syntax_pos::Span;
5652
use rustc::ty::TyCtxt;
5753

5854
const LABEL: &'static str = "label";
5955
const CFG: &'static str = "cfg";
6056

61-
pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
62-
nodes: &IndexVec<DepNodeIndex, DepNode>,
63-
dirty_inputs: &DirtyNodes) {
57+
pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
6458
// can't add `#[rustc_dirty]` etc without opting in to this feature
6559
if !tcx.sess.features.borrow().rustc_attrs {
6660
return;
6761
}
6862

6963
let _ignore = tcx.dep_graph.in_ignore();
70-
let dirty_inputs: FxHashSet<DepNode> =
71-
dirty_inputs.keys()
72-
.filter_map(|dep_node_index| {
73-
let dep_node = nodes[*dep_node_index];
74-
if dep_node.extract_def_id(tcx).is_some() {
75-
Some(dep_node)
76-
} else {
77-
None
78-
}
79-
})
80-
.collect();
81-
82-
let query = tcx.dep_graph.query();
83-
debug!("query-nodes: {:?}", query.nodes());
8464
let krate = tcx.hir.krate();
8565
let mut dirty_clean_visitor = DirtyCleanVisitor {
8666
tcx,
87-
query: &query,
88-
dirty_inputs,
8967
checked_attrs: FxHashSet(),
9068
};
9169
krate.visit_all_item_likes(&mut dirty_clean_visitor);
@@ -105,8 +83,6 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10583

10684
pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
10785
tcx: TyCtxt<'a, 'tcx, 'tcx>,
108-
query: &'a DepGraphQuery,
109-
dirty_inputs: FxHashSet<DepNode>,
11086
checked_attrs: FxHashSet<ast::AttrId>,
11187
}
11288

@@ -143,59 +119,28 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
143119
fn assert_dirty(&self, item_span: Span, dep_node: DepNode) {
144120
debug!("assert_dirty({:?})", dep_node);
145121

146-
match dep_node.kind {
147-
DepKind::Krate |
148-
DepKind::Hir |
149-
DepKind::HirBody => {
150-
// HIR nodes are inputs, so if we are asserting that the HIR node is
151-
// dirty, we check the dirty input set.
152-
if !self.dirty_inputs.contains(&dep_node) {
153-
let dep_node_str = self.dep_node_str(&dep_node);
154-
self.tcx.sess.span_err(
155-
item_span,
156-
&format!("`{}` not found in dirty set, but should be dirty",
157-
dep_node_str));
158-
}
159-
}
160-
_ => {
161-
// Other kinds of nodes would be targets, so check if
162-
// the dep-graph contains the node.
163-
if self.query.contains_node(&dep_node) {
164-
let dep_node_str = self.dep_node_str(&dep_node);
165-
self.tcx.sess.span_err(
166-
item_span,
167-
&format!("`{}` found in dep graph, but should be dirty", dep_node_str));
168-
}
169-
}
122+
let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
123+
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
124+
125+
if current_fingerprint == prev_fingerprint {
126+
let dep_node_str = self.dep_node_str(&dep_node);
127+
self.tcx.sess.span_err(
128+
item_span,
129+
&format!("`{}` should be dirty but is not", dep_node_str));
170130
}
171131
}
172132

173133
fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
174134
debug!("assert_clean({:?})", dep_node);
175135

176-
match dep_node.kind {
177-
DepKind::Krate |
178-
DepKind::Hir |
179-
DepKind::HirBody => {
180-
// For HIR nodes, check the inputs.
181-
if self.dirty_inputs.contains(&dep_node) {
182-
let dep_node_str = self.dep_node_str(&dep_node);
183-
self.tcx.sess.span_err(
184-
item_span,
185-
&format!("`{}` found in dirty-node set, but should be clean",
186-
dep_node_str));
187-
}
188-
}
189-
_ => {
190-
// Otherwise, check if the dep-node exists.
191-
if !self.query.contains_node(&dep_node) {
192-
let dep_node_str = self.dep_node_str(&dep_node);
193-
self.tcx.sess.span_err(
194-
item_span,
195-
&format!("`{}` not found in dep graph, but should be clean",
196-
dep_node_str));
197-
}
198-
}
136+
let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
137+
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
138+
139+
if current_fingerprint != prev_fingerprint {
140+
let dep_node_str = self.dep_node_str(&dep_node);
141+
self.tcx.sess.span_err(
142+
item_span,
143+
&format!("`{}` should be clean but is not", dep_node_str));
199144
}
200145
}
201146

src/librustc_incremental/persist/load.rs

-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_serialize::opaque::Decoder;
2323
use std::path::{Path};
2424

2525
use super::data::*;
26-
use super::dirty_clean;
2726
use super::fs::*;
2827
use super::file_format;
2928
use super::work_product;
@@ -186,9 +185,6 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
186185
// dirty.
187186
reconcile_work_products(tcx, work_products, &clean_work_products);
188187

189-
dirty_clean::check_dirty_clean_annotations(tcx,
190-
&serialized_dep_graph.nodes,
191-
&dirty_raw_nodes);
192188
Ok(())
193189
}
194190

src/librustc_incremental/persist/save.rs

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
8989
|e| encode_dep_graph_new(tcx, e));
9090
});
9191

92+
dirty_clean::check_dirty_clean_annotations(tcx);
9293
dirty_clean::check_dirty_clean_metadata(tcx,
9394
&prev_metadata_hashes,
9495
&current_metadata_hashes);

src/test/incremental/dirty_clean.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ mod y {
3737

3838
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
3939
pub fn y() {
40-
//[cfail2]~^ ERROR `TypeckTables(y::y)` not found in dep graph, but should be clean
40+
//[cfail2]~^ ERROR `TypeckTables(y::y)` should be clean but is not
4141
x::x();
4242
}
4343
}
4444

4545
mod z {
4646
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
4747
pub fn z() {
48-
//[cfail2]~^ ERROR `TypeckTables(z::z)` found in dep graph, but should be dirty
48+
//[cfail2]~^ ERROR `TypeckTables(z::z)` should be dirty but is not
4949
}
5050
}

src/test/incremental/hashes/enum_defs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ enum EnumChangeValueCStyleVariant1 {
143143
#[cfg(not(cfail1))]
144144
#[rustc_dirty(label="Hir", cfg="cfail2")]
145145
#[rustc_clean(label="Hir", cfg="cfail3")]
146-
#[rustc_clean(label="HirBody", cfg="cfail2")]
146+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
147147
#[rustc_clean(label="HirBody", cfg="cfail3")]
148148
#[rustc_metadata_dirty(cfg="cfail2")]
149149
#[rustc_metadata_clean(cfg="cfail3")]

src/test/incremental/string_constant.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ mod x {
2727
}
2828

2929
#[cfg(rpass2)]
30-
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
30+
#[rustc_dirty(label="HirBody", cfg="rpass2")]
31+
#[rustc_dirty(label="MirOptimized", cfg="rpass2")]
3132
pub fn x() {
3233
println!("{}", "2");
3334
}
@@ -37,6 +38,7 @@ mod y {
3738
use x;
3839

3940
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
41+
#[rustc_clean(label="MirOptimized", cfg="rpass2")]
4042
pub fn y() {
4143
x::x();
4244
}
@@ -46,6 +48,7 @@ mod z {
4648
use y;
4749

4850
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
51+
#[rustc_clean(label="MirOptimized", cfg="rpass2")]
4952
pub fn z() {
5053
y::y();
5154
}

0 commit comments

Comments
 (0)