@@ -4,14 +4,14 @@ use crate::borrow_check::nll::facts::AllFactsExt;
44use crate :: borrow_check:: nll:: type_check:: { MirTypeckResults , MirTypeckRegionConstraints } ;
55use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
66use crate :: dataflow:: indexes:: BorrowIndex ;
7- use crate :: dataflow:: move_paths:: { MoveData , MovePathIndex } ;
7+ use crate :: dataflow:: move_paths:: { InitLocation , MoveData , MovePathIndex , InitKind } ;
88use crate :: dataflow:: FlowAtLocation ;
99use crate :: dataflow:: MaybeInitializedPlaces ;
1010use crate :: transform:: MirSource ;
1111use crate :: borrow_check:: Upvar ;
1212use rustc:: hir:: def_id:: DefId ;
1313use rustc:: infer:: InferCtxt ;
14- use rustc:: mir:: { ClosureOutlivesSubject , ClosureRegionRequirements , Local , Body , Promoted } ;
14+ use rustc:: mir:: { ClosureOutlivesSubject , ClosureRegionRequirements , Local , Location , Body , LocalKind , BasicBlock , Promoted } ;
1515use rustc:: ty:: { self , RegionKind , RegionVid } ;
1616use rustc_data_structures:: indexed_vec:: IndexVec ;
1717use rustc_errors:: Diagnostic ;
@@ -69,6 +69,61 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
6969 universal_regions
7070}
7171
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+
72127/// Computes the (non-lexical) regions from the input MIR.
73128///
74129/// This may result in errors being reported.
@@ -123,6 +178,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
123178 all_facts
124179 . universal_region
125180 . extend ( universal_regions. universal_regions ( ) ) ;
181+ populate_polonius_move_facts ( all_facts, move_data, location_table, body) ;
126182 }
127183
128184 // Create the region inference context, taking ownership of the
0 commit comments