Skip to content

Commit eaddc37

Browse files
committed
Take MIR dataflow analyses by mutable reference.
1 parent fdd0301 commit eaddc37

File tree

19 files changed

+491
-288
lines changed

19 files changed

+491
-288
lines changed

compiler/rustc_borrowck/src/dataflow.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ macro_rules! impl_visitable {
5959
}
6060

6161
fn reconstruct_before_statement_effect(
62-
&self,
62+
&mut self,
6363
state: &mut Self::FlowState,
6464
stmt: &mir::Statement<'tcx>,
6565
loc: Location,
@@ -69,7 +69,7 @@ macro_rules! impl_visitable {
6969
}
7070

7171
fn reconstruct_statement_effect(
72-
&self,
72+
&mut self,
7373
state: &mut Self::FlowState,
7474
stmt: &mir::Statement<'tcx>,
7575
loc: Location,
@@ -79,7 +79,7 @@ macro_rules! impl_visitable {
7979
}
8080

8181
fn reconstruct_before_terminator_effect(
82-
&self,
82+
&mut self,
8383
state: &mut Self::FlowState,
8484
term: &mir::Terminator<'tcx>,
8585
loc: Location,
@@ -89,7 +89,7 @@ macro_rules! impl_visitable {
8989
}
9090

9191
fn reconstruct_terminator_effect(
92-
&self,
92+
&mut self,
9393
state: &mut Self::FlowState,
9494
term: &mir::Terminator<'tcx>,
9595
loc: Location,
@@ -341,7 +341,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
341341
type Idx = BorrowIndex;
342342

343343
fn before_statement_effect(
344-
&self,
344+
&mut self,
345345
trans: &mut impl GenKill<Self::Idx>,
346346
_statement: &mir::Statement<'tcx>,
347347
location: Location,
@@ -350,7 +350,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
350350
}
351351

352352
fn statement_effect(
353-
&self,
353+
&mut self,
354354
trans: &mut impl GenKill<Self::Idx>,
355355
stmt: &mir::Statement<'tcx>,
356356
location: Location,
@@ -398,7 +398,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
398398
}
399399

400400
fn before_terminator_effect(
401-
&self,
401+
&mut self,
402402
trans: &mut impl GenKill<Self::Idx>,
403403
_terminator: &mir::Terminator<'tcx>,
404404
location: Location,
@@ -407,7 +407,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
407407
}
408408

409409
fn terminator_effect(
410-
&self,
410+
&mut self,
411411
trans: &mut impl GenKill<Self::Idx>,
412412
terminator: &mir::Terminator<'tcx>,
413413
_location: Location,
@@ -424,7 +424,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
424424
}
425425

426426
fn call_return_effect(
427-
&self,
427+
&mut self,
428428
_trans: &mut impl GenKill<Self::Idx>,
429429
_block: mir::BasicBlock,
430430
_return_places: CallReturnPlaces<'_, 'tcx>,

compiler/rustc_borrowck/src/lib.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ fn do_mir_borrowck<'tcx>(
372372
// Compute and report region errors, if any.
373373
mbcx.report_region_errors(nll_errors);
374374

375-
let results = BorrowckResults {
375+
let mut results = BorrowckResults {
376376
ever_inits: flow_ever_inits,
377377
uninits: flow_uninits,
378378
borrows: flow_borrows,
@@ -383,7 +383,7 @@ fn do_mir_borrowck<'tcx>(
383383
rustc_mir_dataflow::visit_results(
384384
body,
385385
traversal::reverse_postorder(body).map(|(bb, _)| bb),
386-
&results,
386+
&mut results,
387387
&mut mbcx,
388388
);
389389

@@ -618,11 +618,12 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
618618
// 2. loans made in overlapping scopes do not conflict
619619
// 3. assignments do not affect things loaned out as immutable
620620
// 4. moves do not affect things loaned out in any way
621-
impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx> {
621+
impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorrowckCtxt<'cx, 'tcx> {
622622
type FlowState = Flows<'cx, 'tcx>;
623623

624624
fn visit_statement_before_primary_effect(
625625
&mut self,
626+
_results: &R,
626627
flow_state: &Flows<'cx, 'tcx>,
627628
stmt: &'cx Statement<'tcx>,
628629
location: Location,
@@ -692,6 +693,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
692693

693694
fn visit_terminator_before_primary_effect(
694695
&mut self,
696+
_results: &R,
695697
flow_state: &Flows<'cx, 'tcx>,
696698
term: &'cx Terminator<'tcx>,
697699
loc: Location,
@@ -800,6 +802,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
800802

801803
fn visit_terminator_after_primary_effect(
802804
&mut self,
805+
_results: &R,
803806
flow_state: &Flows<'cx, 'tcx>,
804807
term: &'cx Terminator<'tcx>,
805808
loc: Location,

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ where
337337
Q: Qualif,
338338
{
339339
fn apply_statement_effect(
340-
&self,
340+
&mut self,
341341
state: &mut Self::Domain,
342342
statement: &mir::Statement<'tcx>,
343343
location: Location,
@@ -346,7 +346,7 @@ where
346346
}
347347

348348
fn apply_terminator_effect(
349-
&self,
349+
&mut self,
350350
state: &mut Self::Domain,
351351
terminator: &mir::Terminator<'tcx>,
352352
location: Location,
@@ -355,7 +355,7 @@ where
355355
}
356356

357357
fn apply_call_return_effect(
358-
&self,
358+
&mut self,
359359
state: &mut Self::Domain,
360360
block: BasicBlock,
361361
return_places: CallReturnPlaces<'_, 'tcx>,

compiler/rustc_mir_dataflow/src/framework/cursor.rs

+97-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,60 @@
11
//! Random access inspection of the results of a dataflow analysis.
22
3-
use crate::framework::BitSetExt;
3+
use crate::{framework::BitSetExt, CloneAnalysis};
44

5-
use std::borrow::Borrow;
5+
use std::borrow::{Borrow, BorrowMut};
66
use std::cmp::Ordering;
77

88
#[cfg(debug_assertions)]
99
use rustc_index::bit_set::BitSet;
1010
use rustc_middle::mir::{self, BasicBlock, Location};
1111

12-
use super::{Analysis, Direction, Effect, EffectIndex, Results};
12+
use super::{Analysis, Direction, Effect, EffectIndex, EntrySets, Results, ResultsCloned};
13+
14+
// `AnalysisResults` is needed as an impl such as the following has an unconstrained type
15+
// parameter:
16+
// ```
17+
// impl<'tcx, A, E, R> ResultsCursor<'_, 'tcx, A, R>
18+
// where
19+
// A: Analysis<'tcx>,
20+
// E: Borrow<EntrySets<'tcx, A>>,
21+
// R: Results<'tcx, A, E>,
22+
// {}
23+
// ```
24+
25+
/// A type representing the analysis results consumed by a `ResultsCursor`.
26+
pub trait AnalysisResults<'tcx, A>: BorrowMut<Results<'tcx, A, Self::EntrySets>>
27+
where
28+
A: Analysis<'tcx>,
29+
{
30+
/// The type containing the entry sets for this `Results` type.
31+
///
32+
/// Should be either `EntrySets<'tcx, A>` or `&EntrySets<'tcx, A>`.
33+
type EntrySets: Borrow<EntrySets<'tcx, A>>;
34+
}
35+
impl<'tcx, A, E> AnalysisResults<'tcx, A> for Results<'tcx, A, E>
36+
where
37+
A: Analysis<'tcx>,
38+
E: Borrow<EntrySets<'tcx, A>>,
39+
{
40+
type EntrySets = E;
41+
}
42+
impl<'a, 'tcx, A, E> AnalysisResults<'tcx, A> for &'a mut Results<'tcx, A, E>
43+
where
44+
A: Analysis<'tcx>,
45+
E: Borrow<EntrySets<'tcx, A>>,
46+
{
47+
type EntrySets = E;
48+
}
1349

1450
/// A `ResultsCursor` that borrows the underlying `Results`.
15-
pub type ResultsRefCursor<'a, 'mir, 'tcx, A> = ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>;
51+
pub type ResultsRefCursor<'res, 'mir, 'tcx, A> =
52+
ResultsCursor<'mir, 'tcx, A, &'res mut Results<'tcx, A>>;
53+
54+
/// A `ResultsCursor` which uses a cloned `Analysis` while borrowing the underlying `Results`. This
55+
/// allows multiple cursors over the same `Results`.
56+
pub type ResultsClonedCursor<'res, 'mir, 'tcx, A> =
57+
ResultsCursor<'mir, 'tcx, A, ResultsCloned<'res, 'tcx, A>>;
1658

1759
/// Allows random access inspection of the results of a dataflow analysis.
1860
///
@@ -45,7 +87,38 @@ where
4587
impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
4688
where
4789
A: Analysis<'tcx>,
48-
R: Borrow<Results<'tcx, A>>,
90+
{
91+
/// Returns the dataflow state at the current location.
92+
pub fn get(&self) -> &A::Domain {
93+
&self.state
94+
}
95+
96+
/// Returns the body this analysis was run on.
97+
pub fn body(&self) -> &'mir mir::Body<'tcx> {
98+
self.body
99+
}
100+
101+
/// Unwraps this cursor, returning the underlying `Results`.
102+
pub fn into_results(self) -> R {
103+
self.results
104+
}
105+
}
106+
107+
impl<'res, 'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A, ResultsCloned<'res, 'tcx, A>>
108+
where
109+
A: Analysis<'tcx> + CloneAnalysis,
110+
{
111+
/// Creates a new cursor over the same `Results`. Note that the cursor's position is *not*
112+
/// copied.
113+
pub fn new_cursor(&self) -> Self {
114+
Self::new(self.body, self.results.reclone_analysis())
115+
}
116+
}
117+
118+
impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
119+
where
120+
A: Analysis<'tcx>,
121+
R: AnalysisResults<'tcx, A>,
49122
{
50123
/// Returns a new cursor that can inspect `results`.
51124
pub fn new(body: &'mir mir::Body<'tcx>, results: R) -> Self {
@@ -74,18 +147,28 @@ where
74147
}
75148

76149
/// Returns the underlying `Results`.
77-
pub fn results(&self) -> &Results<'tcx, A> {
78-
&self.results.borrow()
150+
pub fn results(&mut self) -> &Results<'tcx, A, R::EntrySets> {
151+
self.results.borrow()
152+
}
153+
154+
/// Returns the underlying `Results`.
155+
pub fn mut_results(&mut self) -> &mut Results<'tcx, A, R::EntrySets> {
156+
self.results.borrow_mut()
79157
}
80158

81159
/// Returns the `Analysis` used to generate the underlying `Results`.
82160
pub fn analysis(&self) -> &A {
83161
&self.results.borrow().analysis
84162
}
85163

86-
/// Returns the dataflow state at the current location.
87-
pub fn get(&self) -> &A::Domain {
88-
&self.state
164+
/// Returns the `Analysis` used to generate the underlying `Results`.
165+
pub fn mut_analysis(&mut self) -> &mut A {
166+
&mut self.results.borrow_mut().analysis
167+
}
168+
169+
/// Returns both the dataflow state at the current location and the `Analysis`.
170+
pub fn get_with_analysis(&mut self) -> (&A::Domain, &mut A) {
171+
(&self.state, &mut self.results.borrow_mut().analysis)
89172
}
90173

91174
/// Resets the cursor to hold the entry set for the given basic block.
@@ -97,7 +180,7 @@ where
97180
#[cfg(debug_assertions)]
98181
assert!(self.reachable_blocks.contains(block));
99182

100-
self.state.clone_from(&self.results.borrow().entry_set_for_block(block));
183+
self.state.clone_from(self.results.borrow().entry_set_for_block(block));
101184
self.pos = CursorPosition::block_entry(block);
102185
self.state_needs_reset = false;
103186
}
@@ -186,7 +269,7 @@ where
186269
)
187270
};
188271

189-
let analysis = &self.results.borrow().analysis;
272+
let analysis = &mut self.results.borrow_mut().analysis;
190273
let target_effect_index = effect.at_index(target.statement_index);
191274

192275
A::Direction::apply_effects_in_range(
@@ -205,8 +288,8 @@ where
205288
///
206289
/// This can be used, e.g., to apply the call return effect directly to the cursor without
207290
/// creating an extra copy of the dataflow state.
208-
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
209-
f(&self.results.borrow().analysis, &mut self.state);
291+
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
292+
f(&mut self.results.borrow_mut().analysis, &mut self.state);
210293
self.state_needs_reset = true;
211294
}
212295
}
@@ -215,7 +298,6 @@ impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
215298
where
216299
A: crate::GenKillAnalysis<'tcx>,
217300
A::Domain: BitSetExt<A::Idx>,
218-
R: Borrow<Results<'tcx, A>>,
219301
{
220302
pub fn contains(&self, elem: A::Idx) -> bool {
221303
self.get().contains(elem)

0 commit comments

Comments
 (0)