Skip to content
3 changes: 3 additions & 0 deletions compiler/rustc_borrowck/src/borrow_set.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cell::OnceCell;
use std::fmt;
use std::ops::Index;

Expand Down Expand Up @@ -84,6 +85,7 @@ pub struct BorrowData<'tcx> {
pub(crate) borrowed_place: mir::Place<'tcx>,
/// Place to which the borrow was stored
pub(crate) assigned_place: mir::Place<'tcx>,
pub(crate) dependent_regions: OnceCell<DenseBitSet<RegionVid>>,
}

// These methods are public to support borrowck consumers.
Expand Down Expand Up @@ -261,6 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
activation_location: TwoPhaseActivation::NotTwoPhase,
borrowed_place,
assigned_place: *assigned_place,
dependent_regions: OnceCell::new(),
};
let (idx, _) = self.location_map.insert_full(location, borrow);
let idx = BorrowIndex::from(idx);
Expand Down
30 changes: 29 additions & 1 deletion compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}

#[expect(dead_code)]
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
fn compute(
body: &Body<'tcx>,
Expand Down Expand Up @@ -476,11 +477,18 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set)
} else {
PoloniusOutOfScopePrecomputer::compute(body, regioncx, borrow_set)
unimplemented!() // This should probably be removed.
};
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
}

/// A dummy `Borrows` with no useful information.
///
/// Used for Polonius which doesn't need this.
pub fn dummy(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, borrow_set: &'a BorrowSet<'tcx>) -> Self {
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location: Default::default() }
}

/// Add all borrows to the kill set, if those borrows are out of scope at `location`.
/// That means they went out of a nonlexical scope
fn kill_loans_out_of_scope_at_location(
Expand Down Expand Up @@ -563,6 +571,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
const NAME: &'static str = "borrows";

fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
return DenseBitSet::new_empty(0);
}

// bottom = nothing is reserved or activated yet;
DenseBitSet::new_empty(self.borrow_set.len())
}
Expand All @@ -578,6 +590,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
_statement: &mir::Statement<'tcx>,
location: Location,
) {
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
return;
}

self.kill_loans_out_of_scope_at_location(state, location);
}

Expand All @@ -587,6 +603,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
stmt: &mir::Statement<'tcx>,
location: Location,
) {
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
return;
}

match &stmt.kind {
mir::StatementKind::Assign(box (lhs, rhs)) => {
if let mir::Rvalue::Ref(_, _, place) = rhs {
Expand Down Expand Up @@ -636,6 +656,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
return;
}

self.kill_loans_out_of_scope_at_location(state, location);
}

Expand All @@ -645,6 +669,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
terminator: &'mir mir::Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
return terminator.edges();
}

if let mir::TerminatorKind::InlineAsm { operands, .. } = &terminator.kind {
for op in operands {
if let mir::InlineAsmOperand::Out { place: Some(place), .. }
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
// We want to focus on relevant live locals in diagnostics, so when polonius is enabled, we
// ensure that we don't emit live boring locals as explanations.
let is_local_boring = |local| {
if let Some(polonius_diagnostics) = self.polonius_diagnostics {
polonius_diagnostics.boring_nll_locals.contains(&local)
if let Some(polonius) = &self.polonius {
polonius.pcx.is_boring_local(local)
} else {
assert!(!tcx.sess.opts.unstable_opts.polonius.is_next_enabled());

Expand Down
Loading
Loading