Skip to content

Commit a97cd3b

Browse files
committed
Make Analysis immutable in many more places.
The `state: A::Domain` value is the primary things that's modified when performing an analysis. The `Analysis` impl is immutable in every case but one (`MaybeRequiredStorage`) and it now uses interior mutability. As well as changing many `&mut A` arguments to `&A`, this also: - lets `CowMut` be replaced with the simpler `SimpleCow` in `cursor.rs`; - removes the need for the `RefCell` in `Formatter`; - removes the need for `MaybeBorrowedLocals` to impl `Clone`, because it's a unit type and it's now clear that its constructor can be used directly instead of being put into a local variable and cloned.
1 parent 8afbd9f commit a97cd3b

File tree

16 files changed

+111
-140
lines changed

16 files changed

+111
-140
lines changed

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
4444
}
4545

4646
fn apply_early_statement_effect(
47-
&mut self,
47+
&self,
4848
state: &mut Self::Domain,
4949
stmt: &mir::Statement<'tcx>,
5050
loc: Location,
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
5555
}
5656

5757
fn apply_primary_statement_effect(
58-
&mut self,
58+
&self,
5959
state: &mut Self::Domain,
6060
stmt: &mir::Statement<'tcx>,
6161
loc: Location,
@@ -66,7 +66,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
6666
}
6767

6868
fn apply_early_terminator_effect(
69-
&mut self,
69+
&self,
7070
state: &mut Self::Domain,
7171
term: &mir::Terminator<'tcx>,
7272
loc: Location,
@@ -77,7 +77,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
7777
}
7878

7979
fn apply_primary_terminator_effect<'mir>(
80-
&mut self,
80+
&self,
8181
state: &mut Self::Domain,
8282
term: &'mir mir::Terminator<'tcx>,
8383
loc: Location,
@@ -92,7 +92,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
9292
}
9393

9494
fn apply_call_return_effect(
95-
&mut self,
95+
&self,
9696
_state: &mut Self::Domain,
9797
_block: BasicBlock,
9898
_return_places: CallReturnPlaces<'_, 'tcx>,
@@ -533,7 +533,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
533533
}
534534

535535
fn apply_early_statement_effect(
536-
&mut self,
536+
&self,
537537
state: &mut Self::Domain,
538538
_statement: &mir::Statement<'tcx>,
539539
location: Location,
@@ -542,7 +542,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
542542
}
543543

544544
fn apply_primary_statement_effect(
545-
&mut self,
545+
&self,
546546
state: &mut Self::Domain,
547547
stmt: &mir::Statement<'tcx>,
548548
location: Location,
@@ -590,7 +590,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
590590
}
591591

592592
fn apply_early_terminator_effect(
593-
&mut self,
593+
&self,
594594
state: &mut Self::Domain,
595595
_terminator: &mir::Terminator<'tcx>,
596596
location: Location,
@@ -599,7 +599,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
599599
}
600600

601601
fn apply_primary_terminator_effect<'mir>(
602-
&mut self,
602+
&self,
603603
state: &mut Self::Domain,
604604
terminator: &'mir mir::Terminator<'tcx>,
605605
_location: Location,

compiler/rustc_borrowck/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,13 +537,13 @@ fn borrowck_check_region_constraints<'tcx>(
537537
mbcx.report_region_errors(nll_errors);
538538
}
539539

540-
let (mut flow_analysis, flow_entry_states) =
540+
let (flow_analysis, flow_results) =
541541
get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
542542
visit_results(
543543
body,
544544
traversal::reverse_postorder(body).map(|(bb, _)| bb),
545-
&mut flow_analysis,
546-
&flow_entry_states,
545+
&flow_analysis,
546+
&flow_results,
547547
&mut mbcx,
548548
);
549549

compiler/rustc_const_eval/src/check_consts/resolver.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ where
332332
}
333333

334334
fn apply_primary_statement_effect(
335-
&mut self,
335+
&self,
336336
state: &mut Self::Domain,
337337
statement: &mir::Statement<'tcx>,
338338
location: Location,
@@ -341,7 +341,7 @@ where
341341
}
342342

343343
fn apply_primary_terminator_effect<'mir>(
344-
&mut self,
344+
&self,
345345
state: &mut Self::Domain,
346346
terminator: &'mir mir::Terminator<'tcx>,
347347
location: Location,
@@ -351,7 +351,7 @@ where
351351
}
352352

353353
fn apply_call_return_effect(
354-
&mut self,
354+
&self,
355355
state: &mut Self::Domain,
356356
block: BasicBlock,
357357
return_places: CallReturnPlaces<'_, 'tcx>,

compiler/rustc_mir_dataflow/src/framework/cursor.rs

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,28 @@
11
//! Random access inspection of the results of a dataflow analysis.
22
3-
use std::borrow::Cow;
43
use std::cmp::Ordering;
5-
use std::ops::{Deref, DerefMut};
4+
use std::ops::Deref;
65

76
#[cfg(debug_assertions)]
87
use rustc_index::bit_set::DenseBitSet;
98
use rustc_middle::mir::{self, BasicBlock, Location};
109

1110
use super::{Analysis, Direction, Effect, EffectIndex, Results};
1211

13-
/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either
14-
/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow`
15-
/// doesn't allow mutable borrowing.
16-
enum CowMut<'a, T> {
17-
BorrowedMut(&'a mut T),
12+
/// This is like `Cow`, but it lacks the `T: ToOwned` bound and doesn't support
13+
/// `to_owned`/`into_owned`.
14+
enum SimpleCow<'a, T> {
15+
Borrowed(&'a T),
1816
Owned(T),
1917
}
2018

21-
impl<T> Deref for CowMut<'_, T> {
19+
impl<T> Deref for SimpleCow<'_, T> {
2220
type Target = T;
2321

2422
fn deref(&self) -> &T {
2523
match self {
26-
CowMut::BorrowedMut(borrowed) => borrowed,
27-
CowMut::Owned(owned) => owned,
28-
}
29-
}
30-
}
31-
32-
impl<T> DerefMut for CowMut<'_, T> {
33-
fn deref_mut(&mut self) -> &mut T {
34-
match self {
35-
CowMut::BorrowedMut(borrowed) => borrowed,
36-
CowMut::Owned(owned) => owned,
24+
SimpleCow::Borrowed(borrowed) => borrowed,
25+
SimpleCow::Owned(owned) => owned,
3726
}
3827
}
3928
}
@@ -53,8 +42,8 @@ where
5342
A: Analysis<'tcx>,
5443
{
5544
body: &'mir mir::Body<'tcx>,
56-
analysis: CowMut<'mir, A>,
57-
results: Cow<'mir, Results<A::Domain>>,
45+
analysis: SimpleCow<'mir, A>,
46+
results: SimpleCow<'mir, Results<A::Domain>>,
5847
state: A::Domain,
5948

6049
pos: CursorPosition,
@@ -84,8 +73,8 @@ where
8473

8574
fn new(
8675
body: &'mir mir::Body<'tcx>,
87-
analysis: CowMut<'mir, A>,
88-
results: Cow<'mir, Results<A::Domain>>,
76+
analysis: SimpleCow<'mir, A>,
77+
results: SimpleCow<'mir, Results<A::Domain>>,
8978
) -> Self {
9079
let bottom_value = analysis.bottom_value(body);
9180
ResultsCursor {
@@ -111,16 +100,16 @@ where
111100
analysis: A,
112101
results: Results<A::Domain>,
113102
) -> Self {
114-
Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
103+
Self::new(body, SimpleCow::Owned(analysis), SimpleCow::Owned(results))
115104
}
116105

117106
/// Returns a new cursor that borrows and inspects analysis results.
118107
pub fn new_borrowing(
119108
body: &'mir mir::Body<'tcx>,
120-
analysis: &'mir mut A,
109+
analysis: &'mir A,
121110
results: &'mir Results<A::Domain>,
122111
) -> Self {
123-
Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
112+
Self::new(body, SimpleCow::Borrowed(analysis), SimpleCow::Borrowed(results))
124113
}
125114

126115
/// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
@@ -236,7 +225,7 @@ where
236225
let target_effect_index = effect.at_index(target.statement_index);
237226

238227
A::Direction::apply_effects_in_range(
239-
&mut *self.analysis,
228+
&*self.analysis,
240229
&mut self.state,
241230
target.block,
242231
block_data,
@@ -251,8 +240,8 @@ where
251240
///
252241
/// This can be used, e.g., to apply the call return effect directly to the cursor without
253242
/// creating an extra copy of the dataflow state.
254-
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
255-
f(&mut self.analysis, &mut self.state);
243+
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
244+
f(&self.analysis, &mut self.state);
256245
self.state_needs_reset = true;
257246
}
258247
}

compiler/rustc_mir_dataflow/src/framework/direction.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub trait Direction {
1414

1515
/// Called by `iterate_to_fixpoint` during initial analysis computation.
1616
fn apply_effects_in_block<'mir, 'tcx, A>(
17-
analysis: &mut A,
17+
analysis: &A,
1818
body: &mir::Body<'tcx>,
1919
state: &mut A::Domain,
2020
block: BasicBlock,
@@ -28,7 +28,7 @@ pub trait Direction {
2828
///
2929
/// `effects.start()` must precede or equal `effects.end()` in this direction.
3030
fn apply_effects_in_range<'tcx, A>(
31-
analysis: &mut A,
31+
analysis: &A,
3232
state: &mut A::Domain,
3333
block: BasicBlock,
3434
block_data: &mir::BasicBlockData<'tcx>,
@@ -40,7 +40,7 @@ pub trait Direction {
4040
/// all locations in a basic block (starting from `entry_state` and to
4141
/// visit them with `vis`.
4242
fn visit_results_in_block<'mir, 'tcx, A>(
43-
analysis: &mut A,
43+
analysis: &A,
4444
state: &mut A::Domain,
4545
block: BasicBlock,
4646
block_data: &'mir mir::BasicBlockData<'tcx>,
@@ -56,7 +56,7 @@ impl Direction for Backward {
5656
const IS_FORWARD: bool = false;
5757

5858
fn apply_effects_in_block<'mir, 'tcx, A>(
59-
analysis: &mut A,
59+
analysis: &A,
6060
body: &mir::Body<'tcx>,
6161
state: &mut A::Domain,
6262
block: BasicBlock,
@@ -129,7 +129,7 @@ impl Direction for Backward {
129129
}
130130

131131
fn apply_effects_in_range<'tcx, A>(
132-
analysis: &mut A,
132+
analysis: &A,
133133
state: &mut A::Domain,
134134
block: BasicBlock,
135135
block_data: &mir::BasicBlockData<'tcx>,
@@ -206,7 +206,7 @@ impl Direction for Backward {
206206
}
207207

208208
fn visit_results_in_block<'mir, 'tcx, A>(
209-
analysis: &mut A,
209+
analysis: &A,
210210
state: &mut A::Domain,
211211
block: BasicBlock,
212212
block_data: &'mir mir::BasicBlockData<'tcx>,
@@ -242,7 +242,7 @@ impl Direction for Forward {
242242
const IS_FORWARD: bool = true;
243243

244244
fn apply_effects_in_block<'mir, 'tcx, A>(
245-
analysis: &mut A,
245+
analysis: &A,
246246
body: &mir::Body<'tcx>,
247247
state: &mut A::Domain,
248248
block: BasicBlock,
@@ -312,7 +312,7 @@ impl Direction for Forward {
312312
}
313313

314314
fn apply_effects_in_range<'tcx, A>(
315-
analysis: &mut A,
315+
analysis: &A,
316316
state: &mut A::Domain,
317317
block: BasicBlock,
318318
block_data: &mir::BasicBlockData<'tcx>,
@@ -386,7 +386,7 @@ impl Direction for Forward {
386386
}
387387

388388
fn visit_results_in_block<'mir, 'tcx, A>(
389-
analysis: &mut A,
389+
analysis: &A,
390390
state: &mut A::Domain,
391391
block: BasicBlock,
392392
block_data: &'mir mir::BasicBlockData<'tcx>,

compiler/rustc_mir_dataflow/src/framework/graphviz.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! A helpful diagram for debugging dataflow problems.
22
33
use std::borrow::Cow;
4-
use std::cell::RefCell;
54
use std::ffi::OsString;
65
use std::path::PathBuf;
76
use std::sync::OnceLock;
@@ -33,7 +32,7 @@ use crate::errors::{
3332
pub(super) fn write_graphviz_results<'tcx, A>(
3433
tcx: TyCtxt<'tcx>,
3534
body: &Body<'tcx>,
36-
analysis: &mut A,
35+
analysis: &A,
3736
results: &Results<A::Domain>,
3837
pass_name: Option<&'static str>,
3938
) -> std::io::Result<()>
@@ -206,11 +205,7 @@ where
206205
A: Analysis<'tcx>,
207206
{
208207
body: &'mir Body<'tcx>,
209-
// The `RefCell` is used because `<Formatter as Labeller>::node_label`
210-
// takes `&self`, but it needs to modify the analysis. This is also the
211-
// reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
212-
// the operations that involve the mutation, i.e. within the `borrow_mut`.
213-
analysis: RefCell<&'mir mut A>,
208+
analysis: &'mir A,
214209
results: &'mir Results<A::Domain>,
215210
style: OutputStyle,
216211
reachable: DenseBitSet<BasicBlock>,
@@ -222,12 +217,12 @@ where
222217
{
223218
fn new(
224219
body: &'mir Body<'tcx>,
225-
analysis: &'mir mut A,
220+
analysis: &'mir A,
226221
results: &'mir Results<A::Domain>,
227222
style: OutputStyle,
228223
) -> Self {
229224
let reachable = traversal::reachable_as_bitset(body);
230-
Formatter { body, analysis: analysis.into(), results, style, reachable }
225+
Formatter { body, analysis, results, style, reachable }
231226
}
232227
}
233228

@@ -265,12 +260,11 @@ where
265260
}
266261

267262
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
268-
let analysis = &mut **self.analysis.borrow_mut();
269-
270-
let diffs = StateDiffCollector::run(self.body, *block, analysis, self.results, self.style);
263+
let diffs =
264+
StateDiffCollector::run(self.body, *block, self.analysis, self.results, self.style);
271265

272266
let mut fmt = BlockFormatter {
273-
cursor: ResultsCursor::new_borrowing(self.body, analysis, self.results),
267+
cursor: ResultsCursor::new_borrowing(self.body, self.analysis, self.results),
274268
style: self.style,
275269
bg: Background::Light,
276270
};
@@ -698,7 +692,7 @@ impl<D> StateDiffCollector<D> {
698692
fn run<'tcx, A>(
699693
body: &Body<'tcx>,
700694
block: BasicBlock,
701-
analysis: &mut A,
695+
analysis: &A,
702696
results: &Results<A::Domain>,
703697
style: OutputStyle,
704698
) -> Self

0 commit comments

Comments
 (0)