Skip to content

Commit 546643c

Browse files
Rollup merge of #118638 - nnethercote:rustc_mir_dataflow-more, r=cjgillot
More `rustc_mir_dataflow` cleanups r? `@cjgillot`
2 parents 0865eef + 4b364b6 commit 546643c

File tree

9 files changed

+102
-138
lines changed

9 files changed

+102
-138
lines changed

Diff for: compiler/rustc_borrowck/src/dataflow.rs

+70-83
Original file line numberDiff line numberDiff line change
@@ -11,101 +11,88 @@ use rustc_middle::ty::TyCtxt;
1111
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
1212
use rustc_mir_dataflow::ResultsVisitable;
1313
use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
14-
use rustc_mir_dataflow::{Analysis, Direction, Results};
14+
use rustc_mir_dataflow::{Analysis, AnalysisDomain, Results};
1515
use std::fmt;
1616

1717
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
1818

19-
/// A tuple with named fields that can hold either the results or the transient state of the
20-
/// dataflow analyses used by the borrow checker.
21-
#[derive(Debug)]
22-
pub struct BorrowckAnalyses<B, U, E> {
23-
pub borrows: B,
24-
pub uninits: U,
25-
pub ever_inits: E,
26-
}
27-
2819
/// The results of the dataflow analyses used by the borrow checker.
29-
pub type BorrowckResults<'mir, 'tcx> = BorrowckAnalyses<
30-
Results<'tcx, Borrows<'mir, 'tcx>>,
31-
Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
32-
Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
33-
>;
20+
pub struct BorrowckResults<'mir, 'tcx> {
21+
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
22+
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
23+
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
24+
}
3425

3526
/// The transient state of the dataflow analyses used by the borrow checker.
36-
pub type BorrowckFlowState<'mir, 'tcx> =
37-
<BorrowckResults<'mir, 'tcx> as ResultsVisitable<'tcx>>::FlowState;
38-
39-
macro_rules! impl_visitable {
40-
( $(
41-
$T:ident { $( $field:ident : $A:ident ),* $(,)? }
42-
)* ) => { $(
43-
impl<'tcx, $($A),*, D: Direction> ResultsVisitable<'tcx> for $T<$( Results<'tcx, $A> ),*>
44-
where
45-
$( $A: Analysis<'tcx, Direction = D>, )*
46-
{
47-
type Direction = D;
48-
type FlowState = $T<$( $A::Domain ),*>;
27+
#[derive(Debug)]
28+
pub struct BorrowckFlowState<'mir, 'tcx> {
29+
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
30+
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
31+
pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
32+
}
4933

50-
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
51-
$T {
52-
$( $field: self.$field.analysis.bottom_value(body) ),*
53-
}
54-
}
34+
impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> {
35+
// All three analyses are forward, but we have to use just one here.
36+
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
37+
type FlowState = BorrowckFlowState<'mir, 'tcx>;
5538

56-
fn reset_to_block_entry(
57-
&self,
58-
state: &mut Self::FlowState,
59-
block: BasicBlock,
60-
) {
61-
$( state.$field.clone_from(&self.$field.entry_set_for_block(block)); )*
62-
}
39+
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
40+
BorrowckFlowState {
41+
borrows: self.borrows.analysis.bottom_value(body),
42+
uninits: self.uninits.analysis.bottom_value(body),
43+
ever_inits: self.ever_inits.analysis.bottom_value(body),
44+
}
45+
}
6346

64-
fn reconstruct_before_statement_effect(
65-
&mut self,
66-
state: &mut Self::FlowState,
67-
stmt: &mir::Statement<'tcx>,
68-
loc: Location,
69-
) {
70-
$( self.$field.analysis
71-
.apply_before_statement_effect(&mut state.$field, stmt, loc); )*
72-
}
47+
fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
48+
state.borrows.clone_from(&self.borrows.entry_set_for_block(block));
49+
state.uninits.clone_from(&self.uninits.entry_set_for_block(block));
50+
state.ever_inits.clone_from(&self.ever_inits.entry_set_for_block(block));
51+
}
7352

74-
fn reconstruct_statement_effect(
75-
&mut self,
76-
state: &mut Self::FlowState,
77-
stmt: &mir::Statement<'tcx>,
78-
loc: Location,
79-
) {
80-
$( self.$field.analysis
81-
.apply_statement_effect(&mut state.$field, stmt, loc); )*
82-
}
53+
fn reconstruct_before_statement_effect(
54+
&mut self,
55+
state: &mut Self::FlowState,
56+
stmt: &mir::Statement<'tcx>,
57+
loc: Location,
58+
) {
59+
self.borrows.analysis.apply_before_statement_effect(&mut state.borrows, stmt, loc);
60+
self.uninits.analysis.apply_before_statement_effect(&mut state.uninits, stmt, loc);
61+
self.ever_inits.analysis.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
62+
}
8363

84-
fn reconstruct_before_terminator_effect(
85-
&mut self,
86-
state: &mut Self::FlowState,
87-
term: &mir::Terminator<'tcx>,
88-
loc: Location,
89-
) {
90-
$( self.$field.analysis
91-
.apply_before_terminator_effect(&mut state.$field, term, loc); )*
92-
}
64+
fn reconstruct_statement_effect(
65+
&mut self,
66+
state: &mut Self::FlowState,
67+
stmt: &mir::Statement<'tcx>,
68+
loc: Location,
69+
) {
70+
self.borrows.analysis.apply_statement_effect(&mut state.borrows, stmt, loc);
71+
self.uninits.analysis.apply_statement_effect(&mut state.uninits, stmt, loc);
72+
self.ever_inits.analysis.apply_statement_effect(&mut state.ever_inits, stmt, loc);
73+
}
9374

94-
fn reconstruct_terminator_effect(
95-
&mut self,
96-
state: &mut Self::FlowState,
97-
term: &mir::Terminator<'tcx>,
98-
loc: Location,
99-
) {
100-
$( self.$field.analysis
101-
.apply_terminator_effect(&mut state.$field, term, loc); )*
102-
}
103-
}
104-
)* }
105-
}
75+
fn reconstruct_before_terminator_effect(
76+
&mut self,
77+
state: &mut Self::FlowState,
78+
term: &mir::Terminator<'tcx>,
79+
loc: Location,
80+
) {
81+
self.borrows.analysis.apply_before_terminator_effect(&mut state.borrows, term, loc);
82+
self.uninits.analysis.apply_before_terminator_effect(&mut state.uninits, term, loc);
83+
self.ever_inits.analysis.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
84+
}
10685

107-
impl_visitable! {
108-
BorrowckAnalyses { borrows: B, uninits: U, ever_inits: E }
86+
fn reconstruct_terminator_effect(
87+
&mut self,
88+
state: &mut Self::FlowState,
89+
term: &mir::Terminator<'tcx>,
90+
loc: Location,
91+
) {
92+
self.borrows.analysis.apply_terminator_effect(&mut state.borrows, term, loc);
93+
self.uninits.analysis.apply_terminator_effect(&mut state.uninits, term, loc);
94+
self.ever_inits.analysis.apply_terminator_effect(&mut state.ever_inits, term, loc);
95+
}
10996
}
11097

11198
rustc_index::newtype_index! {
@@ -598,7 +585,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
598585

599586
fn before_terminator_effect(
600587
&mut self,
601-
trans: &mut impl GenKill<Self::Idx>,
588+
trans: &mut Self::Domain,
602589
_terminator: &mir::Terminator<'tcx>,
603590
location: Location,
604591
) {
@@ -625,7 +612,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
625612

626613
fn call_return_effect(
627614
&mut self,
628-
_trans: &mut impl GenKill<Self::Idx>,
615+
_trans: &mut Self::Domain,
629616
_block: mir::BasicBlock,
630617
_return_places: CallReturnPlaces<'_, 'tcx>,
631618
) {

Diff for: compiler/rustc_mir_dataflow/src/framework/direction.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl Direction for Backward {
196196
{
197197
results.reset_to_block_entry(state, block);
198198

199-
vis.visit_block_end(results, state, block_data, block);
199+
vis.visit_block_end(state);
200200

201201
// Terminator
202202
let loc = Location { block, statement_index: block_data.statements.len() };
@@ -214,7 +214,7 @@ impl Direction for Backward {
214214
vis.visit_statement_after_primary_effect(results, state, stmt, loc);
215215
}
216216

217-
vis.visit_block_start(results, state, block_data, block);
217+
vis.visit_block_start(state);
218218
}
219219

220220
fn join_state_into_successors_of<'tcx, A>(
@@ -449,7 +449,7 @@ impl Direction for Forward {
449449
{
450450
results.reset_to_block_entry(state, block);
451451

452-
vis.visit_block_start(results, state, block_data, block);
452+
vis.visit_block_start(state);
453453

454454
for (statement_index, stmt) in block_data.statements.iter().enumerate() {
455455
let loc = Location { block, statement_index };
@@ -466,7 +466,7 @@ impl Direction for Forward {
466466
results.reconstruct_terminator_effect(state, term, loc);
467467
vis.visit_terminator_after_primary_effect(results, state, term, loc);
468468

469-
vis.visit_block_end(results, state, block_data, block);
469+
vis.visit_block_end(state);
470470
}
471471

472472
fn join_state_into_successors_of<'tcx, A>(

Diff for: compiler/rustc_mir_dataflow/src/framework/graphviz.rs

+2-14
Original file line numberDiff line numberDiff line change
@@ -545,25 +545,13 @@ where
545545
{
546546
type FlowState = A::Domain;
547547

548-
fn visit_block_start(
549-
&mut self,
550-
_results: &mut Results<'tcx, A>,
551-
state: &Self::FlowState,
552-
_block_data: &mir::BasicBlockData<'tcx>,
553-
_block: BasicBlock,
554-
) {
548+
fn visit_block_start(&mut self, state: &Self::FlowState) {
555549
if A::Direction::IS_FORWARD {
556550
self.prev_state.clone_from(state);
557551
}
558552
}
559553

560-
fn visit_block_end(
561-
&mut self,
562-
_results: &mut Results<'tcx, A>,
563-
state: &Self::FlowState,
564-
_block_data: &mir::BasicBlockData<'tcx>,
565-
_block: BasicBlock,
566-
) {
554+
fn visit_block_end(&mut self, state: &Self::FlowState) {
567555
if A::Direction::IS_BACKWARD {
568556
self.prev_state.clone_from(state);
569557
}

Diff for: compiler/rustc_mir_dataflow/src/framework/mod.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -248,26 +248,28 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
248248

249249
/// A gen/kill dataflow problem.
250250
///
251-
/// Each method in this trait has a corresponding one in `Analysis`. However, these methods only
252-
/// allow modification of the dataflow state via "gen" and "kill" operations. By defining transfer
253-
/// functions for each statement in this way, the transfer function for an entire basic block can
254-
/// be computed efficiently.
251+
/// Each method in this trait has a corresponding one in `Analysis`. However, the first two methods
252+
/// here only allow modification of the dataflow state via "gen" and "kill" operations. By defining
253+
/// transfer functions for each statement in this way, the transfer function for an entire basic
254+
/// block can be computed efficiently. The remaining methods match up with `Analysis` exactly.
255255
///
256-
/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis`.
256+
/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis` via a blanket
257+
/// impl below.
257258
pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
258259
type Idx: Idx;
259260

260261
fn domain_size(&self, body: &mir::Body<'tcx>) -> usize;
261262

262-
/// See `Analysis::apply_statement_effect`.
263+
/// See `Analysis::apply_statement_effect`. Note how the second arg differs.
263264
fn statement_effect(
264265
&mut self,
265266
trans: &mut impl GenKill<Self::Idx>,
266267
statement: &mir::Statement<'tcx>,
267268
location: Location,
268269
);
269270

270-
/// See `Analysis::apply_before_statement_effect`.
271+
/// See `Analysis::apply_before_statement_effect`. Note how the second arg
272+
/// differs.
271273
fn before_statement_effect(
272274
&mut self,
273275
_trans: &mut impl GenKill<Self::Idx>,
@@ -287,7 +289,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
287289
/// See `Analysis::apply_before_terminator_effect`.
288290
fn before_terminator_effect(
289291
&mut self,
290-
_trans: &mut impl GenKill<Self::Idx>,
292+
_trans: &mut Self::Domain,
291293
_terminator: &mir::Terminator<'tcx>,
292294
_location: Location,
293295
) {
@@ -298,7 +300,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
298300
/// See `Analysis::apply_call_return_effect`.
299301
fn call_return_effect(
300302
&mut self,
301-
trans: &mut impl GenKill<Self::Idx>,
303+
trans: &mut Self::Domain,
302304
block: BasicBlock,
303305
return_places: CallReturnPlaces<'_, 'tcx>,
304306
);
@@ -313,6 +315,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
313315
}
314316
}
315317

318+
// Blanket impl: any impl of `GenKillAnalysis` automatically impls `Analysis`.
316319
impl<'tcx, A> Analysis<'tcx> for A
317320
where
318321
A: GenKillAnalysis<'tcx>,

Diff for: compiler/rustc_mir_dataflow/src/framework/visitor.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,7 @@ pub fn visit_results<'mir, 'tcx, F, R>(
3131
pub trait ResultsVisitor<'mir, 'tcx, R> {
3232
type FlowState;
3333

34-
fn visit_block_start(
35-
&mut self,
36-
_results: &mut R,
37-
_state: &Self::FlowState,
38-
_block_data: &'mir mir::BasicBlockData<'tcx>,
39-
_block: BasicBlock,
40-
) {
41-
}
34+
fn visit_block_start(&mut self, _state: &Self::FlowState) {}
4235

4336
/// Called with the `before_statement_effect` of the given statement applied to `state` but not
4437
/// its `statement_effect`.
@@ -86,20 +79,13 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
8679
) {
8780
}
8881

89-
fn visit_block_end(
90-
&mut self,
91-
_results: &mut R,
92-
_state: &Self::FlowState,
93-
_block_data: &'mir mir::BasicBlockData<'tcx>,
94-
_block: BasicBlock,
95-
) {
96-
}
82+
fn visit_block_end(&mut self, _state: &Self::FlowState) {}
9783
}
9884

9985
/// Things that can be visited by a `ResultsVisitor`.
10086
///
101-
/// This trait exists so that we can visit the results of multiple dataflow analyses simultaneously.
102-
/// DO NOT IMPLEMENT MANUALLY. Instead, use the `impl_visitable` macro below.
87+
/// This trait exists so that we can visit the results of one or more dataflow analyses
88+
/// simultaneously.
10389
pub trait ResultsVisitable<'tcx> {
10490
type Direction: Direction;
10591
type FlowState;

Diff for: compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals {
6262

6363
fn call_return_effect(
6464
&mut self,
65-
_trans: &mut impl GenKill<Self::Idx>,
65+
_trans: &mut Self::Domain,
6666
_block: BasicBlock,
6767
_return_places: CallReturnPlaces<'_, 'tcx>,
6868
) {

Diff for: compiler/rustc_mir_dataflow/src/impls/initialized.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
376376

377377
fn call_return_effect(
378378
&mut self,
379-
trans: &mut impl GenKill<Self::Idx>,
379+
trans: &mut Self::Domain,
380380
_block: mir::BasicBlock,
381381
return_places: CallReturnPlaces<'_, 'tcx>,
382382
) {
@@ -499,7 +499,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
499499

500500
fn call_return_effect(
501501
&mut self,
502-
trans: &mut impl GenKill<Self::Idx>,
502+
trans: &mut Self::Domain,
503503
_block: mir::BasicBlock,
504504
return_places: CallReturnPlaces<'_, 'tcx>,
505505
) {
@@ -617,7 +617,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
617617

618618
fn call_return_effect(
619619
&mut self,
620-
trans: &mut impl GenKill<Self::Idx>,
620+
trans: &mut Self::Domain,
621621
_block: mir::BasicBlock,
622622
return_places: CallReturnPlaces<'_, 'tcx>,
623623
) {
@@ -712,7 +712,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
712712

713713
fn call_return_effect(
714714
&mut self,
715-
trans: &mut impl GenKill<Self::Idx>,
715+
trans: &mut Self::Domain,
716716
block: mir::BasicBlock,
717717
_return_places: CallReturnPlaces<'_, 'tcx>,
718718
) {

0 commit comments

Comments
 (0)