about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-09-22 15:07:51 +0200
committerMichael Woerister <michaelwoerister@posteo>2017-09-23 19:47:46 +0200
commit45a03f153fe4da92a579108bff135cc822cd8700 (patch)
tree7a73caf137855b5f566adcacba3450184e439c36
parent2a50d127ddc8a40c526d3409159a328517a6ff84 (diff)
downloadrust-45a03f153fe4da92a579108bff135cc822cd8700.tar.gz
rust-45a03f153fe4da92a579108bff135cc822cd8700.zip
incr.comp.: Make #[rustc_dirty/clean] test for fingerprint equality instead of DepNode existence.
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs105
-rw-r--r--src/librustc_incremental/persist/load.rs4
-rw-r--r--src/librustc_incremental/persist/save.rs1
-rw-r--r--src/test/incremental/dirty_clean.rs4
-rw-r--r--src/test/incremental/hashes/enum_defs.rs2
-rw-r--r--src/test/incremental/string_constant.rs5
6 files changed, 33 insertions, 88 deletions
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 126057fd043..a6d39a91863 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -8,18 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Debugging code to test the state of the dependency graph just
-//! after it is loaded from disk and just after it has been saved.
+//! Debugging code to test fingerprints computed for query results.
 //! For each node marked with `#[rustc_clean]` or `#[rustc_dirty]`,
-//! we will check that a suitable node for that item either appears
-//! or does not appear in the dep-graph, as appropriate:
+//! we will compare the fingerprint from the current and from the previous
+//! compilation session as appropriate:
 //!
 //! - `#[rustc_dirty(label="TypeckTables", cfg="rev2")]` if we are
-//!   in `#[cfg(rev2)]`, then there MUST NOT be a node
-//!   `DepNode::TypeckTables(X)` where `X` is the def-id of the
-//!   current node.
+//!   in `#[cfg(rev2)]`, then the fingerprints associated with
+//!   `DepNode::TypeckTables(X)` must be DIFFERENT (`X` is the def-id of the
+//!   current node).
 //! - `#[rustc_clean(label="TypeckTables", cfg="rev2")]` same as above,
-//!   except that the node MUST exist.
+//!   except that the fingerprints must be the SAME.
 //!
 //! Errors are reported if we are in the suitable configuration but
 //! the required condition is not met.
@@ -40,9 +39,7 @@
 //! previous revision to compare things to.
 //!
 
-use super::data::DepNodeIndex;
-use super::load::DirtyNodes;
-use rustc::dep_graph::{DepGraphQuery, DepNode, DepKind};
+use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -51,41 +48,22 @@ use rustc::ich::{Fingerprint, ATTR_DIRTY, ATTR_CLEAN, ATTR_DIRTY_METADATA,
                  ATTR_CLEAN_METADATA};
 use syntax::ast::{self, Attribute, NestedMetaItem};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use rustc_data_structures::indexed_vec::IndexVec;
 use syntax_pos::Span;
 use rustc::ty::TyCtxt;
 
 const LABEL: &'static str = "label";
 const CFG: &'static str = "cfg";
 
-pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                               nodes: &IndexVec<DepNodeIndex, DepNode>,
-                                               dirty_inputs: &DirtyNodes) {
+pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // can't add `#[rustc_dirty]` etc without opting in to this feature
     if !tcx.sess.features.borrow().rustc_attrs {
         return;
     }
 
     let _ignore = tcx.dep_graph.in_ignore();
-    let dirty_inputs: FxHashSet<DepNode> =
-        dirty_inputs.keys()
-                    .filter_map(|dep_node_index| {
-                        let dep_node = nodes[*dep_node_index];
-                        if dep_node.extract_def_id(tcx).is_some() {
-                            Some(dep_node)
-                        } else {
-                            None
-                        }
-                    })
-                    .collect();
-
-    let query = tcx.dep_graph.query();
-    debug!("query-nodes: {:?}", query.nodes());
     let krate = tcx.hir.krate();
     let mut dirty_clean_visitor = DirtyCleanVisitor {
         tcx,
-        query: &query,
-        dirty_inputs,
         checked_attrs: FxHashSet(),
     };
     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>,
 
 pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    query: &'a DepGraphQuery,
-    dirty_inputs: FxHashSet<DepNode>,
     checked_attrs: FxHashSet<ast::AttrId>,
 }
 
@@ -143,59 +119,28 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
     fn assert_dirty(&self, item_span: Span, dep_node: DepNode) {
         debug!("assert_dirty({:?})", dep_node);
 
-        match dep_node.kind {
-            DepKind::Krate |
-            DepKind::Hir |
-            DepKind::HirBody => {
-                // HIR nodes are inputs, so if we are asserting that the HIR node is
-                // dirty, we check the dirty input set.
-                if !self.dirty_inputs.contains(&dep_node) {
-                    let dep_node_str = self.dep_node_str(&dep_node);
-                    self.tcx.sess.span_err(
-                        item_span,
-                        &format!("`{}` not found in dirty set, but should be dirty",
-                                 dep_node_str));
-                }
-            }
-            _ => {
-                // Other kinds of nodes would be targets, so check if
-                // the dep-graph contains the node.
-                if self.query.contains_node(&dep_node) {
-                    let dep_node_str = self.dep_node_str(&dep_node);
-                    self.tcx.sess.span_err(
-                        item_span,
-                        &format!("`{}` found in dep graph, but should be dirty", dep_node_str));
-                }
-            }
+        let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
+        let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
+
+        if current_fingerprint == prev_fingerprint {
+            let dep_node_str = self.dep_node_str(&dep_node);
+            self.tcx.sess.span_err(
+                item_span,
+                &format!("`{}` should be dirty but is not", dep_node_str));
         }
     }
 
     fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
         debug!("assert_clean({:?})", dep_node);
 
-        match dep_node.kind {
-            DepKind::Krate |
-            DepKind::Hir |
-            DepKind::HirBody => {
-                // For HIR nodes, check the inputs.
-                if self.dirty_inputs.contains(&dep_node) {
-                    let dep_node_str = self.dep_node_str(&dep_node);
-                    self.tcx.sess.span_err(
-                        item_span,
-                        &format!("`{}` found in dirty-node set, but should be clean",
-                                 dep_node_str));
-                }
-            }
-            _ => {
-                // Otherwise, check if the dep-node exists.
-                if !self.query.contains_node(&dep_node) {
-                    let dep_node_str = self.dep_node_str(&dep_node);
-                    self.tcx.sess.span_err(
-                        item_span,
-                        &format!("`{}` not found in dep graph, but should be clean",
-                                 dep_node_str));
-                }
-            }
+        let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
+        let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
+
+        if current_fingerprint != prev_fingerprint {
+            let dep_node_str = self.dep_node_str(&dep_node);
+            self.tcx.sess.span_err(
+                item_span,
+                &format!("`{}` should be clean but is not", dep_node_str));
         }
     }
 
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 28d05a897c8..6d019a25ed3 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -23,7 +23,6 @@ use rustc_serialize::opaque::Decoder;
 use std::path::{Path};
 
 use super::data::*;
-use super::dirty_clean;
 use super::fs::*;
 use super::file_format;
 use super::work_product;
@@ -186,9 +185,6 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // dirty.
     reconcile_work_products(tcx, work_products, &clean_work_products);
 
-    dirty_clean::check_dirty_clean_annotations(tcx,
-                                               &serialized_dep_graph.nodes,
-                                               &dirty_raw_nodes);
     Ok(())
 }
 
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index c9efd97d47b..83a618211da 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -89,6 +89,7 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 |e| encode_dep_graph_new(tcx, e));
     });
 
+    dirty_clean::check_dirty_clean_annotations(tcx);
     dirty_clean::check_dirty_clean_metadata(tcx,
                                             &prev_metadata_hashes,
                                             &current_metadata_hashes);
diff --git a/src/test/incremental/dirty_clean.rs b/src/test/incremental/dirty_clean.rs
index b828cc9c70a..6d54cf53660 100644
--- a/src/test/incremental/dirty_clean.rs
+++ b/src/test/incremental/dirty_clean.rs
@@ -37,7 +37,7 @@ mod y {
 
     #[rustc_clean(label="TypeckTables", cfg="cfail2")]
     pub fn y() {
-        //[cfail2]~^ ERROR `TypeckTables(y::y)` not found in dep graph, but should be clean
+        //[cfail2]~^ ERROR `TypeckTables(y::y)` should be clean but is not
         x::x();
     }
 }
@@ -45,6 +45,6 @@ mod y {
 mod z {
     #[rustc_dirty(label="TypeckTables", cfg="cfail2")]
     pub fn z() {
-        //[cfail2]~^ ERROR `TypeckTables(z::z)` found in dep graph, but should be dirty
+        //[cfail2]~^ ERROR `TypeckTables(z::z)` should be dirty but is not
     }
 }
diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs
index 0f734683b60..8f84266d5a4 100644
--- a/src/test/incremental/hashes/enum_defs.rs
+++ b/src/test/incremental/hashes/enum_defs.rs
@@ -143,7 +143,7 @@ enum EnumChangeValueCStyleVariant1 {
 #[cfg(not(cfail1))]
 #[rustc_dirty(label="Hir", cfg="cfail2")]
 #[rustc_clean(label="Hir", cfg="cfail3")]
-#[rustc_clean(label="HirBody", cfg="cfail2")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
 #[rustc_clean(label="HirBody", cfg="cfail3")]
 #[rustc_metadata_dirty(cfg="cfail2")]
 #[rustc_metadata_clean(cfg="cfail3")]
diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs
index 36a26cf1755..760975b292f 100644
--- a/src/test/incremental/string_constant.rs
+++ b/src/test/incremental/string_constant.rs
@@ -27,7 +27,8 @@ mod x {
     }
 
     #[cfg(rpass2)]
-    #[rustc_dirty(label="TypeckTables", cfg="rpass2")]
+    #[rustc_dirty(label="HirBody", cfg="rpass2")]
+    #[rustc_dirty(label="MirOptimized", cfg="rpass2")]
     pub fn x() {
         println!("{}", "2");
     }
@@ -37,6 +38,7 @@ mod y {
     use x;
 
     #[rustc_clean(label="TypeckTables", cfg="rpass2")]
+    #[rustc_clean(label="MirOptimized", cfg="rpass2")]
     pub fn y() {
         x::x();
     }
@@ -46,6 +48,7 @@ mod z {
     use y;
 
     #[rustc_clean(label="TypeckTables", cfg="rpass2")]
+    #[rustc_clean(label="MirOptimized", cfg="rpass2")]
     pub fn z() {
         y::y();
     }