1
1
use rustc_data_structures:: graph;
2
2
use 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 ;
6
4
7
5
use crate :: constraints:: { OutlivesConstraint , OutlivesConstraintIndex , OutlivesConstraintSet } ;
8
- use crate :: type_check:: Locations ;
9
6
10
7
/// The construct graph organizes the constraints by their end-points.
11
8
/// 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>;
23
20
/// Marker trait that controls whether a `R1: R2` constraint
24
21
/// represents an edge `R1 -> R2` or `R2 -> R1`.
25
22
pub ( 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 ;
28
25
fn is_normal ( ) -> bool ;
29
26
}
30
27
@@ -36,12 +33,12 @@ pub(crate) trait ConstraintGraphDirection: Copy + 'static {
36
33
pub ( crate ) struct Normal ;
37
34
38
35
impl ConstraintGraphDirection for Normal {
39
- fn start_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
40
- c . sup
36
+ fn start_region ( sup : RegionVid , _sub : RegionVid ) -> RegionVid {
37
+ sup
41
38
}
42
39
43
- fn end_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
44
- c . sub
40
+ fn end_region ( _sup : RegionVid , sub : RegionVid ) -> RegionVid {
41
+ sub
45
42
}
46
43
47
44
fn is_normal ( ) -> bool {
@@ -57,12 +54,12 @@ impl ConstraintGraphDirection for Normal {
57
54
pub ( crate ) struct Reverse ;
58
55
59
56
impl ConstraintGraphDirection for Reverse {
60
- fn start_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
61
- c . sub
57
+ fn start_region ( _sup : RegionVid , sub : RegionVid ) -> RegionVid {
58
+ sub
62
59
}
63
60
64
- fn end_region ( c : & OutlivesConstraint < ' _ > ) -> RegionVid {
65
- c . sup
61
+ fn end_region ( sup : RegionVid , _sub : RegionVid ) -> RegionVid {
62
+ sup
66
63
}
67
64
68
65
fn is_normal ( ) -> bool {
@@ -84,7 +81,7 @@ impl<D: ConstraintGraphDirection> ConstraintGraph<D> {
84
81
let mut next_constraints = IndexVec :: from_elem ( None , & set. outlives ) ;
85
82
86
83
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 ) ] ;
88
85
let next = & mut next_constraints[ idx] ;
89
86
debug_assert ! ( next. is_none( ) ) ;
90
87
* next = * head;
@@ -105,63 +102,57 @@ impl<D: ConstraintGraphDirection> ConstraintGraph<D> {
105
102
RegionGraph :: new ( set, self , static_region)
106
103
}
107
104
105
+ pub ( crate ) fn is_normal ( & self ) -> bool {
106
+ D :: is_normal ( )
107
+ }
108
+
108
109
/// 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 > (
110
111
& ' a self ,
111
112
region_sup : RegionVid ,
112
113
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 ( ) }
130
121
}
131
122
}
132
123
133
- pub ( crate ) struct Edges < ' a , ' tcx , D : ConstraintGraphDirection > {
124
+ pub ( crate ) struct EdgesFromGraph < ' a , ' tcx , D : ConstraintGraphDirection > {
134
125
graph : & ' a ConstraintGraph < D > ,
135
126
constraints : & ' a OutlivesConstraintSet < ' tcx > ,
136
127
pointer : Option < OutlivesConstraintIndex > ,
137
- next_static_idx : Option < usize > ,
138
- static_region : RegionVid ,
139
128
}
140
129
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 > ;
143
132
144
133
fn next ( & mut self ) -> Option < Self :: Item > {
145
134
if let Some ( p) = self . pointer {
146
135
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 ;
147
150
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)
165
156
} else {
166
157
None
167
158
}
@@ -193,21 +184,38 @@ impl<'a, 'tcx, D: ConstraintGraphDirection> RegionGraph<'a, 'tcx, D> {
193
184
/// Given a region `R`, iterate over all regions `R1` such that
194
185
/// there exists a constraint `R: R1`.
195
186
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
+ )
198
196
}
199
197
}
200
198
}
201
199
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 > ) ,
204
203
}
205
204
206
205
impl < ' a , ' tcx , D : ConstraintGraphDirection > Iterator for Successors < ' a , ' tcx , D > {
207
206
type Item = RegionVid ;
208
207
209
208
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
+ }
211
219
}
212
220
}
213
221
0 commit comments