about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2018-08-26 22:50:57 -0400
committerWesley Wiser <wwiser@gmail.com>2018-09-06 19:58:22 -0400
commit4e706f56bd3beb0833d9e05b0dabdc3c3ce750e4 (patch)
treee784b157a2104fc1249faf28c0feb49686057d48
parentdb01b6789db9b4f89209ea6e28781dfd66eebbcb (diff)
downloadrust-4e706f56bd3beb0833d9e05b0dabdc3c3ce750e4.tar.gz
rust-4e706f56bd3beb0833d9e05b0dabdc3c3ce750e4.zip
[nll] teach SCC about `'static`
Fixes #53178
-rw-r--r--src/librustc_mir/borrow_check/nll/constraints/graph.rs70
-rw-r--r--src/librustc_mir/borrow_check/nll/constraints/mod.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs3
5 files changed, 71 insertions, 13 deletions
diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs
index 7cf94ec84dc..b1e8b974379 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use borrow_check::nll::type_check::Locations;
 use borrow_check::nll::constraints::{ConstraintIndex, ConstraintSet, OutlivesConstraint};
 use rustc::ty::RegionVid;
 use rustc_data_structures::graph;
@@ -31,6 +32,7 @@ crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
 crate trait ConstraintGraphDirecton: Copy + 'static {
     fn start_region(c: &OutlivesConstraint) -> RegionVid;
     fn end_region(c: &OutlivesConstraint) -> RegionVid;
+    fn is_normal() -> bool;
 }
 
 /// In normal mode, a `R1: R2` constraint results in an edge `R1 ->
@@ -48,6 +50,10 @@ impl ConstraintGraphDirecton for Normal {
     fn end_region(c: &OutlivesConstraint) -> RegionVid {
         c.sub
     }
+
+    fn is_normal() -> bool {
+        true
+    }
 }
 
 /// In reverse mode, a `R1: R2` constraint results in an edge `R2 ->
@@ -65,6 +71,10 @@ impl ConstraintGraphDirecton for Reverse {
     fn end_region(c: &OutlivesConstraint) -> RegionVid {
         c.sup
     }
+
+    fn is_normal() -> bool {
+        false
+    }
 }
 
 impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
@@ -98,8 +108,12 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// Given the constraint set from which this graph was built
     /// creates a region graph so that you can iterate over *regions*
     /// and not constraints.
-    crate fn region_graph<'rg>(&'rg self, set: &'rg ConstraintSet) -> RegionGraph<'rg, D> {
-        RegionGraph::new(set, self)
+    crate fn region_graph<'rg>(
+        &'rg self,
+        set: &'rg ConstraintSet,
+        static_region: RegionVid,
+    ) -> RegionGraph<'rg, D> {
+        RegionGraph::new(set, self, static_region)
     }
 
     /// Given a region `R`, iterate over all constraints `R: R1`.
@@ -107,12 +121,28 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
         &'a self,
         region_sup: RegionVid,
         constraints: &'a ConstraintSet,
+        static_region: RegionVid,
     ) -> Edges<'a, D> {
-        let first = self.first_constraints[region_sup];
-        Edges {
-            graph: self,
-            constraints,
-            pointer: first,
+        //if this is the `'static` region and the graph's direction is normal,
+        //then setup the Edges iterator to return all regions #53178
+        if region_sup == static_region && D::is_normal() {
+            Edges {
+                graph: self,
+                constraints,
+                pointer: None,
+                next_static_idx: Some(0),
+                static_region,
+            }
+        } else {
+            //otherwise, just setup the iterator as normal
+            let first = self.first_constraints[region_sup];
+            Edges {
+                graph: self,
+                constraints,
+                pointer: first,
+                next_static_idx: None,
+                static_region,
+           }
         }
     }
 }
@@ -121,6 +151,8 @@ crate struct Edges<'s, D: ConstraintGraphDirecton> {
     graph: &'s ConstraintGraph<D>,
     constraints: &'s ConstraintSet,
     pointer: Option<ConstraintIndex>,
+    next_static_idx: Option<usize>,
+    static_region: RegionVid,
 }
 
 impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
@@ -129,7 +161,21 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
     fn next(&mut self) -> Option<Self::Item> {
         if let Some(p) = self.pointer {
             self.pointer = self.graph.next_constraints[p];
+
             Some(self.constraints[p])
+        } else if let Some(next_static_idx) = self.next_static_idx {
+            self.next_static_idx =
+                if next_static_idx == (self.graph.first_constraints.len() - 1) {
+                    None
+                } else {
+                    Some(next_static_idx + 1)
+                };
+
+            Some(OutlivesConstraint {
+                sup: self.static_region,
+                sub: next_static_idx.into(),
+                locations: Locations::All,
+            })
         } else {
             None
         }
@@ -142,6 +188,7 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
 crate struct RegionGraph<'s, D: ConstraintGraphDirecton> {
     set: &'s ConstraintSet,
     constraint_graph: &'s ConstraintGraph<D>,
+    static_region: RegionVid,
 }
 
 impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
@@ -149,10 +196,15 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
     /// R2` is treated as an edge `R1 -> R2`. We use this graph to
     /// construct SCCs for region inference but also for error
     /// reporting.
-    crate fn new(set: &'s ConstraintSet, constraint_graph: &'s ConstraintGraph<D>) -> Self {
+    crate fn new(
+        set: &'s ConstraintSet,
+        constraint_graph: &'s ConstraintGraph<D>,
+        static_region: RegionVid,
+    ) -> Self {
         Self {
             set,
             constraint_graph,
+            static_region,
         }
     }
 
@@ -160,7 +212,7 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
     /// there exists a constraint `R: R1`.
     crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'_, D> {
         Successors {
-            edges: self.constraint_graph.outgoing_edges(region_sup, self.set),
+            edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region),
         }
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
index 4cb92262ff0..9a8b0f391de 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
@@ -58,8 +58,9 @@ impl ConstraintSet {
     crate fn compute_sccs(
         &self,
         constraint_graph: &graph::NormalConstraintGraph,
+        static_region: RegionVid,
     ) -> Sccs<RegionVid, ConstraintSccIndex> {
-        let region_graph = &constraint_graph.region_graph(self);
+        let region_graph = &constraint_graph.region_graph(self, static_region);
         Sccs::new(region_graph)
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 2a541b6474f..0b9b9b33b3f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -201,7 +201,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // Otherwise, walk over the outgoing constraints and
             // enqueue any regions we find, keeping track of how we
             // reached them.
-            for constraint in self.constraint_graph.outgoing_edges(r, &self.constraints) {
+            let fr_static = self.universal_regions.fr_static;
+            for constraint in self.constraint_graph.outgoing_edges(r,
+                                                                   &self.constraints,
+                                                                   fr_static) {
                 assert_eq!(constraint.sup, r);
                 let sub_region = constraint.sub;
                 if let Trace::NotVisited = context[sub_region] {
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 4fe39ba3c95..bbdf2a92922 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -234,7 +234,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let constraints = Rc::new(outlives_constraints); // freeze constraints
         let constraint_graph = Rc::new(constraints.graph(definitions.len()));
-        let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph));
+        let fr_static = universal_regions.fr_static;
+        let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
 
         let mut scc_values = RegionValues::new(elements, universal_regions.len(), max_universe);
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index b3fc73e9b7b..357e9ee7210 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -69,7 +69,8 @@ fn regions_that_outlive_free_regions(
     // reachable from each free region, we will have all the
     // regions that are forced to outlive some free region.
     let rev_constraint_graph = constraint_set.reverse_graph(num_region_vars);
-    let rev_region_graph = rev_constraint_graph.region_graph(constraint_set);
+    let fr_static = universal_regions.fr_static;
+    let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static);
 
     // Stack for the depth-first search. Start out with all the free regions.
     let mut stack: Vec<_> = universal_regions.universal_regions().collect();