about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-08-02 19:12:02 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-08-02 19:31:25 -0400
commit54595ecb60e681ecf682af7e76289ef695b23ebc (patch)
treea908df53449c343ce13898431af355c2987df740 /src
parentb13d5041f65df03bd3a34070cb08d339fa629f18 (diff)
downloadrust-54595ecb60e681ecf682af7e76289ef695b23ebc.tar.gz
rust-54595ecb60e681ecf682af7e76289ef695b23ebc.zip
use memoized pattern for SizedConstraint
I cannot figure out how to write a test for this, but I observed
incorrect edges as a result of not using memoized pattern here
(e.g., LateLintCheck -> SizedConstraint).
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/ivar.rs4
-rw-r--r--src/librustc/ty/mod.rs15
2 files changed, 13 insertions, 6 deletions
diff --git a/src/librustc/ty/ivar.rs b/src/librustc/ty/ivar.rs
index 88327ab19a5..634599406af 100644
--- a/src/librustc/ty/ivar.rs
+++ b/src/librustc/ty/ivar.rs
@@ -52,8 +52,10 @@ impl<'tcx, 'lt> TyIVar<'tcx, 'lt> {
         self.untracked_get()
     }
 
+    /// Reads the ivar without registered a dep-graph read. Use with
+    /// caution.
     #[inline]
-    fn untracked_get(&self) -> Option<Ty<'tcx>> {
+    pub fn untracked_get(&self) -> Option<Ty<'tcx>> {
         match self.0.get() {
             None => None,
             // valid because of invariant (A)
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 03e893727d1..a7c53419892 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1757,8 +1757,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer, e.g. issue #31299.
     pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
-        let dep_node = DepNode::SizedConstraint(self.did);
-        match self.sized_constraint.get(dep_node) {
+        match self.sized_constraint.get(DepNode::SizedConstraint(self.did)) {
             None => {
                 let global_tcx = tcx.global_tcx();
                 let this = global_tcx.lookup_adt_def_master(self.did);
@@ -1786,12 +1785,18 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
     ///       such.
     ///     - a TyError, if a type contained itself. The representability
     ///       check should catch this case.
-    fn calculate_sized_constraint_inner(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn calculate_sized_constraint_inner(&'tcx self,
+                                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         stack: &mut Vec<AdtDefMaster<'tcx>>)
     {
-
         let dep_node = || DepNode::SizedConstraint(self.did);
-        if self.sized_constraint.get(dep_node()).is_some() {
+
+        // Follow the memoization pattern: push the computation of
+        // DepNode::SizedConstraint as our current task.
+        let _task = tcx.dep_graph.in_task(dep_node());
+        if self.sized_constraint.untracked_get().is_some() {
+            //                   ---------------
+            // can skip the dep-graph read since we just pushed the task
             return;
         }