8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use borrow_check:: nll:: type_check:: Locations ;
11
12
use borrow_check:: nll:: constraints:: { ConstraintIndex , ConstraintSet , OutlivesConstraint } ;
12
13
use rustc:: ty:: RegionVid ;
13
14
use rustc_data_structures:: graph;
@@ -31,6 +32,7 @@ crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
31
32
crate trait ConstraintGraphDirecton : Copy + ' static {
32
33
fn start_region ( c : & OutlivesConstraint ) -> RegionVid ;
33
34
fn end_region ( c : & OutlivesConstraint ) -> RegionVid ;
35
+ fn is_normal ( ) -> bool ;
34
36
}
35
37
36
38
/// In normal mode, a `R1: R2` constraint results in an edge `R1 ->
@@ -48,6 +50,10 @@ impl ConstraintGraphDirecton for Normal {
48
50
fn end_region ( c : & OutlivesConstraint ) -> RegionVid {
49
51
c. sub
50
52
}
53
+
54
+ fn is_normal ( ) -> bool {
55
+ true
56
+ }
51
57
}
52
58
53
59
/// In reverse mode, a `R1: R2` constraint results in an edge `R2 ->
@@ -65,6 +71,10 @@ impl ConstraintGraphDirecton for Reverse {
65
71
fn end_region ( c : & OutlivesConstraint ) -> RegionVid {
66
72
c. sup
67
73
}
74
+
75
+ fn is_normal ( ) -> bool {
76
+ false
77
+ }
68
78
}
69
79
70
80
impl < D : ConstraintGraphDirecton > ConstraintGraph < D > {
@@ -98,32 +108,74 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
98
108
/// Given the constraint set from which this graph was built
99
109
/// creates a region graph so that you can iterate over *regions*
100
110
/// 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)
103
117
}
104
118
105
119
/// Given a region `R`, iterate over all constraints `R: R1`.
106
- crate fn outgoing_edges ( & self , region_sup : RegionVid ) -> Edges < ' _ , D > {
107
- let first = self . first_constraints [ region_sup] ;
108
- Edges {
109
- graph : self ,
110
- pointer : first,
120
+ crate fn outgoing_edges < ' a > (
121
+ & ' a self ,
122
+ region_sup : RegionVid ,
123
+ constraints : & ' a ConstraintSet ,
124
+ static_region : RegionVid ,
125
+ ) -> Edges < ' a , D > {
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
+ }
111
146
}
112
147
}
113
148
}
114
149
115
150
crate struct Edges < ' s , D : ConstraintGraphDirecton > {
116
151
graph : & ' s ConstraintGraph < D > ,
152
+ constraints : & ' s ConstraintSet ,
117
153
pointer : Option < ConstraintIndex > ,
154
+ next_static_idx : Option < usize > ,
155
+ static_region : RegionVid ,
118
156
}
119
157
120
158
impl < ' s , D : ConstraintGraphDirecton > Iterator for Edges < ' s , D > {
121
- type Item = ConstraintIndex ;
159
+ type Item = OutlivesConstraint ;
122
160
123
161
fn next ( & mut self ) -> Option < Self :: Item > {
124
162
if let Some ( p) = self . pointer {
125
163
self . pointer = self . graph . next_constraints [ p] ;
126
- Some ( p)
164
+
165
+ 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
+ } )
127
179
} else {
128
180
None
129
181
}
@@ -136,40 +188,44 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
136
188
crate struct RegionGraph < ' s , D : ConstraintGraphDirecton > {
137
189
set : & ' s ConstraintSet ,
138
190
constraint_graph : & ' s ConstraintGraph < D > ,
191
+ static_region : RegionVid ,
139
192
}
140
193
141
194
impl < ' s , D : ConstraintGraphDirecton > RegionGraph < ' s , D > {
142
195
/// Create a "dependency graph" where each region constraint `R1:
143
196
/// R2` is treated as an edge `R1 -> R2`. We use this graph to
144
197
/// construct SCCs for region inference but also for error
145
198
/// reporting.
146
- 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 {
147
204
Self {
148
205
set,
149
206
constraint_graph,
207
+ static_region,
150
208
}
151
209
}
152
210
153
211
/// Given a region `R`, iterate over all regions `R1` such that
154
212
/// there exists a constraint `R: R1`.
155
213
crate fn outgoing_regions ( & self , region_sup : RegionVid ) -> Successors < ' _ , D > {
156
214
Successors {
157
- set : self . set ,
158
- edges : self . constraint_graph . outgoing_edges ( region_sup) ,
215
+ edges : self . constraint_graph . outgoing_edges ( region_sup, self . set , self . static_region ) ,
159
216
}
160
217
}
161
218
}
162
219
163
220
crate struct Successors < ' s , D : ConstraintGraphDirecton > {
164
- set : & ' s ConstraintSet ,
165
221
edges : Edges < ' s , D > ,
166
222
}
167
223
168
224
impl < ' s , D : ConstraintGraphDirecton > Iterator for Successors < ' s , D > {
169
225
type Item = RegionVid ;
170
226
171
227
fn next ( & mut self ) -> Option < Self :: Item > {
172
- self . edges . next ( ) . map ( |c| D :: end_region ( & self . set [ c ] ) )
228
+ self . edges . next ( ) . map ( |c| D :: end_region ( & c ) )
173
229
}
174
230
}
175
231
0 commit comments