|
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