1
1
use rustc_data_structures:: fx:: FxHashSet ;
2
2
use rustc_middle:: mir:: { Body , Location , Statement , StatementKind , Terminator , TerminatorKind } ;
3
- use rustc_middle:: ty:: { TyCtxt , TypeVisitable } ;
3
+ use rustc_middle:: ty:: TyCtxt ;
4
4
use rustc_mir_dataflow:: points:: PointIndex ;
5
5
6
6
use super :: { LocalizedOutlivesConstraint , LocalizedOutlivesConstraintSet } ;
@@ -52,10 +52,8 @@ pub(super) fn convert_typeck_constraints<'tcx>(
52
52
// this information better in MIR typeck instead, for example with a new `Locations`
53
53
// variant that contains which node is crossing over between entry and exit.
54
54
let point = liveness. point_from_location ( location) ;
55
- let ( from, to) = if let Some ( stmt) =
56
- body[ location. block ] . statements . get ( location. statement_index )
57
- {
58
- localize_statement_constraint (
55
+ if let Some ( stmt) = body[ location. block ] . statements . get ( location. statement_index ) {
56
+ convert_statement_constraint (
59
57
tcx,
60
58
body,
61
59
stmt,
@@ -64,34 +62,30 @@ pub(super) fn convert_typeck_constraints<'tcx>(
64
62
location,
65
63
point,
66
64
universal_regions,
65
+ localized_outlives_constraints,
67
66
)
68
67
} else {
69
68
assert_eq ! ( location. statement_index, body[ location. block] . statements. len( ) ) ;
70
69
let terminator = body[ location. block ] . terminator ( ) ;
71
- localize_terminator_constraint (
70
+ convert_terminator_constraint (
72
71
tcx,
73
72
body,
74
73
terminator,
75
74
liveness,
76
75
& outlives_constraint,
77
76
point,
78
77
universal_regions,
78
+ localized_outlives_constraints,
79
79
)
80
- } ;
81
- localized_outlives_constraints. push ( LocalizedOutlivesConstraint {
82
- source : outlives_constraint. sup ,
83
- from,
84
- target : outlives_constraint. sub ,
85
- to,
86
- } ) ;
80
+ }
87
81
}
88
82
}
89
83
}
90
84
}
91
85
92
86
/// For a given outlives constraint arising from a MIR statement, computes the CFG `from`-`to`
93
87
/// intra-block nodes to localize the constraint.
94
- fn localize_statement_constraint < ' tcx > (
88
+ fn convert_statement_constraint < ' tcx > (
95
89
tcx : TyCtxt < ' tcx > ,
96
90
body : & Body < ' tcx > ,
97
91
stmt : & Statement < ' tcx > ,
@@ -100,7 +94,8 @@ fn localize_statement_constraint<'tcx>(
100
94
current_location : Location ,
101
95
current_point : PointIndex ,
102
96
universal_regions : & UniversalRegions < ' tcx > ,
103
- ) -> ( PointIndex , PointIndex ) {
97
+ localized_outlives_constraints : & mut LocalizedOutlivesConstraintSet ,
98
+ ) {
104
99
match & stmt. kind {
105
100
StatementKind :: Assign ( box ( lhs, rhs) ) => {
106
101
// To create localized outlives constraints without midpoints, we rely on the property
@@ -146,33 +141,52 @@ fn localize_statement_constraint<'tcx>(
146
141
statement_index : current_location. statement_index + 1 ,
147
142
} ;
148
143
let successor_point = liveness. point_from_location ( successor_location) ;
149
- compute_constraint_direction (
150
- tcx,
151
- outlives_constraint,
152
- & lhs_ty,
153
- current_point,
154
- successor_point,
155
- universal_regions,
156
- )
144
+
145
+ let mut from = current_point;
146
+ let mut to = current_point;
147
+ tcx. for_each_free_region ( & lhs_ty, |region| {
148
+ let region = universal_regions. to_region_vid ( region) ;
149
+ if region == outlives_constraint. sub {
150
+ // This constraint flows into the LHS, its effects start becoming visible on
151
+ // exit.
152
+ to = successor_point;
153
+ } else if region == outlives_constraint. sup {
154
+ // This constraint flows from the LHS, its effects start becoming visible on
155
+ // exit.
156
+ from = successor_point;
157
+ }
158
+ } ) ;
159
+ localized_outlives_constraints. push ( LocalizedOutlivesConstraint {
160
+ source : outlives_constraint. sup ,
161
+ from,
162
+ target : outlives_constraint. sub ,
163
+ to,
164
+ } ) ;
157
165
}
158
166
_ => {
159
167
// For the other cases, we localize an outlives constraint to where it arises.
160
- ( current_point, current_point)
168
+ localized_outlives_constraints. push ( LocalizedOutlivesConstraint {
169
+ source : outlives_constraint. sup ,
170
+ from : current_point,
171
+ target : outlives_constraint. sub ,
172
+ to : current_point,
173
+ } ) ;
161
174
}
162
175
}
163
176
}
164
177
165
178
/// For a given outlives constraint arising from a MIR terminator, computes the CFG `from`-`to`
166
179
/// inter-block nodes to localize the constraint.
167
- fn localize_terminator_constraint < ' tcx > (
180
+ fn convert_terminator_constraint < ' tcx > (
168
181
tcx : TyCtxt < ' tcx > ,
169
182
body : & Body < ' tcx > ,
170
183
terminator : & Terminator < ' tcx > ,
171
184
liveness : & LivenessValues ,
172
185
outlives_constraint : & OutlivesConstraint < ' tcx > ,
173
186
current_point : PointIndex ,
174
187
universal_regions : & UniversalRegions < ' tcx > ,
175
- ) -> ( PointIndex , PointIndex ) {
188
+ localized_outlives_constraints : & mut LocalizedOutlivesConstraintSet ,
189
+ ) {
176
190
// FIXME: check if other terminators need the same handling as `Call`s, in particular
177
191
// Assert/Yield/Drop. A handful of tests are failing with Drop related issues, as well as some
178
192
// coroutine tests, and that may be why.
@@ -185,47 +199,39 @@ fn localize_terminator_constraint<'tcx>(
185
199
let destination_ty = destination. ty ( & body. local_decls , tcx) ;
186
200
let successor_location = Location { block : * target, statement_index : 0 } ;
187
201
let successor_point = liveness. point_from_location ( successor_location) ;
188
- compute_constraint_direction (
189
- tcx,
190
- outlives_constraint,
191
- & destination_ty,
192
- current_point,
193
- successor_point,
194
- universal_regions,
195
- )
202
+
203
+ let mut from = current_point;
204
+ let mut to = current_point;
205
+ tcx. for_each_free_region ( & destination_ty, |region| {
206
+ let region = universal_regions. to_region_vid ( region) ;
207
+ if region == outlives_constraint. sub {
208
+ // This constraint flows into the destination, its effects start becoming
209
+ // visible on exit.
210
+ to = successor_point;
211
+ } else if region == outlives_constraint. sup {
212
+ // This constraint flows from the destination, its effects start becoming
213
+ // visible on exit.
214
+ from = successor_point;
215
+ }
216
+ } ) ;
217
+
218
+ localized_outlives_constraints. push ( LocalizedOutlivesConstraint {
219
+ source : outlives_constraint. sup ,
220
+ from,
221
+ target : outlives_constraint. sub ,
222
+ to,
223
+ } ) ;
196
224
}
197
225
_ => {
198
226
// Typeck constraints guide loans between regions at the current point, so we do that in
199
227
// the general case, and liveness will take care of making them flow to the terminator's
200
228
// successors.
201
- ( current_point, current_point)
229
+ localized_outlives_constraints. push ( LocalizedOutlivesConstraint {
230
+ source : outlives_constraint. sup ,
231
+ from : current_point,
232
+ target : outlives_constraint. sub ,
233
+ to : current_point,
234
+ } ) ;
202
235
}
203
236
}
204
237
}
205
-
206
- /// For a given constraint, returns the `from`-`to` edge according to whether the constraint flows
207
- /// to or from a free region in the given `value`, some kind of result for an effectful operation,
208
- /// like the LHS of an assignment.
209
- fn compute_constraint_direction < ' tcx > (
210
- tcx : TyCtxt < ' tcx > ,
211
- outlives_constraint : & OutlivesConstraint < ' tcx > ,
212
- value : & impl TypeVisitable < TyCtxt < ' tcx > > ,
213
- current_point : PointIndex ,
214
- successor_point : PointIndex ,
215
- universal_regions : & UniversalRegions < ' tcx > ,
216
- ) -> ( PointIndex , PointIndex ) {
217
- let mut to = current_point;
218
- let mut from = current_point;
219
- tcx. for_each_free_region ( value, |region| {
220
- let region = universal_regions. to_region_vid ( region) ;
221
- if region == outlives_constraint. sub {
222
- // This constraint flows into the result, its effects start becoming visible on exit.
223
- to = successor_point;
224
- } else if region == outlives_constraint. sup {
225
- // This constraint flows from the result, its effects start becoming visible on exit.
226
- from = successor_point;
227
- }
228
- } ) ;
229
-
230
- ( from, to)
231
- }
0 commit comments