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,21 +108,41 @@ 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
120
crate fn outgoing_edges < ' a > (
107
121
& ' a self ,
108
122
region_sup : RegionVid ,
109
123
constraints : & ' a ConstraintSet ,
124
+ static_region : RegionVid ,
110
125
) -> 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
+ }
116
146
}
117
147
}
118
148
}
@@ -121,6 +151,8 @@ crate struct Edges<'s, D: ConstraintGraphDirecton> {
121
151
graph : & ' s ConstraintGraph < D > ,
122
152
constraints : & ' s ConstraintSet ,
123
153
pointer : Option < ConstraintIndex > ,
154
+ next_static_idx : Option < usize > ,
155
+ static_region : RegionVid ,
124
156
}
125
157
126
158
impl < ' s , D : ConstraintGraphDirecton > Iterator for Edges < ' s , D > {
@@ -129,7 +161,21 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
129
161
fn next ( & mut self ) -> Option < Self :: Item > {
130
162
if let Some ( p) = self . pointer {
131
163
self . pointer = self . graph . next_constraints [ p] ;
164
+
132
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
+ } )
133
179
} else {
134
180
None
135
181
}
@@ -142,25 +188,31 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
142
188
crate struct RegionGraph < ' s , D : ConstraintGraphDirecton > {
143
189
set : & ' s ConstraintSet ,
144
190
constraint_graph : & ' s ConstraintGraph < D > ,
191
+ static_region : RegionVid ,
145
192
}
146
193
147
194
impl < ' s , D : ConstraintGraphDirecton > RegionGraph < ' s , D > {
148
195
/// Create a "dependency graph" where each region constraint `R1:
149
196
/// R2` is treated as an edge `R1 -> R2`. We use this graph to
150
197
/// construct SCCs for region inference but also for error
151
198
/// 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 {
153
204
Self {
154
205
set,
155
206
constraint_graph,
207
+ static_region,
156
208
}
157
209
}
158
210
159
211
/// Given a region `R`, iterate over all regions `R1` such that
160
212
/// there exists a constraint `R: R1`.
161
213
crate fn outgoing_regions ( & self , region_sup : RegionVid ) -> Successors < ' _ , D > {
162
214
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 ) ,
164
216
}
165
217
}
166
218
}
0 commit comments