1
1
use crate :: borrow_check:: location:: LocationTable ;
2
2
use crate :: borrow_check:: nll:: region_infer:: values:: { self , PointIndex , RegionValueElements } ;
3
3
use crate :: borrow_check:: nll:: type_check:: liveness:: local_use_map:: LocalUseMap ;
4
+ use crate :: borrow_check:: nll:: type_check:: liveness:: polonius;
4
5
use crate :: borrow_check:: nll:: type_check:: NormalizeLocation ;
5
6
use crate :: borrow_check:: nll:: type_check:: TypeChecker ;
6
7
use crate :: dataflow:: indexes:: MovePathIndex ;
7
8
use crate :: dataflow:: move_paths:: MoveData ;
8
9
use crate :: dataflow:: { FlowAtLocation , FlowsAtLocation , MaybeInitializedPlaces } ;
9
10
use rustc:: infer:: canonical:: QueryRegionConstraints ;
10
- use rustc:: mir:: { BasicBlock , ConstraintCategory , Local , Location , Body } ;
11
+ use rustc:: mir:: { BasicBlock , Body , ConstraintCategory , Local , Location } ;
11
12
use rustc:: traits:: query:: dropck_outlives:: DropckOutlivesResult ;
12
13
use rustc:: traits:: query:: type_op:: outlives:: DropckOutlives ;
13
14
use rustc:: traits:: query:: type_op:: TypeOp ;
@@ -130,6 +131,12 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
130
131
for local in live_locals {
131
132
self . reset_local_state ( ) ;
132
133
self . add_defs_for ( local) ;
134
+
135
+ // FIXME: this is temporary until we can generate our own initialization
136
+ if self . cx . typeck . borrowck_context . all_facts . is_some ( ) {
137
+ self . add_polonius_var_initialized_on_exit_for ( local)
138
+ }
139
+
133
140
self . compute_use_live_points_for ( local) ;
134
141
self . compute_drop_live_points_for ( local) ;
135
142
@@ -150,6 +157,63 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
150
157
}
151
158
}
152
159
160
+ // WARNING: panics if self.cx.typeck.borrowck_context.all_facts != None
161
+ //
162
+ // FIXME: this analysis (the initialization tracking) should be
163
+ // done in Polonius, but isn't yet.
164
+ fn add_polonius_var_initialized_on_exit_for ( & mut self , local : Local ) {
165
+ let move_path = self . cx . move_data . rev_lookup . find_local ( local) ;
166
+ let facts = self . cx . typeck . borrowck_context . all_facts . as_mut ( ) . unwrap ( ) ;
167
+ for block in self . cx . body . basic_blocks ( ) . indices ( ) {
168
+ debug ! ( "polonius: generating initialization facts for {:?} in {:?}" , local, block) ;
169
+
170
+ // iterate through the block, applying the effects of each statement
171
+ // up to and including location, and populate `var_initialized_on_exit`
172
+ self . cx . flow_inits . reset_to_entry_of ( block) ;
173
+ let start_location = Location { block, statement_index : 0 } ;
174
+ self . cx . flow_inits . apply_local_effect ( start_location) ;
175
+
176
+ for statement_index in 0 ..self . cx . body [ block] . statements . len ( ) {
177
+ let current_location = Location { block, statement_index } ;
178
+
179
+ self . cx . flow_inits . reconstruct_statement_effect ( current_location) ;
180
+
181
+ // statement has not yet taken effect:
182
+ if self . cx . flow_inits . has_any_child_of ( move_path) . is_some ( ) {
183
+ facts
184
+ . var_initialized_on_exit
185
+ . push ( ( local, self . cx . location_table . start_index ( current_location) ) ) ;
186
+ }
187
+
188
+ // statement has now taken effect
189
+ self . cx . flow_inits . apply_local_effect ( current_location) ;
190
+
191
+ if self . cx . flow_inits . has_any_child_of ( move_path) . is_some ( ) {
192
+ facts
193
+ . var_initialized_on_exit
194
+ . push ( ( local, self . cx . location_table . mid_index ( current_location) ) ) ;
195
+ }
196
+ }
197
+
198
+ let terminator_location = self . cx . body . terminator_loc ( block) ;
199
+
200
+ if self . cx . flow_inits . has_any_child_of ( move_path) . is_some ( ) {
201
+ facts
202
+ . var_initialized_on_exit
203
+ . push ( ( local, self . cx . location_table . start_index ( terminator_location) ) ) ;
204
+ }
205
+
206
+ // apply the effects of the terminator and push it if needed
207
+ self . cx . flow_inits . reset_to_exit_of ( block) ;
208
+
209
+ if self . cx . flow_inits . has_any_child_of ( move_path) . is_some ( ) {
210
+ facts
211
+ . var_initialized_on_exit
212
+ . push ( ( local, self . cx . location_table . mid_index ( terminator_location) ) ) ;
213
+ }
214
+ }
215
+ }
216
+
153
217
/// Clear the value of fields that are "per local variable".
154
218
fn reset_local_state ( & mut self ) {
155
219
self . defs . clear ( ) ;
@@ -211,6 +275,11 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
211
275
debug_assert_eq ! ( self . cx. body. terminator_loc( location. block) , location, ) ;
212
276
213
277
if self . cx . initialized_at_terminator ( location. block , mpi) {
278
+ // FIXME: this analysis (the initialization tracking) should be
279
+ // done in Polonius, but isn't yet.
280
+ if let Some ( facts) = self . cx . typeck . borrowck_context . all_facts {
281
+ facts. var_drop_used . push ( ( local, self . cx . location_table . mid_index ( location) ) ) ;
282
+ }
214
283
if self . drop_live_at . insert ( drop_point) {
215
284
self . drop_locations . push ( location) ;
216
285
self . stack . push ( drop_point) ;
@@ -487,6 +556,8 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
487
556
live_at,
488
557
self . location_table ,
489
558
) ;
559
+
560
+ polonius:: add_var_drops_regions ( & mut self . typeck , dropped_local, & kind) ;
490
561
}
491
562
}
492
563
@@ -505,14 +576,15 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
505
576
506
577
let tcx = typeck. tcx ( ) ;
507
578
tcx. for_each_free_region ( & value, |live_region| {
508
- let live_region_vid = typeck . borrowck_context
509
- . universal_regions
510
- . to_region_vid ( live_region ) ;
511
- typeck . borrowck_context
579
+ let live_region_vid =
580
+ typeck . borrowck_context . universal_regions . to_region_vid ( live_region ) ;
581
+ typeck
582
+ . borrowck_context
512
583
. constraints
513
584
. liveness_constraints
514
585
. add_elements ( live_region_vid, live_at) ;
515
586
587
+ // FIXME: remove this when we can generate our own region-live-at reliably
516
588
if let Some ( facts) = typeck. borrowck_context . all_facts {
517
589
for point in live_at. iter ( ) {
518
590
let loc = elements. to_location ( point) ;
0 commit comments