diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index e569a9bc7df40..837aa9360c895 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -24,6 +24,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::intravisit; use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN}; use rustc::ty::TyCtxt; +use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashSet; use syntax::ast::{self, Attribute, NestedMetaItem}; use syntax::symbol::{Symbol, sym}; @@ -71,6 +72,7 @@ const BASE_IMPL: &[&str] = &[ /// code, i.e., functions+methods const BASE_MIR: &[&str] = &[ label_strs::optimized_mir, + label_strs::promoted_mir, label_strs::mir_built, ]; @@ -472,11 +474,10 @@ impl DirtyCleanVisitor<'tcx> { fn assert_dirty(&self, item_span: Span, dep_node: DepNode) { debug!("assert_dirty({:?})", dep_node); - let dep_node_index = self.tcx.dep_graph.dep_node_index_of(&dep_node); - let current_fingerprint = self.tcx.dep_graph.fingerprint_of(dep_node_index); + let current_fingerprint = self.get_fingerprint(&dep_node); let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node); - if Some(current_fingerprint) == prev_fingerprint { + if current_fingerprint == prev_fingerprint { let dep_node_str = self.dep_node_str(&dep_node); self.tcx.sess.span_err( item_span, @@ -484,14 +485,28 @@ impl DirtyCleanVisitor<'tcx> { } } + fn get_fingerprint(&self, dep_node: &DepNode) -> Option { + if self.tcx.dep_graph.dep_node_exists(dep_node) { + let dep_node_index = self.tcx.dep_graph.dep_node_index_of(dep_node); + Some(self.tcx.dep_graph.fingerprint_of(dep_node_index)) + } else { + None + } + } + fn assert_clean(&self, item_span: Span, dep_node: DepNode) { debug!("assert_clean({:?})", dep_node); - let dep_node_index = self.tcx.dep_graph.dep_node_index_of(&dep_node); - let current_fingerprint = self.tcx.dep_graph.fingerprint_of(dep_node_index); + let current_fingerprint = self.get_fingerprint(&dep_node); let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node); - if Some(current_fingerprint) != prev_fingerprint { + // if the node wasn't previously evaluated and now is (or vice versa), + // then the node isn't actually clean or dirty. + if (current_fingerprint == None) ^ (prev_fingerprint == None) { + return; + } + + if current_fingerprint != prev_fingerprint { let dep_node_str = self.dep_node_str(&dep_node); self.tcx.sess.span_err( item_span, diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs index 5d0b8b867b22f..70820dfaea4a0 100644 --- a/src/test/incremental/hashes/for_loops.rs +++ b/src/test/incremental/hashes/for_loops.rs @@ -94,7 +94,7 @@ pub fn change_iterable() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, promoted_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_iterable() { let mut _x = 0; diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 882383e841957..e98f9b67ca421 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -42,7 +42,10 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")] + #[rustc_clean( + cfg="cfail2", + except="HirBody,optimized_mir,promoted_mir,mir_built,typeck_tables_of" + )] #[rustc_clean(cfg="cfail3")] pub fn method_body() { println!("Hello, world!"); @@ -63,7 +66,10 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")] + #[rustc_clean( + cfg="cfail2", + except="HirBody,optimized_mir,promoted_mir,mir_built,typeck_tables_of" + )] #[rustc_clean(cfg="cfail3")] #[inline] pub fn method_body_inlined() { @@ -97,7 +103,7 @@ impl Foo { #[rustc_clean(cfg="cfail2", except="Hir,HirBody")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_dirty(cfg="cfail2", except="type_of,predicates_of")] + #[rustc_dirty(cfg="cfail2", except="type_of,predicates_of,promoted_mir")] #[rustc_clean(cfg="cfail3")] pub fn method_selfness(&self) { } }