Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 77f7e0d

Browse files
committed
Auto merge of rust-lang#141326 - tage64:horatio, r=<try>
[experimental, do not merge!] a faster implementation of Polonius This is an experiment to use a more lazy approach to Polonius by only invoking the location-sensitive analysis when needed and using NLL otherwise. This means all programs that currently compile will still use NLL for borrow checking, and the experimental location-sensitive analysis will only be triggered if NLL encounters an invalid access. The idea is that it should not affect performance significantly for existing programs that compile with NLL. However, it still alters the computation of active loans in rustc_borrowck, and I want a perf run to measure the performance impact. I expect a slight regression but hopefully not so much. r? lqd
2 parents 87b4541 + 95e1a43 commit 77f7e0d

File tree

27 files changed

+2720
-447
lines changed

27 files changed

+2720
-447
lines changed

compiler/rustc_borrowck/src/borrow_set.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::OnceCell;
12
use std::fmt;
23
use std::ops::Index;
34

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

8991
// These methods are public to support borrowck consumers.
@@ -261,6 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
261263
activation_location: TwoPhaseActivation::NotTwoPhase,
262264
borrowed_place,
263265
assigned_place: *assigned_place,
266+
dependent_regions: OnceCell::new(),
264267
};
265268
let (idx, _) = self.location_map.insert_full(location, borrow);
266269
let idx = BorrowIndex::from(idx);

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
301301
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
302302
}
303303

304+
#[expect(dead_code)]
304305
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
305306
fn compute(
306307
body: &Body<'tcx>,
@@ -476,11 +477,18 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
476477
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
477478
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set)
478479
} else {
479-
PoloniusOutOfScopePrecomputer::compute(body, regioncx, borrow_set)
480+
unimplemented!() // This should probably be removed.
480481
};
481482
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
482483
}
483484

485+
/// A dummy `Borrows` with no useful information.
486+
///
487+
/// Used for Polonius which doesn't need this.
488+
pub fn dummy(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, borrow_set: &'a BorrowSet<'tcx>) -> Self {
489+
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location: Default::default() }
490+
}
491+
484492
/// Add all borrows to the kill set, if those borrows are out of scope at `location`.
485493
/// That means they went out of a nonlexical scope
486494
fn kill_loans_out_of_scope_at_location(
@@ -563,6 +571,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
563571
const NAME: &'static str = "borrows";
564572

565573
fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
574+
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
575+
return DenseBitSet::new_empty(0);
576+
}
577+
566578
// bottom = nothing is reserved or activated yet;
567579
DenseBitSet::new_empty(self.borrow_set.len())
568580
}
@@ -578,6 +590,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
578590
_statement: &mir::Statement<'tcx>,
579591
location: Location,
580592
) {
593+
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
594+
return;
595+
}
596+
581597
self.kill_loans_out_of_scope_at_location(state, location);
582598
}
583599

@@ -587,6 +603,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
587603
stmt: &mir::Statement<'tcx>,
588604
location: Location,
589605
) {
606+
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
607+
return;
608+
}
609+
590610
match &stmt.kind {
591611
mir::StatementKind::Assign(box (lhs, rhs)) => {
592612
if let mir::Rvalue::Ref(_, _, place) = rhs {
@@ -636,6 +656,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
636656
_terminator: &mir::Terminator<'tcx>,
637657
location: Location,
638658
) {
659+
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
660+
return;
661+
}
662+
639663
self.kill_loans_out_of_scope_at_location(state, location);
640664
}
641665

@@ -645,6 +669,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
645669
terminator: &'mir mir::Terminator<'tcx>,
646670
_location: Location,
647671
) -> TerminatorEdges<'mir, 'tcx> {
672+
if !self.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
673+
return terminator.edges();
674+
}
675+
648676
if let mir::TerminatorKind::InlineAsm { operands, .. } = &terminator.kind {
649677
for op in operands {
650678
if let mir::InlineAsmOperand::Out { place: Some(place), .. }

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,8 +632,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
632632
// We want to focus on relevant live locals in diagnostics, so when polonius is enabled, we
633633
// ensure that we don't emit live boring locals as explanations.
634634
let is_local_boring = |local| {
635-
if let Some(polonius_diagnostics) = self.polonius_diagnostics {
636-
polonius_diagnostics.boring_nll_locals.contains(&local)
635+
if let Some(polonius) = &self.polonius {
636+
polonius.pcx.is_boring_local(local)
637637
} else {
638638
assert!(!tcx.sess.opts.unstable_opts.polonius.is_next_enabled());
639639

0 commit comments

Comments
 (0)