11use rustc_data_structures:: graph;
22use rustc_index:: IndexVec ;
3- use rustc_middle:: mir:: ConstraintCategory ;
4- use rustc_middle:: ty:: { RegionVid , VarianceDiagInfo } ;
5- use rustc_span:: DUMMY_SP ;
3+ use rustc_middle:: ty:: RegionVid ;
64
75use crate :: constraints:: { OutlivesConstraint , OutlivesConstraintIndex , OutlivesConstraintSet } ;
8- use crate :: type_check:: Locations ;
96
107/// The construct graph organizes the constraints by their end-points.
118/// It can be used to view a `R1: R2` constraint as either an edge `R1
@@ -23,8 +20,8 @@ pub(crate) type ReverseConstraintGraph = ConstraintGraph<Reverse>;
2320/// Marker trait that controls whether a `R1: R2` constraint
2421/// represents an edge `R1 -> R2` or `R2 -> R1`.
2522pub ( crate ) trait ConstraintGraphDirection : Copy + ' static {
26- fn start_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid ;
27- fn end_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid ;
23+ fn start_region ( sup : RegionVid , sub : RegionVid ) -> RegionVid ;
24+ fn end_region ( sup : RegionVid , sub : RegionVid ) -> RegionVid ;
2825 fn is_normal ( ) -> bool ;
2926}
3027
@@ -36,12 +33,12 @@ pub(crate) trait ConstraintGraphDirection: Copy + 'static {
3633pub ( crate ) struct Normal ;
3734
3835impl ConstraintGraphDirection for Normal {
39- fn start_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
40- c . sup
36+ fn start_region ( sup : RegionVid , _sub : RegionVid ) -> RegionVid {
37+ sup
4138 }
4239
43- fn end_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
44- c . sub
40+ fn end_region ( _sup : RegionVid , sub : RegionVid ) -> RegionVid {
41+ sub
4542 }
4643
4744 fn is_normal ( ) -> bool {
@@ -57,12 +54,12 @@ impl ConstraintGraphDirection for Normal {
5754pub ( crate ) struct Reverse ;
5855
5956impl ConstraintGraphDirection for Reverse {
60- fn start_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
61- c . sub
57+ fn start_region ( _sup : RegionVid , sub : RegionVid ) -> RegionVid {
58+ sub
6259 }
6360
64- fn end_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
65- c . sup
61+ fn end_region ( sup : RegionVid , _sub : RegionVid ) -> RegionVid {
62+ sup
6663 }
6764
6865 fn is_normal ( ) -> bool {
@@ -84,7 +81,7 @@ impl<D: ConstraintGraphDirection> ConstraintGraph<D> {
8481 let mut next_constraints = IndexVec :: from_elem ( None , & set. outlives ) ;
8582
8683 for ( idx, constraint) in set. outlives . iter_enumerated ( ) . rev ( ) {
87- let head = & mut first_constraints[ D :: start_region ( constraint) ] ;
84+ let head = & mut first_constraints[ D :: start_region ( constraint. sup , constraint . sub ) ] ;
8885 let next = & mut next_constraints[ idx] ;
8986 debug_assert ! ( next. is_none( ) ) ;
9087 * next = * head;
@@ -105,63 +102,57 @@ impl<D: ConstraintGraphDirection> ConstraintGraph<D> {
105102 RegionGraph :: new ( set, self , static_region)
106103 }
107104
105+ pub ( crate ) fn is_normal ( & self ) -> bool {
106+ D :: is_normal ( )
107+ }
108+
108109 /// Given a region `R`, iterate over all constraints `R: R1`.
109- pub ( crate ) fn outgoing_edges < ' a , ' tcx > (
110+ pub ( crate ) fn outgoing_edges_from_graph < ' a , ' tcx > (
110111 & ' a self ,
111112 region_sup : RegionVid ,
112113 constraints : & ' a OutlivesConstraintSet < ' tcx > ,
113- static_region : RegionVid ,
114- ) -> Edges < ' a , ' tcx , D > {
115- //if this is the `'static` region and the graph's direction is normal,
116- //then setup the Edges iterator to return all regions #53178
117- if region_sup == static_region && D :: is_normal ( ) {
118- Edges {
119- graph : self ,
120- constraints,
121- pointer : None ,
122- next_static_idx : Some ( 0 ) ,
123- static_region,
124- }
125- } else {
126- //otherwise, just setup the iterator as normal
127- let first = self . first_constraints [ region_sup] ;
128- Edges { graph : self , constraints, pointer : first, next_static_idx : None , static_region }
129- }
114+ ) -> EdgesFromGraph < ' a , ' tcx , D > {
115+ EdgesFromGraph { graph : self , constraints, pointer : self . first_constraints [ region_sup] }
116+ }
117+
118+ /// Returns all regions (#53178).
119+ pub ( crate ) fn outgoing_edges_from_static ( & self ) -> EdgesFromStatic {
120+ EdgesFromStatic { next_static_idx : 0 , end_static_idx : self . first_constraints . len ( ) }
130121 }
131122}
132123
133- pub ( crate ) struct Edges < ' a , ' tcx , D : ConstraintGraphDirection > {
124+ pub ( crate ) struct EdgesFromGraph < ' a , ' tcx , D : ConstraintGraphDirection > {
134125 graph : & ' a ConstraintGraph < D > ,
135126 constraints : & ' a OutlivesConstraintSet < ' tcx > ,
136127 pointer : Option < OutlivesConstraintIndex > ,
137- next_static_idx : Option < usize > ,
138- static_region : RegionVid ,
139128}
140129
141- impl < ' a , ' tcx , D : ConstraintGraphDirection > Iterator for Edges < ' a , ' tcx , D > {
142- type Item = OutlivesConstraint < ' tcx > ;
130+ impl < ' a , ' tcx , D : ConstraintGraphDirection > Iterator for EdgesFromGraph < ' a , ' tcx , D > {
131+ type Item = & ' a OutlivesConstraint < ' tcx > ;
143132
144133 fn next ( & mut self ) -> Option < Self :: Item > {
145134 if let Some ( p) = self . pointer {
146135 self . pointer = self . graph . next_constraints [ p] ;
136+ Some ( & self . constraints [ p] )
137+ } else {
138+ None
139+ }
140+ }
141+ }
142+
143+ pub ( crate ) struct EdgesFromStatic {
144+ next_static_idx : usize ,
145+ end_static_idx : usize ,
146+ }
147+
148+ impl Iterator for EdgesFromStatic {
149+ type Item = RegionVid ;
147150
148- Some ( self . constraints [ p] )
149- } else if let Some ( next_static_idx) = self . next_static_idx {
150- self . next_static_idx = if next_static_idx == ( self . graph . first_constraints . len ( ) - 1 ) {
151- None
152- } else {
153- Some ( next_static_idx + 1 )
154- } ;
155-
156- Some ( OutlivesConstraint {
157- sup : self . static_region ,
158- sub : next_static_idx. into ( ) ,
159- locations : Locations :: All ( DUMMY_SP ) ,
160- span : DUMMY_SP ,
161- category : ConstraintCategory :: Internal ,
162- variance_info : VarianceDiagInfo :: default ( ) ,
163- from_closure : false ,
164- } )
151+ fn next ( & mut self ) -> Option < Self :: Item > {
152+ if self . next_static_idx < self . end_static_idx {
153+ let ret = RegionVid :: from_usize ( self . next_static_idx ) ;
154+ self . next_static_idx += 1 ;
155+ Some ( ret)
165156 } else {
166157 None
167158 }
@@ -193,21 +184,38 @@ impl<'a, 'tcx, D: ConstraintGraphDirection> RegionGraph<'a, 'tcx, D> {
193184 /// Given a region `R`, iterate over all regions `R1` such that
194185 /// there exists a constraint `R: R1`.
195186 pub ( crate ) fn outgoing_regions ( & self , region_sup : RegionVid ) -> Successors < ' a , ' tcx , D > {
196- Successors {
197- edges : self . constraint_graph . outgoing_edges ( region_sup, self . set , self . static_region ) ,
187+ // If this is the `'static` region and the graph's direction is normal,
188+ // then setup the Edges iterator to return all regions (#53178).
189+ if region_sup == self . static_region && D :: is_normal ( ) {
190+ Successors :: FromStatic ( self . constraint_graph . outgoing_edges_from_static ( ) )
191+ } else {
192+ // Otherwise, just setup the iterator as normal.
193+ Successors :: FromGraph (
194+ self . constraint_graph . outgoing_edges_from_graph ( region_sup, self . set ) ,
195+ )
198196 }
199197 }
200198}
201199
202- pub ( crate ) struct Successors < ' a , ' tcx , D : ConstraintGraphDirection > {
203- edges : Edges < ' a , ' tcx , D > ,
200+ pub ( crate ) enum Successors < ' a , ' tcx , D : ConstraintGraphDirection > {
201+ FromStatic ( EdgesFromStatic ) ,
202+ FromGraph ( EdgesFromGraph < ' a , ' tcx , D > ) ,
204203}
205204
206205impl < ' a , ' tcx , D : ConstraintGraphDirection > Iterator for Successors < ' a , ' tcx , D > {
207206 type Item = RegionVid ;
208207
209208 fn next ( & mut self ) -> Option < Self :: Item > {
210- self . edges . next ( ) . map ( |c| D :: end_region ( & c) )
209+ match self {
210+ Successors :: FromStatic ( edges) => {
211+ // No `D::end_region` call needed here: static successors are only possible when
212+ // the direction is `Normal`, so we can directly use what would be the `sub` value.
213+ edges. next ( )
214+ }
215+ Successors :: FromGraph ( edges) => {
216+ edges. next ( ) . map ( |constraint| D :: end_region ( constraint. sup , constraint. sub ) )
217+ }
218+ }
211219 }
212220}
213221
0 commit comments