about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/dep_graph/graph.rs18
-rw-r--r--src/librustc/dep_graph/raii.rs18
2 files changed, 35 insertions, 1 deletions
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index bb027b11b45..ca441c4bc3f 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -38,6 +38,10 @@ struct DepGraphData {
 
     /// Work-products that we generate in this run.
     work_products: RefCell<FnvHashMap<Arc<WorkProductId>, WorkProduct>>,
+
+    /// Tracks nodes that are forbidden to read/write; see
+    /// `DepGraph::forbid`. Used for debugging only.
+    forbidden: RefCell<Vec<DepNode<DefId>>>,
 }
 
 impl DepGraph {
@@ -46,7 +50,8 @@ impl DepGraph {
             data: Rc::new(DepGraphData {
                 thread: DepGraphThreadData::new(enabled),
                 previous_work_products: RefCell::new(FnvHashMap()),
-                work_products: RefCell::new(FnvHashMap())
+                work_products: RefCell::new(FnvHashMap()),
+                forbidden: RefCell::new(Vec::new()),
             })
         }
     }
@@ -70,6 +75,15 @@ impl DepGraph {
         raii::DepTask::new(&self.data.thread, key)
     }
 
+    /// Debugging aid -- forbid reads/writes to `key` while the return
+    /// value is in scope. Note that this is only available when debug
+    /// assertions are enabled -- you should not check in code that
+    /// invokes this function.
+    #[cfg(debug_assertions)]
+    pub fn forbid<'graph>(&'graph self, key: DepNode<DefId>) -> raii::Forbid<'graph> {
+        raii::Forbid::new(&self.data.forbidden, key)
+    }
+
     pub fn with_ignore<OP,R>(&self, op: OP) -> R
         where OP: FnOnce() -> R
     {
@@ -85,10 +99,12 @@ impl DepGraph {
     }
 
     pub fn read(&self, v: DepNode<DefId>) {
+        debug_assert!(!self.data.forbidden.borrow().contains(&v));
         self.data.thread.enqueue(DepMessage::Read(v));
     }
 
     pub fn write(&self, v: DepNode<DefId>) {
+        debug_assert!(!self.data.forbidden.borrow().contains(&v));
         self.data.thread.enqueue(DepMessage::Write(v));
     }
 
diff --git a/src/librustc/dep_graph/raii.rs b/src/librustc/dep_graph/raii.rs
index c43d493d176..b344eb48624 100644
--- a/src/librustc/dep_graph/raii.rs
+++ b/src/librustc/dep_graph/raii.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
+use std::cell::RefCell;
 use super::DepNode;
 use super::thread::{DepGraphThreadData, DepMessage};
 
@@ -47,3 +48,20 @@ impl<'graph> Drop for IgnoreTask<'graph> {
         self.data.enqueue(DepMessage::PopIgnore);
     }
 }
+
+pub struct Forbid<'graph> {
+    forbidden: &'graph RefCell<Vec<DepNode<DefId>>>
+}
+
+impl<'graph> Forbid<'graph> {
+    pub fn new(forbidden: &'graph RefCell<Vec<DepNode<DefId>>>, node: DepNode<DefId>) -> Self {
+        forbidden.borrow_mut().push(node);
+        Forbid { forbidden: forbidden }
+    }
+}
+
+impl<'graph> Drop for Forbid<'graph> {
+    fn drop(&mut self) {
+        self.forbidden.borrow_mut().pop();
+    }
+}