@@ -4,14 +4,14 @@ use crate::borrow_check::nll::facts::AllFactsExt;
4
4
use crate :: borrow_check:: nll:: type_check:: { MirTypeckResults , MirTypeckRegionConstraints } ;
5
5
use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
6
6
use crate :: dataflow:: indexes:: BorrowIndex ;
7
- use crate :: dataflow:: move_paths:: { MoveData , MovePathIndex } ;
7
+ use crate :: dataflow:: move_paths:: { InitLocation , MoveData , MovePathIndex , InitKind } ;
8
8
use crate :: dataflow:: FlowAtLocation ;
9
9
use crate :: dataflow:: MaybeInitializedPlaces ;
10
10
use crate :: transform:: MirSource ;
11
11
use crate :: borrow_check:: Upvar ;
12
12
use rustc:: hir:: def_id:: DefId ;
13
13
use rustc:: infer:: InferCtxt ;
14
- use rustc:: mir:: { ClosureOutlivesSubject , ClosureRegionRequirements , Local , Body , Promoted } ;
14
+ use rustc:: mir:: { ClosureOutlivesSubject , ClosureRegionRequirements , Local , Location , Body , LocalKind , BasicBlock , Promoted } ;
15
15
use rustc:: ty:: { self , RegionKind , RegionVid } ;
16
16
use rustc_data_structures:: indexed_vec:: IndexVec ;
17
17
use rustc_errors:: Diagnostic ;
@@ -69,6 +69,61 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
69
69
universal_regions
70
70
}
71
71
72
+
73
+ // This function populates an AllFacts instance with base facts related to
74
+ // MovePaths and needed for the move analysis.
75
+ fn populate_polonius_move_facts ( all_facts : & mut AllFacts , move_data : & MoveData < ' _ > , location_table : & LocationTable , body : & Body < ' _ > ) {
76
+ all_facts. var_starts_path . extend ( move_data. rev_lookup . iter_locals_enumerated ( ) . map ( |( v, & m) | ( v, m) ) ) ;
77
+
78
+ for ( idx, move_path) in move_data. move_paths . iter_enumerated ( ) {
79
+ all_facts. parent . extend ( move_path. parents ( & move_data. move_paths ) . iter ( ) . map ( |& parent| ( parent, idx) ) ) ;
80
+ }
81
+
82
+ // initialized_at
83
+ for init in move_data. inits . iter ( ) {
84
+
85
+ match init. location {
86
+ InitLocation :: Statement ( location) => {
87
+ let block_data = & body[ location. block ] ;
88
+ let is_terminator = location. statement_index == block_data. statements . len ( ) ;
89
+
90
+ if is_terminator && init. kind == InitKind :: NonPanicPathOnly {
91
+ // We are at the terminator of an init that has a panic path,
92
+ // and where the init should not happen on panic
93
+
94
+ for & successor in block_data. terminator ( ) . successors ( ) {
95
+ if body[ successor] . is_cleanup {
96
+ continue ;
97
+ }
98
+
99
+ // The initialization happened in (or rather, when arriving at)
100
+ // the successors, but not in the unwind block.
101
+ let first_statement = Location { block : successor, statement_index : 0 } ;
102
+ all_facts. initialized_at . push ( ( init. path , location_table. start_index ( first_statement) ) ) ;
103
+ }
104
+
105
+ } else {
106
+ // In all other cases, the initialization just happens at the
107
+ // midpoint, like any other effect.
108
+ all_facts. initialized_at . push ( ( init. path , location_table. mid_index ( location) ) ) ;
109
+ }
110
+ } ,
111
+ // Arguments are initialized on function entry
112
+ InitLocation :: Argument ( local) => {
113
+ assert ! ( body. local_kind( local) == LocalKind :: Arg ) ;
114
+ let fn_entry = Location { block : BasicBlock :: from_u32 ( 0u32 ) , statement_index : 0 } ;
115
+ all_facts. initialized_at . push ( ( init. path , location_table. start_index ( fn_entry) ) ) ;
116
+
117
+ }
118
+ }
119
+ }
120
+
121
+
122
+ // moved_out_at
123
+ // deinitialisation is assumed to always happen!
124
+ all_facts. moved_out_at . extend ( move_data. moves . iter ( ) . map ( |mo| ( mo. path , location_table. mid_index ( mo. source ) ) ) ) ;
125
+ }
126
+
72
127
/// Computes the (non-lexical) regions from the input MIR.
73
128
///
74
129
/// This may result in errors being reported.
@@ -123,6 +178,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
123
178
all_facts
124
179
. universal_region
125
180
. extend ( universal_regions. universal_regions ( ) ) ;
181
+ populate_polonius_move_facts ( all_facts, move_data, location_table, body) ;
126
182
}
127
183
128
184
// Create the region inference context, taking ownership of the
0 commit comments