]> git.lizzy.rs Git - rust.git/commitdiff
[nll] teach SCC about `'static`
authorWesley Wiser <wwiser@gmail.com>
Mon, 27 Aug 2018 02:50:57 +0000 (22:50 -0400)
committerWesley Wiser <wwiser@gmail.com>
Thu, 6 Sep 2018 23:58:22 +0000 (19:58 -0400)
Fixes #53178

src/librustc_mir/borrow_check/nll/constraints/graph.rs
src/librustc_mir/borrow_check/nll/constraints/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

index 7cf94ec84dc935eac95218de674fd446df762467..b1e8b974379d61c0335e186b785da76f82cc37f0 100644 (file)
@@ -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 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 @@ fn start_region(c: &OutlivesConstraint) -> RegionVid {
     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 @@ fn start_region(c: &OutlivesConstraint) -> RegionVid {
     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 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     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 @@ fn next(&mut self) -> Option<Self::Item> {
 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),
         }
     }
 }
index 4cb92262ff08590a9d2c6f8ab00f4c25419eb13d..9a8b0f391de9d1339d512a84239c0039964f355a 100644 (file)
@@ -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)
     }
 }
index 2a541b6474f583fc71648189587de2bd55a69358..0b9b9b33b3f154577bda5fa1edff3c0998b1899a 100644 (file)
@@ -201,7 +201,10 @@ fn find_constraint_paths_between_regions(
             // 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] {
index 4fe39ba3c9520bea74aed78160f7fa822c31e835..bbdf2a929221093d88f37b7f083a4f5f5807901a 100644 (file)
@@ -234,7 +234,8 @@ pub(crate) fn new(
 
         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);
 
index b3fc73e9b7be342a11244c9e324fdeaf6a9ff544..357e9ee72102a6d59400a32847cfac8f616f440a 100644 (file)
@@ -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();