about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/nll.rs2
-rw-r--r--compiler/rustc_borrowck/src/polonius/constraint_generation.rs178
-rw-r--r--compiler/rustc_borrowck/src/polonius/mod.rs10
3 files changed, 83 insertions, 107 deletions
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 1b4c92e3ee2..0c88f5cf363 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -158,7 +158,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
         borrow_set,
     );
     polonius::emit_cfg_and_loan_kills_facts(
-        infcx,
+        infcx.tcx,
         &mut all_facts,
         location_table,
         body,
diff --git a/compiler/rustc_borrowck/src/polonius/constraint_generation.rs b/compiler/rustc_borrowck/src/polonius/constraint_generation.rs
index ac9401924fb..27efc3c4108 100644
--- a/compiler/rustc_borrowck/src/polonius/constraint_generation.rs
+++ b/compiler/rustc_borrowck/src/polonius/constraint_generation.rs
@@ -1,23 +1,23 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{
     Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind,
     Terminator, TerminatorKind, UserTypeProjection,
 };
-use rustc_middle::ty::{self};
+use rustc_middle::ty::{TyCtxt, Variance};
 
 use crate::{borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict};
 
 pub(super) fn generate_constraints<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    all_facts: &mut Option<AllFacts>,
+    tcx: TyCtxt<'tcx>,
+    all_facts: &mut AllFacts,
     location_table: &LocationTable,
     body: &Body<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
 ) {
-    let mut cg = ConstraintGeneration { borrow_set, infcx, location_table, all_facts, body };
+    let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
+    let mut cg = ConstraintGeneration { borrow_set, tcx, location_table, all_facts, body };
     for (bb, data) in body.basic_blocks.iter_enumerated() {
         cg.visit_basic_block_data(bb, data);
     }
@@ -25,8 +25,8 @@ pub(super) fn generate_constraints<'tcx>(
 
 /// 'cg = the duration of the constraint generation process itself.
 struct ConstraintGeneration<'cg, 'tcx> {
-    infcx: &'cg InferCtxt<'tcx>,
-    all_facts: &'cg mut Option<AllFacts>,
+    tcx: TyCtxt<'tcx>,
+    all_facts: &'cg mut AllFacts,
     location_table: &'cg LocationTable,
     borrow_set: &'cg BorrowSet<'tcx>,
     body: &'cg Body<'tcx>,
@@ -34,28 +34,19 @@ struct ConstraintGeneration<'cg, 'tcx> {
 
 impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-            all_facts.cfg_edge.push((
-                self.location_table.start_index(location),
-                self.location_table.mid_index(location),
-            ));
-
-            all_facts.cfg_edge.push((
-                self.location_table.mid_index(location),
-                self.location_table.start_index(location.successor_within_block()),
-            ));
-
-            // If there are borrows on this now dead local, we need to record them as `killed`.
-            if let StatementKind::StorageDead(local) = statement.kind {
-                record_killed_borrows_for_local(
-                    all_facts,
-                    self.borrow_set,
-                    self.location_table,
-                    local,
-                    location,
-                );
-            }
+        self.all_facts.cfg_edge.push((
+            self.location_table.start_index(location),
+            self.location_table.mid_index(location),
+        ));
+
+        self.all_facts.cfg_edge.push((
+            self.location_table.mid_index(location),
+            self.location_table.start_index(location.successor_within_block()),
+        ));
+
+        // If there are borrows on this now dead local, we need to record them as `killed`.
+        if let StatementKind::StorageDead(local) = statement.kind {
+            self.record_killed_borrows_for_local(local, location);
         }
 
         self.super_statement(statement, location);
@@ -70,21 +61,18 @@ impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
     }
 
     fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-            all_facts.cfg_edge.push((
-                self.location_table.start_index(location),
+        self.all_facts.cfg_edge.push((
+            self.location_table.start_index(location),
+            self.location_table.mid_index(location),
+        ));
+
+        let successor_blocks = terminator.successors();
+        self.all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
+        for successor_block in successor_blocks {
+            self.all_facts.cfg_edge.push((
                 self.location_table.mid_index(location),
+                self.location_table.start_index(successor_block.start_location()),
             ));
-
-            let successor_blocks = terminator.successors();
-            all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
-            for successor_block in successor_blocks {
-                all_facts.cfg_edge.push((
-                    self.location_table.mid_index(location),
-                    self.location_table.start_index(successor_block.start_location()),
-                ));
-            }
         }
 
         // A `Call` terminator's return value can be a local which has borrows,
@@ -99,7 +87,7 @@ impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
     fn visit_ascribe_user_ty(
         &mut self,
         _place: &Place<'tcx>,
-        _variance: ty::Variance,
+        _variance: Variance,
         _user_ty: &UserTypeProjection,
         _location: Location,
     ) {
@@ -110,75 +98,59 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> {
     /// When recording facts for Polonius, records the borrows on the specified place
     /// as `killed`. For example, when assigning to a local, or on a call's return destination.
     fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-
-            // Depending on the `Place` we're killing:
-            // - if it's a local, or a single deref of a local,
-            //   we kill all the borrows on the local.
-            // - if it's a deeper projection, we have to filter which
-            //   of the borrows are killed: the ones whose `borrowed_place`
-            //   conflicts with the `place`.
-            match place.as_ref() {
-                PlaceRef { local, projection: &[] }
-                | PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
-                    debug!(
-                        "Recording `killed` facts for borrows of local={:?} at location={:?}",
-                        local, location
-                    );
-
-                    record_killed_borrows_for_local(
-                        all_facts,
-                        self.borrow_set,
-                        self.location_table,
-                        local,
-                        location,
-                    );
-                }
+        // Depending on the `Place` we're killing:
+        // - if it's a local, or a single deref of a local,
+        //   we kill all the borrows on the local.
+        // - if it's a deeper projection, we have to filter which
+        //   of the borrows are killed: the ones whose `borrowed_place`
+        //   conflicts with the `place`.
+        match place.as_ref() {
+            PlaceRef { local, projection: &[] }
+            | PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
+                debug!(
+                    "Recording `killed` facts for borrows of local={:?} at location={:?}",
+                    local, location
+                );
+
+                self.record_killed_borrows_for_local(local, location);
+            }
 
-                PlaceRef { local, projection: &[.., _] } => {
-                    // Kill conflicting borrows of the innermost local.
-                    debug!(
-                        "Recording `killed` facts for borrows of \
+            PlaceRef { local, projection: &[.., _] } => {
+                // Kill conflicting borrows of the innermost local.
+                debug!(
+                    "Recording `killed` facts for borrows of \
                             innermost projected local={:?} at location={:?}",
-                        local, location
-                    );
-
-                    if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
-                        for &borrow_index in borrow_indices {
-                            let places_conflict = places_conflict::places_conflict(
-                                self.infcx.tcx,
-                                self.body,
-                                self.borrow_set[borrow_index].borrowed_place,
-                                place,
-                                places_conflict::PlaceConflictBias::NoOverlap,
-                            );
-
-                            if places_conflict {
-                                let location_index = self.location_table.mid_index(location);
-                                all_facts.loan_killed_at.push((borrow_index, location_index));
-                            }
+                    local, location
+                );
+
+                if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
+                    for &borrow_index in borrow_indices {
+                        let places_conflict = places_conflict::places_conflict(
+                            self.tcx,
+                            self.body,
+                            self.borrow_set[borrow_index].borrowed_place,
+                            place,
+                            places_conflict::PlaceConflictBias::NoOverlap,
+                        );
+
+                        if places_conflict {
+                            let location_index = self.location_table.mid_index(location);
+                            self.all_facts.loan_killed_at.push((borrow_index, location_index));
                         }
                     }
                 }
             }
         }
     }
-}
 
-/// When recording facts for Polonius, records the borrows on the specified local as `killed`.
-fn record_killed_borrows_for_local(
-    all_facts: &mut AllFacts,
-    borrow_set: &BorrowSet<'_>,
-    location_table: &LocationTable,
-    local: Local,
-    location: Location,
-) {
-    if let Some(borrow_indices) = borrow_set.local_map.get(&local) {
-        all_facts.loan_killed_at.reserve(borrow_indices.len());
-        for &borrow_index in borrow_indices {
-            let location_index = location_table.mid_index(location);
-            all_facts.loan_killed_at.push((borrow_index, location_index));
+    /// When recording facts for Polonius, records the borrows on the specified local as `killed`.
+    fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) {
+        if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
+            let location_index = self.location_table.mid_index(location);
+            self.all_facts.loan_killed_at.reserve(borrow_indices.len());
+            for &borrow_index in borrow_indices {
+                self.all_facts.loan_killed_at.push((borrow_index, location_index));
+            }
         }
     }
 }
diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs
index c41afc8078a..0fbe221ad10 100644
--- a/compiler/rustc_borrowck/src/polonius/mod.rs
+++ b/compiler/rustc_borrowck/src/polonius/mod.rs
@@ -3,7 +3,6 @@
 //! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature
 //! parity.
 
-use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK};
 use rustc_middle::ty::TyCtxt;
 use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
@@ -150,11 +149,16 @@ pub(crate) fn emit_loan_invalidations_facts<'tcx>(
 
 /// Emit facts about CFG points and edges, as well as locations where loans are killed.
 pub(crate) fn emit_cfg_and_loan_kills_facts<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    tcx: TyCtxt<'tcx>,
     all_facts: &mut Option<AllFacts>,
     location_table: &LocationTable,
     body: &Body<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
 ) {
-    constraint_generation::generate_constraints(infcx, all_facts, location_table, body, borrow_set);
+    let Some(all_facts) = all_facts else {
+        // Nothing to do if we don't have any facts to fill
+        return;
+    };
+
+    constraint_generation::generate_constraints(tcx, all_facts, location_table, body, borrow_set);
 }