summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/dataflow.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_borrowck/src/dataflow.rs
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/dataflow.rs')
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs193
1 files changed, 91 insertions, 102 deletions
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 8676d2ba7..1bd891bdd 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -10,105 +10,93 @@ use rustc_middle::ty::RegionVid;
use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
use rustc_mir_dataflow::ResultsVisitable;
-use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
-use rustc_mir_dataflow::{Analysis, Direction, Results};
+use rustc_mir_dataflow::{fmt::DebugWithContext, GenKill};
+use rustc_mir_dataflow::{Analysis, AnalysisDomain, Results};
use std::fmt;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
-/// A tuple with named fields that can hold either the results or the transient state of the
-/// dataflow analyses used by the borrow checker.
-#[derive(Debug)]
-pub struct BorrowckAnalyses<B, U, E> {
- pub borrows: B,
- pub uninits: U,
- pub ever_inits: E,
-}
-
/// The results of the dataflow analyses used by the borrow checker.
-pub type BorrowckResults<'mir, 'tcx> = BorrowckAnalyses<
- Results<'tcx, Borrows<'mir, 'tcx>>,
- Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
- Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
->;
+pub struct BorrowckResults<'mir, 'tcx> {
+ pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
+ pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
+ pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
+}
/// The transient state of the dataflow analyses used by the borrow checker.
-pub type BorrowckFlowState<'mir, 'tcx> =
- <BorrowckResults<'mir, 'tcx> as ResultsVisitable<'tcx>>::FlowState;
-
-macro_rules! impl_visitable {
- ( $(
- $T:ident { $( $field:ident : $A:ident ),* $(,)? }
- )* ) => { $(
- impl<'tcx, $($A),*, D: Direction> ResultsVisitable<'tcx> for $T<$( Results<'tcx, $A> ),*>
- where
- $( $A: Analysis<'tcx, Direction = D>, )*
- {
- type Direction = D;
- type FlowState = $T<$( $A::Domain ),*>;
+#[derive(Debug)]
+pub struct BorrowckFlowState<'mir, 'tcx> {
+ pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
+ pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
+ pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
+}
- fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
- $T {
- $( $field: self.$field.analysis.bottom_value(body) ),*
- }
- }
+impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> {
+ // All three analyses are forward, but we have to use just one here.
+ type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
+ type FlowState = BorrowckFlowState<'mir, 'tcx>;
- fn reset_to_block_entry(
- &self,
- state: &mut Self::FlowState,
- block: BasicBlock,
- ) {
- $( state.$field.clone_from(&self.$field.entry_set_for_block(block)); )*
- }
+ fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
+ BorrowckFlowState {
+ borrows: self.borrows.analysis.bottom_value(body),
+ uninits: self.uninits.analysis.bottom_value(body),
+ ever_inits: self.ever_inits.analysis.bottom_value(body),
+ }
+ }
- fn reconstruct_before_statement_effect(
- &mut self,
- state: &mut Self::FlowState,
- stmt: &mir::Statement<'tcx>,
- loc: Location,
- ) {
- $( self.$field.analysis
- .apply_before_statement_effect(&mut state.$field, stmt, loc); )*
- }
+ fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
+ state.borrows.clone_from(&self.borrows.entry_set_for_block(block));
+ state.uninits.clone_from(&self.uninits.entry_set_for_block(block));
+ state.ever_inits.clone_from(&self.ever_inits.entry_set_for_block(block));
+ }
- fn reconstruct_statement_effect(
- &mut self,
- state: &mut Self::FlowState,
- stmt: &mir::Statement<'tcx>,
- loc: Location,
- ) {
- $( self.$field.analysis
- .apply_statement_effect(&mut state.$field, stmt, loc); )*
- }
+ fn reconstruct_before_statement_effect(
+ &mut self,
+ state: &mut Self::FlowState,
+ stmt: &mir::Statement<'tcx>,
+ loc: Location,
+ ) {
+ self.borrows.analysis.apply_before_statement_effect(&mut state.borrows, stmt, loc);
+ self.uninits.analysis.apply_before_statement_effect(&mut state.uninits, stmt, loc);
+ self.ever_inits.analysis.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
+ }
- fn reconstruct_before_terminator_effect(
- &mut self,
- state: &mut Self::FlowState,
- term: &mir::Terminator<'tcx>,
- loc: Location,
- ) {
- $( self.$field.analysis
- .apply_before_terminator_effect(&mut state.$field, term, loc); )*
- }
+ fn reconstruct_statement_effect(
+ &mut self,
+ state: &mut Self::FlowState,
+ stmt: &mir::Statement<'tcx>,
+ loc: Location,
+ ) {
+ self.borrows.analysis.apply_statement_effect(&mut state.borrows, stmt, loc);
+ self.uninits.analysis.apply_statement_effect(&mut state.uninits, stmt, loc);
+ self.ever_inits.analysis.apply_statement_effect(&mut state.ever_inits, stmt, loc);
+ }
- fn reconstruct_terminator_effect(
- &mut self,
- state: &mut Self::FlowState,
- term: &mir::Terminator<'tcx>,
- loc: Location,
- ) {
- $( self.$field.analysis
- .apply_terminator_effect(&mut state.$field, term, loc); )*
- }
- }
- )* }
-}
+ fn reconstruct_before_terminator_effect(
+ &mut self,
+ state: &mut Self::FlowState,
+ term: &mir::Terminator<'tcx>,
+ loc: Location,
+ ) {
+ self.borrows.analysis.apply_before_terminator_effect(&mut state.borrows, term, loc);
+ self.uninits.analysis.apply_before_terminator_effect(&mut state.uninits, term, loc);
+ self.ever_inits.analysis.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
+ }
-impl_visitable! {
- BorrowckAnalyses { borrows: B, uninits: U, ever_inits: E }
+ fn reconstruct_terminator_effect(
+ &mut self,
+ state: &mut Self::FlowState,
+ term: &mir::Terminator<'tcx>,
+ loc: Location,
+ ) {
+ self.borrows.analysis.apply_terminator_effect(&mut state.borrows, term, loc);
+ self.uninits.analysis.apply_terminator_effect(&mut state.uninits, term, loc);
+ self.ever_inits.analysis.apply_terminator_effect(&mut state.ever_inits, term, loc);
+ }
}
rustc_index::newtype_index! {
+ #[orderable]
#[debug_format = "bw{}"]
pub struct BorrowIndex {}
}
@@ -120,24 +108,24 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors.
-pub struct Borrows<'a, 'tcx> {
+pub struct Borrows<'mir, 'tcx> {
tcx: TyCtxt<'tcx>,
- body: &'a Body<'tcx>,
+ body: &'mir Body<'tcx>,
- borrow_set: &'a BorrowSet<'tcx>,
+ borrow_set: &'mir BorrowSet<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}
-struct OutOfScopePrecomputer<'a, 'tcx> {
+struct OutOfScopePrecomputer<'mir, 'tcx> {
visited: BitSet<mir::BasicBlock>,
visit_stack: Vec<mir::BasicBlock>,
- body: &'a Body<'tcx>,
- regioncx: &'a RegionInferenceContext<'tcx>,
+ body: &'mir Body<'tcx>,
+ regioncx: &'mir RegionInferenceContext<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}
-impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> {
- fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
+impl<'mir, 'tcx> OutOfScopePrecomputer<'mir, 'tcx> {
+ fn new(body: &'mir Body<'tcx>, regioncx: &'mir RegionInferenceContext<'tcx>) -> Self {
OutOfScopePrecomputer {
visited: BitSet::new_empty(body.basic_blocks.len()),
visit_stack: vec![],
@@ -240,17 +228,17 @@ pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
prec.borrows_out_of_scope_at_location
}
-struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
+struct PoloniusOutOfScopePrecomputer<'mir, 'tcx> {
visited: BitSet<mir::BasicBlock>,
visit_stack: Vec<mir::BasicBlock>,
- body: &'a Body<'tcx>,
- regioncx: &'a RegionInferenceContext<'tcx>,
+ body: &'mir Body<'tcx>,
+ regioncx: &'mir RegionInferenceContext<'tcx>,
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}
-impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
- fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
+impl<'mir, 'tcx> PoloniusOutOfScopePrecomputer<'mir, 'tcx> {
+ fn new(body: &'mir Body<'tcx>, regioncx: &'mir RegionInferenceContext<'tcx>) -> Self {
Self {
visited: BitSet::new_empty(body.basic_blocks.len()),
visit_stack: vec![],
@@ -403,12 +391,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
}
}
-impl<'a, 'tcx> Borrows<'a, 'tcx> {
+impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
- body: &'a Body<'tcx>,
- regioncx: &'a RegionInferenceContext<'tcx>,
- borrow_set: &'a BorrowSet<'tcx>,
+ body: &'mir Body<'tcx>,
+ regioncx: &'mir RegionInferenceContext<'tcx>,
+ borrow_set: &'mir BorrowSet<'tcx>,
) -> Self {
let mut borrows_out_of_scope_at_location =
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
@@ -431,7 +419,8 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
assert_eq!(
borrows_out_of_scope_at_location, polonius_prec.loans_out_of_scope_at_location,
- "the loans out of scope must be the same as the borrows out of scope"
+ "polonius loan scopes differ from NLL borrow scopes, for body {:?}",
+ body.span,
);
borrows_out_of_scope_at_location = polonius_prec.loans_out_of_scope_at_location;
@@ -596,7 +585,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
fn before_terminator_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
@@ -623,7 +612,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
fn call_return_effect(
&mut self,
- _trans: &mut impl GenKill<Self::Idx>,
+ _trans: &mut Self::Domain,
_block: mir::BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {