|
2 | 2 | #![deny(rustc::diagnostic_outside_of_impl)] |
3 | 3 | //! The entry point of the NLL borrow checker. |
4 | 4 |
|
| 5 | +use polonius_engine::{Algorithm, Output}; |
5 | 6 | use rustc_data_structures::fx::FxIndexMap; |
6 | 7 | use rustc_hir::def_id::LocalDefId; |
7 | 8 | use rustc_index::IndexSlice; |
8 | 9 | use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere}; |
9 | | -use rustc_middle::mir::{ |
10 | | - Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted, |
11 | | - START_BLOCK, |
12 | | -}; |
| 10 | +use rustc_middle::mir::{Body, ClosureOutlivesSubject, ClosureRegionRequirements, Promoted}; |
13 | 11 | use rustc_middle::ty::print::with_no_trimmed_paths; |
14 | 12 | use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; |
| 13 | +use rustc_mir_dataflow::impls::MaybeInitializedPlaces; |
| 14 | +use rustc_mir_dataflow::move_paths::MoveData; |
| 15 | +use rustc_mir_dataflow::ResultsCursor; |
15 | 16 | use rustc_span::symbol::sym; |
16 | 17 | use std::env; |
17 | 18 | use std::io; |
18 | 19 | use std::path::PathBuf; |
19 | 20 | use std::rc::Rc; |
20 | 21 | use std::str::FromStr; |
21 | 22 |
|
22 | | -use polonius_engine::{Algorithm, Output}; |
23 | | - |
24 | | -use rustc_mir_dataflow::impls::MaybeInitializedPlaces; |
25 | | -use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData}; |
26 | | -use rustc_mir_dataflow::ResultsCursor; |
| 23 | +mod polonius; |
27 | 24 |
|
28 | 25 | use crate::{ |
29 | 26 | borrow_set::BorrowSet, |
@@ -78,81 +75,6 @@ pub(crate) fn replace_regions_in_mir<'tcx>( |
78 | 75 | universal_regions |
79 | 76 | } |
80 | 77 |
|
81 | | -// This function populates an AllFacts instance with base facts related to |
82 | | -// MovePaths and needed for the move analysis. |
83 | | -fn populate_polonius_move_facts( |
84 | | - all_facts: &mut AllFacts, |
85 | | - move_data: &MoveData<'_>, |
86 | | - location_table: &LocationTable, |
87 | | - body: &Body<'_>, |
88 | | -) { |
89 | | - all_facts |
90 | | - .path_is_var |
91 | | - .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l))); |
92 | | - |
93 | | - for (child, move_path) in move_data.move_paths.iter_enumerated() { |
94 | | - if let Some(parent) = move_path.parent { |
95 | | - all_facts.child_path.push((child, parent)); |
96 | | - } |
97 | | - } |
98 | | - |
99 | | - let fn_entry_start = |
100 | | - location_table.start_index(Location { block: START_BLOCK, statement_index: 0 }); |
101 | | - |
102 | | - // initialized_at |
103 | | - for init in move_data.inits.iter() { |
104 | | - match init.location { |
105 | | - InitLocation::Statement(location) => { |
106 | | - let block_data = &body[location.block]; |
107 | | - let is_terminator = location.statement_index == block_data.statements.len(); |
108 | | - |
109 | | - if is_terminator && init.kind == InitKind::NonPanicPathOnly { |
110 | | - // We are at the terminator of an init that has a panic path, |
111 | | - // and where the init should not happen on panic |
112 | | - |
113 | | - for successor in block_data.terminator().successors() { |
114 | | - if body[successor].is_cleanup { |
115 | | - continue; |
116 | | - } |
117 | | - |
118 | | - // The initialization happened in (or rather, when arriving at) |
119 | | - // the successors, but not in the unwind block. |
120 | | - let first_statement = Location { block: successor, statement_index: 0 }; |
121 | | - all_facts |
122 | | - .path_assigned_at_base |
123 | | - .push((init.path, location_table.start_index(first_statement))); |
124 | | - } |
125 | | - } else { |
126 | | - // In all other cases, the initialization just happens at the |
127 | | - // midpoint, like any other effect. |
128 | | - all_facts |
129 | | - .path_assigned_at_base |
130 | | - .push((init.path, location_table.mid_index(location))); |
131 | | - } |
132 | | - } |
133 | | - // Arguments are initialized on function entry |
134 | | - InitLocation::Argument(local) => { |
135 | | - assert!(body.local_kind(local) == LocalKind::Arg); |
136 | | - all_facts.path_assigned_at_base.push((init.path, fn_entry_start)); |
137 | | - } |
138 | | - } |
139 | | - } |
140 | | - |
141 | | - for (local, path) in move_data.rev_lookup.iter_locals_enumerated() { |
142 | | - if body.local_kind(local) != LocalKind::Arg { |
143 | | - // Non-arguments start out deinitialised; we simulate this with an |
144 | | - // initial move: |
145 | | - all_facts.path_moved_at_base.push((path, fn_entry_start)); |
146 | | - } |
147 | | - } |
148 | | - |
149 | | - // moved_out_at |
150 | | - // deinitialisation is assumed to always happen! |
151 | | - all_facts |
152 | | - .path_moved_at_base |
153 | | - .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source)))); |
154 | | -} |
155 | | - |
156 | 78 | /// Computes the (non-lexical) regions from the input MIR. |
157 | 79 | /// |
158 | 80 | /// This may result in errors being reported. |
@@ -206,7 +128,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( |
206 | 128 | if let Some(all_facts) = &mut all_facts { |
207 | 129 | let _prof_timer = infcx.tcx.prof.generic_activity("polonius_fact_generation"); |
208 | 130 | all_facts.universal_region.extend(universal_regions.universal_regions()); |
209 | | - populate_polonius_move_facts(all_facts, move_data, location_table, body); |
| 131 | + polonius::emit_move_facts(all_facts, move_data, location_table, body); |
210 | 132 |
|
211 | 133 | // Emit universal regions facts, and their relations, for Polonius. |
212 | 134 | // |
|
0 commit comments