88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use borrow_check:: nll:: type_check:: Locations ;
1112use borrow_check:: nll:: constraints:: { ConstraintIndex , ConstraintSet , OutlivesConstraint } ;
1213use rustc:: ty:: RegionVid ;
1314use rustc_data_structures:: graph;
@@ -31,6 +32,7 @@ crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
3132crate trait ConstraintGraphDirecton : Copy + ' static {
3233 fn start_region ( c : & OutlivesConstraint ) -> RegionVid ;
3334 fn end_region ( c : & OutlivesConstraint ) -> RegionVid ;
35+ fn is_normal ( ) -> bool ;
3436}
3537
3638/// In normal mode, a `R1: R2` constraint results in an edge `R1 ->
@@ -48,6 +50,10 @@ impl ConstraintGraphDirecton for Normal {
4850 fn end_region ( c : & OutlivesConstraint ) -> RegionVid {
4951 c. sub
5052 }
53+
54+ fn is_normal ( ) -> bool {
55+ true
56+ }
5157}
5258
5359/// In reverse mode, a `R1: R2` constraint results in an edge `R2 ->
@@ -65,6 +71,10 @@ impl ConstraintGraphDirecton for Reverse {
6571 fn end_region ( c : & OutlivesConstraint ) -> RegionVid {
6672 c. sup
6773 }
74+
75+ fn is_normal ( ) -> bool {
76+ false
77+ }
6878}
6979
7080impl < D : ConstraintGraphDirecton > ConstraintGraph < D > {
@@ -98,21 +108,41 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
98108 /// Given the constraint set from which this graph was built
99109 /// creates a region graph so that you can iterate over *regions*
100110 /// and not constraints.
101- crate fn region_graph < ' rg > ( & ' rg self , set : & ' rg ConstraintSet ) -> RegionGraph < ' rg , D > {
102- RegionGraph :: new ( set, self )
111+ crate fn region_graph < ' rg > (
112+ & ' rg self ,
113+ set : & ' rg ConstraintSet ,
114+ static_region : RegionVid ,
115+ ) -> RegionGraph < ' rg , D > {
116+ RegionGraph :: new ( set, self , static_region)
103117 }
104118
105119 /// Given a region `R`, iterate over all constraints `R: R1`.
106120 crate fn outgoing_edges < ' a > (
107121 & ' a self ,
108122 region_sup : RegionVid ,
109123 constraints : & ' a ConstraintSet ,
124+ static_region : RegionVid ,
110125 ) -> Edges < ' a , D > {
111- let first = self . first_constraints [ region_sup] ;
112- Edges {
113- graph : self ,
114- constraints,
115- pointer : first,
126+ //if this is the `'static` region and the graph's direction is normal,
127+ //then setup the Edges iterator to return all regions #53178
128+ if region_sup == static_region && D :: is_normal ( ) {
129+ Edges {
130+ graph : self ,
131+ constraints,
132+ pointer : None ,
133+ next_static_idx : Some ( 0 ) ,
134+ static_region,
135+ }
136+ } else {
137+ //otherwise, just setup the iterator as normal
138+ let first = self . first_constraints [ region_sup] ;
139+ Edges {
140+ graph : self ,
141+ constraints,
142+ pointer : first,
143+ next_static_idx : None ,
144+ static_region,
145+ }
116146 }
117147 }
118148}
@@ -121,6 +151,8 @@ crate struct Edges<'s, D: ConstraintGraphDirecton> {
121151 graph : & ' s ConstraintGraph < D > ,
122152 constraints : & ' s ConstraintSet ,
123153 pointer : Option < ConstraintIndex > ,
154+ next_static_idx : Option < usize > ,
155+ static_region : RegionVid ,
124156}
125157
126158impl < ' s , D : ConstraintGraphDirecton > Iterator for Edges < ' s , D > {
@@ -129,7 +161,21 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
129161 fn next ( & mut self ) -> Option < Self :: Item > {
130162 if let Some ( p) = self . pointer {
131163 self . pointer = self . graph . next_constraints [ p] ;
164+
132165 Some ( self . constraints [ p] )
166+ } else if let Some ( next_static_idx) = self . next_static_idx {
167+ self . next_static_idx =
168+ if next_static_idx == ( self . graph . first_constraints . len ( ) - 1 ) {
169+ None
170+ } else {
171+ Some ( next_static_idx + 1 )
172+ } ;
173+
174+ Some ( OutlivesConstraint {
175+ sup : self . static_region ,
176+ sub : next_static_idx. into ( ) ,
177+ locations : Locations :: All ,
178+ } )
133179 } else {
134180 None
135181 }
@@ -142,25 +188,31 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
142188crate struct RegionGraph < ' s , D : ConstraintGraphDirecton > {
143189 set : & ' s ConstraintSet ,
144190 constraint_graph : & ' s ConstraintGraph < D > ,
191+ static_region : RegionVid ,
145192}
146193
147194impl < ' s , D : ConstraintGraphDirecton > RegionGraph < ' s , D > {
148195 /// Create a "dependency graph" where each region constraint `R1:
149196 /// R2` is treated as an edge `R1 -> R2`. We use this graph to
150197 /// construct SCCs for region inference but also for error
151198 /// reporting.
152- crate fn new ( set : & ' s ConstraintSet , constraint_graph : & ' s ConstraintGraph < D > ) -> Self {
199+ crate fn new (
200+ set : & ' s ConstraintSet ,
201+ constraint_graph : & ' s ConstraintGraph < D > ,
202+ static_region : RegionVid ,
203+ ) -> Self {
153204 Self {
154205 set,
155206 constraint_graph,
207+ static_region,
156208 }
157209 }
158210
159211 /// Given a region `R`, iterate over all regions `R1` such that
160212 /// there exists a constraint `R: R1`.
161213 crate fn outgoing_regions ( & self , region_sup : RegionVid ) -> Successors < ' _ , D > {
162214 Successors {
163- edges : self . constraint_graph . outgoing_edges ( region_sup, self . set ) ,
215+ edges : self . constraint_graph . outgoing_edges ( region_sup, self . set , self . static_region ) ,
164216 }
165217 }
166218}
0 commit comments