about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Diebold <flodiebold@gmail.com>2016-11-05 20:12:59 +0100
committerFlorian Diebold <florian.diebold@freiheit.com>2016-11-29 13:04:27 +0100
commit936dbbce377157ac1042028da2ad8d6b8183c4de (patch)
treea4256c9e632d905e065d191a00d79e949b2235d2
parent16eedd2a781ebc5944916bc34d50383c4c3acc1e (diff)
downloadrust-936dbbce377157ac1042028da2ad8d6b8183c4de.tar.gz
rust-936dbbce377157ac1042028da2ad8d6b8183c4de.zip
Give function bodies their own dep graph node
-rw-r--r--src/librustc/dep_graph/dep_node.rs5
-rw-r--r--src/librustc/hir/map/mod.rs52
-rw-r--r--src/librustc_const_eval/eval.rs1
-rw-r--r--src/librustc_incremental/calculate_svh/mod.rs19
-rw-r--r--src/librustc_incremental/calculate_svh/svh_visitor.rs25
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs6
-rw-r--r--src/librustc_incremental/persist/hash.rs6
-rw-r--r--src/librustc_incremental/persist/save.rs4
-rw-r--r--src/test/incremental/hello_world.rs2
-rw-r--r--src/test/incremental/ich_method_call_trait_scope.rs4
-rw-r--r--src/test/incremental/ich_nested_items.rs3
-rw-r--r--src/test/incremental/ich_resolve_results.rs8
-rw-r--r--src/test/incremental/source_loc_macros.rs10
-rw-r--r--src/test/incremental/spans_insignificant_w_o_debuginfo.rs1
-rw-r--r--src/test/incremental/spans_significant_w_debuginfo.rs1
15 files changed, 118 insertions, 29 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 397d61d5372..0fc8bf9e17d 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -42,6 +42,9 @@ pub enum DepNode<D: Clone + Debug> {
     // Represents the HIR node with the given node-id
     Hir(D),
 
+    // Represents the body of a function or method
+    HirBody(D),
+
     // Represents the metadata for a given HIR node, typically found
     // in an extern crate.
     MetaData(D),
@@ -150,6 +153,7 @@ impl<D: Clone + Debug> DepNode<D> {
             CollectItem,
             BorrowCheck,
             Hir,
+            HirBody,
             TransCrateItem,
             TypeckItemType,
             TypeckItemBody,
@@ -199,6 +203,7 @@ impl<D: Clone + Debug> DepNode<D> {
             WorkProduct(ref id) => Some(WorkProduct(id.clone())),
 
             Hir(ref d) => op(d).map(Hir),
+            HirBody(ref d) => op(d).map(HirBody),
             MetaData(ref d) => op(d).map(MetaData),
             CollectItem(ref d) => op(d).map(CollectItem),
             CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 33cdb428220..a78f4de475a 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -256,18 +256,39 @@ impl<'ast> Map<'ast> {
         let map = self.map.borrow();
         let mut id = id0;
         if !self.is_inlined_node_id(id) {
+            let mut last_expr = None;
             loop {
                 match map[id.as_usize()] {
                     EntryItem(_, item) => {
                         assert_eq!(id, item.id);
                         let def_id = self.local_def_id(id);
                         assert!(!self.is_inlined_def_id(def_id));
+
+                        if let Some(last_id) = last_expr {
+                            // The body of the item may have a separate dep node
+                            // (Note that impl/trait items don't currently have
+                            // their own dep node, so there's also just one
+                            // HirBody node for all the items)
+                            if self.is_body(last_id, item) {
+                                return DepNode::HirBody(def_id);
+                            }
+                        }
                         return DepNode::Hir(def_id);
                     }
 
-                    EntryImplItem(..) => {
+                    EntryImplItem(_, item) => {
                         let def_id = self.local_def_id(id);
                         assert!(!self.is_inlined_def_id(def_id));
+
+                        if let Some(last_id) = last_expr {
+                            // The body of the item may have a separate dep node
+                            // (Note that impl/trait items don't currently have
+                            // their own dep node, so there's also just one
+                            // HirBody node for all the items)
+                            if self.is_impl_item_body(last_id, item) {
+                                return DepNode::HirBody(def_id);
+                            }
+                        }
                         return DepNode::Hir(def_id);
                     }
 
@@ -275,7 +296,6 @@ impl<'ast> Map<'ast> {
                     EntryTraitItem(p, _) |
                     EntryVariant(p, _) |
                     EntryField(p, _) |
-                    EntryExpr(p, _) |
                     EntryStmt(p, _) |
                     EntryTy(p, _) |
                     EntryTraitRef(p, _) |
@@ -288,6 +308,11 @@ impl<'ast> Map<'ast> {
                     EntryVisibility(p, _) =>
                         id = p,
 
+                    EntryExpr(p, _) => {
+                        last_expr = Some(id);
+                        id = p;
+                    }
+
                     RootCrate =>
                         return DepNode::Krate,
 
@@ -345,6 +370,29 @@ impl<'ast> Map<'ast> {
         }
     }
 
+    fn is_body(&self, node_id: NodeId, item: &Item) -> bool {
+        match item.node {
+            ItemFn(_, _, _, _, _, body) => body.node_id() == node_id,
+            // Since trait/impl items currently don't get their own dep nodes,
+            // we check here whether node_id is the body of any of the items.
+            // Once they get their own dep nodes, this can go away
+            ItemTrait(_, _, _, ref trait_items) => {
+                trait_items.iter().any(|trait_item| { match trait_item.node {
+                    MethodTraitItem(_, Some(body)) => body.node_id() == node_id,
+                    _ => false
+                }})
+            }
+            _ => false
+        }
+    }
+
+    fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool {
+        match item.node {
+            ImplItemKind::Method(_, body) => body.node_id() == node_id,
+            _ => false
+        }
+    }
+
     pub fn num_local_def_ids(&self) -> usize {
         self.definitions.borrow().len()
     }
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index fb5cff56950..7972b9dc098 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -33,7 +33,6 @@ use graphviz::IntoCow;
 use syntax::ast;
 use rustc::hir::{Expr, PatKind};
 use rustc::hir;
-use rustc::hir::intravisit::FnKind;
 use syntax::ptr::P;
 use syntax::codemap;
 use syntax::attr::IntType;
diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs
index 250ef061e51..578732edd83 100644
--- a/src/librustc_incremental/calculate_svh/mod.rs
+++ b/src/librustc_incremental/calculate_svh/mod.rs
@@ -149,19 +149,27 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
     {
         assert!(def_id.is_local());
         debug!("HashItemsVisitor::calculate(def_id={:?})", def_id);
+        self.calculate_def_hash(DepNode::Hir(def_id), false, &mut walk_op);
+        self.calculate_def_hash(DepNode::HirBody(def_id), true, &mut walk_op);
+    }
+
+    fn calculate_def_hash<W>(&mut self, dep_node: DepNode<DefId>, hash_bodies: bool, walk_op: &mut W)
+        where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
+    {
         let mut state = IchHasher::new();
         walk_op(&mut StrictVersionHashVisitor::new(&mut state,
                                                    self.tcx,
                                                    &mut self.def_path_hashes,
                                                    &mut self.codemap,
-                                                   self.hash_spans));
+                                                   self.hash_spans,
+                                                   hash_bodies));
         let bytes_hashed = state.bytes_hashed();
         let item_hash = state.finish();
-        self.hashes.insert(DepNode::Hir(def_id), item_hash);
-        debug!("calculate_item_hash: def_id={:?} hash={:?}", def_id, item_hash);
+        debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
+        self.hashes.insert(dep_node, item_hash);
 
         let bytes_hashed = self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
-                           bytes_hashed;
+            bytes_hashed;
         self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
     }
 
@@ -200,7 +208,8 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
                                                             self.tcx,
                                                             &mut self.def_path_hashes,
                                                             &mut self.codemap,
-                                                            self.hash_spans);
+                                                            self.hash_spans,
+                                                            false);
             visitor.hash_attributes(&krate.attrs);
         }
 
diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs
index e2b141f2ea6..6a045216ce9 100644
--- a/src/librustc_incremental/calculate_svh/svh_visitor.rs
+++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs
@@ -52,6 +52,7 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
     hash_spans: bool,
     codemap: &'a mut CachingCodemapView<'tcx>,
     overflow_checks_enabled: bool,
+    hash_bodies: bool,
 }
 
 impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
@@ -59,7 +60,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
                tcx: TyCtxt<'hash, 'tcx, 'tcx>,
                def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
                codemap: &'a mut CachingCodemapView<'tcx>,
-               hash_spans: bool)
+               hash_spans: bool,
+               hash_bodies: bool)
                -> Self {
         let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
             .unwrap_or(tcx.sess.opts.debug_assertions);
@@ -71,6 +73,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
             hash_spans: hash_spans,
             codemap: codemap,
             overflow_checks_enabled: check_overflow,
+            hash_bodies: hash_bodies,
         }
     }
 
@@ -459,15 +462,16 @@ fn saw_ty(node: &Ty_) -> SawTyComponent {
 #[derive(Hash)]
 enum SawTraitOrImplItemComponent {
     SawTraitOrImplItemConst,
-    SawTraitOrImplItemMethod(Unsafety, Constness, Abi),
+    // The boolean signifies whether a body is present
+    SawTraitOrImplItemMethod(Unsafety, Constness, Abi, bool),
     SawTraitOrImplItemType
 }
 
 fn saw_trait_item(ti: &TraitItem_) -> SawTraitOrImplItemComponent {
     match *ti {
         ConstTraitItem(..) => SawTraitOrImplItemConst,
-        MethodTraitItem(ref sig, _) =>
-            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
+        MethodTraitItem(ref sig, ref body) =>
+            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()),
         TypeTraitItem(..) => SawTraitOrImplItemType
     }
 }
@@ -476,7 +480,7 @@ fn saw_impl_item(ii: &ImplItemKind) -> SawTraitOrImplItemComponent {
     match *ii {
         ImplItemKind::Const(..) => SawTraitOrImplItemConst,
         ImplItemKind::Method(ref sig, _) =>
-            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
+            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
         ImplItemKind::Type(..) => SawTraitOrImplItemType
     }
 }
@@ -509,6 +513,14 @@ macro_rules! hash_span {
 }
 
 impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
+    fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, visit::NestedVisitMode)> {
+        if self.hash_bodies {
+            Some((&self.tcx.map, visit::NestedVisitMode::OnlyBodies))
+        } else {
+            None
+        }
+    }
+
     fn visit_variant_data(&mut self,
                           s: &'tcx VariantData,
                           name: Name,
@@ -609,7 +621,8 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
 
     fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, n: NodeId) {
         debug!("visit_mod: st={:?}", self.st);
-        SawMod.hash(self.st); visit::walk_mod(self, m, n)
+        SawMod.hash(self.st);
+        visit::walk_mod(self, m, n)
     }
 
     fn visit_ty(&mut self, t: &'tcx Ty) {
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 85c35bf79ce..40873011a7b 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -114,7 +114,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
 
         match dep_node {
             DepNode::Krate |
-            DepNode::Hir(_) => {
+            DepNode::Hir(_) |
+            DepNode::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) {
@@ -143,7 +144,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
 
         match dep_node {
             DepNode::Krate |
-            DepNode::Hir(_) => {
+            DepNode::Hir(_) |
+            DepNode::HirBody(_) => {
                 // For HIR nodes, check the inputs.
                 if self.dirty_inputs.contains(&dep_node) {
                     let dep_node_str = self.dep_node_str(&dep_node);
diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs
index 73311ee96c5..562efa4b0d2 100644
--- a/src/librustc_incremental/persist/hash.rs
+++ b/src/librustc_incremental/persist/hash.rs
@@ -45,7 +45,9 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
     pub fn is_hashable(dep_node: &DepNode<DefId>) -> bool {
         match *dep_node {
             DepNode::Krate |
-            DepNode::Hir(_) => true,
+            DepNode::Hir(_) |
+            DepNode::HirBody(_) =>
+                true,
             DepNode::MetaData(def_id) => !def_id.is_local(),
             _ => false,
         }
@@ -58,7 +60,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
             }
 
             // HIR nodes (which always come from our crate) are an input:
-            DepNode::Hir(def_id) => {
+            DepNode::Hir(def_id) | DepNode::HirBody(def_id) => {
                 assert!(def_id.is_local(),
                         "cannot hash HIR for non-local def-id {:?} => {:?}",
                         def_id,
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index 289eebb2162..05e21aa19b1 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -145,8 +145,8 @@ pub fn encode_dep_graph(preds: &Predecessors,
     for (&target, sources) in &preds.inputs {
         match *target {
             DepNode::MetaData(ref def_id) => {
-                // Metadata *targets* are always local metadata nodes. We handle
-                // those in `encode_metadata_hashes`, which comes later.
+                // Metadata *targets* are always local metadata nodes. We have
+                // already handled those in `encode_metadata_hashes`.
                 assert!(def_id.is_local());
                 continue;
             }
diff --git a/src/test/incremental/hello_world.rs b/src/test/incremental/hello_world.rs
index a06c25ac055..7138b4c7604 100644
--- a/src/test/incremental/hello_world.rs
+++ b/src/test/incremental/hello_world.rs
@@ -31,7 +31,7 @@ mod x {
 mod y {
     use x;
 
-    #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
+    #[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
     pub fn y() {
         x::x();
     }
diff --git a/src/test/incremental/ich_method_call_trait_scope.rs b/src/test/incremental/ich_method_call_trait_scope.rs
index f28ecf74dd4..0a36e3c693e 100644
--- a/src/test/incremental/ich_method_call_trait_scope.rs
+++ b/src/test/incremental/ich_method_call_trait_scope.rs
@@ -46,12 +46,14 @@ mod mod3 {
 mod mod3 {
     use Trait2;
 
-    #[rustc_dirty(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_dirty(label="HirBody", cfg="rpass2")]
     fn bar() {
         ().method();
     }
 
     #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="HirBody", cfg="rpass2")]
     fn baz() {
         22; // no method call, traits in scope don't matter
     }
diff --git a/src/test/incremental/ich_nested_items.rs b/src/test/incremental/ich_nested_items.rs
index 4466cfb1317..e8e40d57b1e 100644
--- a/src/test/incremental/ich_nested_items.rs
+++ b/src/test/incremental/ich_nested_items.rs
@@ -23,11 +23,14 @@ fn foo() {
 
 #[cfg(rpass2)]
 #[rustc_clean(label="Hir", cfg="rpass2")]
+#[rustc_clean(label="HirBody", cfg="rpass2")]
 fn foo() {
     #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="HirBody", cfg="rpass2")]
     fn baz() { } // order is different...
 
     #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="HirBody", cfg="rpass2")]
     fn bar() { } // but that doesn't matter.
 
     fn bap() { } // neither does adding a new item
diff --git a/src/test/incremental/ich_resolve_results.rs b/src/test/incremental/ich_resolve_results.rs
index 680a91da09f..49a88c530ff 100644
--- a/src/test/incremental/ich_resolve_results.rs
+++ b/src/test/incremental/ich_resolve_results.rs
@@ -45,11 +45,13 @@ mod mod3 {
     use test;
 
     #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="HirBody", cfg="rpass2")]
     fn in_expr() {
         Foo(0);
     }
 
     #[rustc_clean(label="Hir", cfg="rpass2")]
+    #[rustc_clean(label="HirBody", cfg="rpass2")]
     fn in_type() {
         test::<Foo>();
     }
@@ -60,12 +62,14 @@ mod mod3 {
     use test;
     use mod2::Foo; // <-- This changed!
 
-    #[rustc_dirty(label="Hir", cfg="rpass3")]
+    #[rustc_clean(label="Hir", cfg="rpass3")]
+    #[rustc_dirty(label="HirBody", cfg="rpass3")]
     fn in_expr() {
         Foo(0);
     }
 
-    #[rustc_dirty(label="Hir", cfg="rpass3")]
+    #[rustc_clean(label="Hir", cfg="rpass3")]
+    #[rustc_dirty(label="HirBody", cfg="rpass3")]
     fn in_type() {
         test::<Foo>();
     }
diff --git a/src/test/incremental/source_loc_macros.rs b/src/test/incremental/source_loc_macros.rs
index f922ac0da41..e81f690f5ca 100644
--- a/src/test/incremental/source_loc_macros.rs
+++ b/src/test/incremental/source_loc_macros.rs
@@ -17,17 +17,17 @@
 
 #![feature(rustc_attrs)]
 
-#[rustc_clean(label="Hir", cfg="rpass2")]
+#[rustc_clean(label="HirBody", cfg="rpass2")]
 fn line_same() {
     let _ = line!();
 }
 
-#[rustc_clean(label="Hir", cfg="rpass2")]
+#[rustc_clean(label="HirBody", cfg="rpass2")]
 fn col_same() {
     let _ = column!();
 }
 
-#[rustc_clean(label="Hir", cfg="rpass2")]
+#[rustc_clean(label="HirBody", cfg="rpass2")]
 fn file_same() {
     let _ = file!();
 }
@@ -38,7 +38,7 @@ fn line_different() {
 }
 
 #[cfg(rpass2)]
-#[rustc_dirty(label="Hir", cfg="rpass2")]
+#[rustc_dirty(label="HirBody", cfg="rpass2")]
 fn line_different() {
     let _ = line!();
 }
@@ -49,7 +49,7 @@ fn col_different() {
 }
 
 #[cfg(rpass2)]
-#[rustc_dirty(label="Hir", cfg="rpass2")]
+#[rustc_dirty(label="HirBody", cfg="rpass2")]
 fn col_different() {
     let _ =        column!();
 }
diff --git a/src/test/incremental/spans_insignificant_w_o_debuginfo.rs b/src/test/incremental/spans_insignificant_w_o_debuginfo.rs
index 9c8b8552498..90ec4a9d558 100644
--- a/src/test/incremental/spans_insignificant_w_o_debuginfo.rs
+++ b/src/test/incremental/spans_insignificant_w_o_debuginfo.rs
@@ -22,4 +22,5 @@ pub fn main() {}
 
 #[cfg(rpass2)]
 #[rustc_clean(label="Hir", cfg="rpass2")]
+#[rustc_clean(label="HirBody", cfg="rpass2")]
 pub fn main() {}
diff --git a/src/test/incremental/spans_significant_w_debuginfo.rs b/src/test/incremental/spans_significant_w_debuginfo.rs
index b0920aa1fa5..cdab8de9828 100644
--- a/src/test/incremental/spans_significant_w_debuginfo.rs
+++ b/src/test/incremental/spans_significant_w_debuginfo.rs
@@ -22,4 +22,5 @@ pub fn main() {}
 
 #[cfg(rpass2)]
 #[rustc_dirty(label="Hir", cfg="rpass2")]
+#[rustc_dirty(label="HirBody", cfg="rpass2")]
 pub fn main() {}