Skip to content

Commit ba13775

Browse files
committed
Merge AnalysisDomain into Analysis.
With `GenKillAnalysis` gone, there is no need for them to be separate.
1 parent 4dc1b4d commit ba13775

File tree

11 files changed

+62
-105
lines changed

11 files changed

+62
-105
lines changed

compiler/rustc_borrowck/src/dataflow.rs

+14-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::mir::{
77
use rustc_middle::ty::{RegionVid, TyCtxt};
88
use rustc_mir_dataflow::fmt::DebugWithContext;
99
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
10-
use rustc_mir_dataflow::{Analysis, AnalysisDomain, Forward, GenKill, Results, ResultsVisitable};
10+
use rustc_mir_dataflow::{Analysis, Forward, GenKill, Results, ResultsVisitable};
1111
use tracing::debug;
1212

1313
use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict};
@@ -22,9 +22,9 @@ pub(crate) struct BorrowckResults<'a, 'tcx> {
2222
/// The transient state of the dataflow analyses used by the borrow checker.
2323
#[derive(Debug)]
2424
pub(crate) struct BorrowckDomain<'a, 'tcx> {
25-
pub(crate) borrows: <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
26-
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
27-
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
25+
pub(crate) borrows: <Borrows<'a, 'tcx> as Analysis<'tcx>>::Domain,
26+
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
27+
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
2828
}
2929

3030
impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
@@ -427,7 +427,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
427427
/// That means they went out of a nonlexical scope
428428
fn kill_loans_out_of_scope_at_location(
429429
&self,
430-
trans: &mut <Self as AnalysisDomain<'tcx>>::Domain,
430+
trans: &mut <Self as Analysis<'tcx>>::Domain,
431431
location: Location,
432432
) {
433433
// NOTE: The state associated with a given `location`
@@ -449,7 +449,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
449449
/// Kill any borrows that conflict with `place`.
450450
fn kill_borrows_on_place(
451451
&self,
452-
trans: &mut <Self as AnalysisDomain<'tcx>>::Domain,
452+
trans: &mut <Self as Analysis<'tcx>>::Domain,
453453
place: Place<'tcx>,
454454
) {
455455
debug!("kill_borrows_on_place: place={:?}", place);
@@ -490,7 +490,14 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
490490
}
491491
}
492492

493-
impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
493+
/// Forward dataflow computation of the set of borrows that are in scope at a particular location.
494+
/// - we gen the introduced loans
495+
/// - we kill loans on locals going out of (regular) scope
496+
/// - we kill the loans going out of their region's NLL scope: in NLL terms, the frontier where a
497+
/// region stops containing the CFG points reachable from the issuing location.
498+
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
499+
/// `a.b.c` when `a` is overwritten.
500+
impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
494501
type Domain = BitSet<BorrowIndex>;
495502

496503
const NAME: &'static str = "borrows";
@@ -504,16 +511,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
504511
// no borrows of code region_scopes have been taken prior to
505512
// function execution, so this method has no effect.
506513
}
507-
}
508514

509-
/// Forward dataflow computation of the set of borrows that are in scope at a particular location.
510-
/// - we gen the introduced loans
511-
/// - we kill loans on locals going out of (regular) scope
512-
/// - we kill the loans going out of their region's NLL scope: in NLL terms, the frontier where a
513-
/// region stops containing the CFG points reachable from the issuing location.
514-
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
515-
/// `a.b.c` when `a` is overwritten.
516-
impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
517515
fn apply_before_statement_effect(
518516
&mut self,
519517
trans: &mut Self::Domain,

compiler/rustc_const_eval/src/check_consts/resolver.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::mir::{
1111
self, BasicBlock, CallReturnPlaces, Local, Location, Statement, StatementKind, TerminatorEdges,
1212
};
1313
use rustc_mir_dataflow::fmt::DebugWithContext;
14-
use rustc_mir_dataflow::{Analysis, AnalysisDomain, JoinSemiLattice};
14+
use rustc_mir_dataflow::{Analysis, JoinSemiLattice};
1515

1616
use super::{ConstCx, Qualif, qualifs};
1717

@@ -310,7 +310,7 @@ impl JoinSemiLattice for State {
310310
}
311311
}
312312

313-
impl<'tcx, Q> AnalysisDomain<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
313+
impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
314314
where
315315
Q: Qualif,
316316
{
@@ -328,12 +328,7 @@ where
328328
fn initialize_start_block(&self, _body: &mir::Body<'tcx>, state: &mut Self::Domain) {
329329
self.transfer_function(state).initialize_state();
330330
}
331-
}
332331

333-
impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
334-
where
335-
Q: Qualif,
336-
{
337332
fn apply_statement_effect(
338333
&mut self,
339334
state: &mut Self::Domain,

compiler/rustc_mir_dataflow/src/framework/engine.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ use {rustc_ast as ast, rustc_graphviz as dot};
1616

1717
use super::fmt::DebugWithContext;
1818
use super::{
19-
Analysis, AnalysisDomain, Direction, JoinSemiLattice, ResultsCursor, ResultsVisitor, graphviz,
20-
visit_results,
19+
Analysis, Direction, JoinSemiLattice, ResultsCursor, ResultsVisitor, graphviz, visit_results,
2120
};
2221
use crate::errors::{
2322
DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
2423
};
2524

26-
type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as AnalysisDomain<'tcx>>::Domain>;
25+
type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
2726

2827
/// A dataflow analysis that has converged to fixpoint.
2928
#[derive(Clone)]

compiler/rustc_mir_dataflow/src/framework/mod.rs

+19-22
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,26 @@ impl<T: Idx> BitSetExt<T> for ChunkedBitSet<T> {
8989
}
9090
}
9191

92-
/// Defines the domain of a dataflow problem.
92+
/// A dataflow problem with an arbitrarily complex transfer function.
93+
///
94+
/// This trait specifies the lattice on which this analysis operates (the domain), its
95+
/// initial value at the entry point of each basic block, and various operations.
9396
///
94-
/// This trait specifies the lattice on which this analysis operates (the domain) as well as its
95-
/// initial value at the entry point of each basic block.
96-
pub trait AnalysisDomain<'tcx> {
97+
/// # Convergence
98+
///
99+
/// When implementing this trait it's possible to choose a transfer function such that the analysis
100+
/// does not reach fixpoint. To guarantee convergence, your transfer functions must maintain the
101+
/// following invariant:
102+
///
103+
/// > If the dataflow state **before** some point in the program changes to be greater
104+
/// than the prior state **before** that point, the dataflow state **after** that point must
105+
/// also change to be greater than the prior state **after** that point.
106+
///
107+
/// This invariant guarantees that the dataflow state at a given point in the program increases
108+
/// monotonically until fixpoint is reached. Note that this monotonicity requirement only applies
109+
/// to the same point in the program at different points in time. The dataflow state at a given
110+
/// point in the program may or may not be greater than the state at any preceding point.
111+
pub trait Analysis<'tcx> {
97112
/// The type that holds the dataflow state at any given point in the program.
98113
type Domain: Clone + JoinSemiLattice;
99114

@@ -118,25 +133,7 @@ pub trait AnalysisDomain<'tcx> {
118133
// block where control flow could exit the MIR body (e.g., those terminated with `return` or
119134
// `resume`). It's not obvious how to handle `yield` points in coroutines, however.
120135
fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain);
121-
}
122136

123-
/// A dataflow problem with an arbitrarily complex transfer function.
124-
///
125-
/// # Convergence
126-
///
127-
/// When implementing this trait it's possible to choose a transfer function such that the analysis
128-
/// does not reach fixpoint. To guarantee convergence, your transfer functions must maintain the
129-
/// following invariant:
130-
///
131-
/// > If the dataflow state **before** some point in the program changes to be greater
132-
/// than the prior state **before** that point, the dataflow state **after** that point must
133-
/// also change to be greater than the prior state **after** that point.
134-
///
135-
/// This invariant guarantees that the dataflow state at a given point in the program increases
136-
/// monotonically until fixpoint is reached. Note that this monotonicity requirement only applies
137-
/// to the same point in the program at different points in time. The dataflow state at a given
138-
/// point in the program may or may not be greater than the state at any preceding point.
139-
pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
140137
/// Updates the current dataflow state with the effect of evaluating a statement.
141138
fn apply_statement_effect(
142139
&mut self,

compiler/rustc_mir_dataflow/src/framework/tests.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
154154
}
155155
}
156156

157-
impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> {
157+
impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
158158
type Domain = BitSet<usize>;
159159
type Direction = D;
160160

@@ -167,9 +167,7 @@ impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> {
167167
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
168168
unimplemented!("This is never called since `MockAnalysis` is never iterated to fixpoint");
169169
}
170-
}
171170

172-
impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
173171
fn apply_statement_effect(
174172
&mut self,
175173
state: &mut Self::Domain,

compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_index::bit_set::BitSet;
22
use rustc_middle::mir::visit::Visitor;
33
use rustc_middle::mir::*;
44

5-
use crate::{Analysis, AnalysisDomain, GenKill};
5+
use crate::{Analysis, GenKill};
66

77
/// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
88
/// to a given local. This analysis ignores fake borrows, so it should not be used by
@@ -20,7 +20,7 @@ impl MaybeBorrowedLocals {
2020
}
2121
}
2222

23-
impl<'tcx> AnalysisDomain<'tcx> for MaybeBorrowedLocals {
23+
impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
2424
type Domain = BitSet<Local>;
2525
const NAME: &'static str = "maybe_borrowed_locals";
2626

@@ -32,9 +32,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeBorrowedLocals {
3232
fn initialize_start_block(&self, _: &Body<'tcx>, _: &mut Self::Domain) {
3333
// No locals are aliased on function entry
3434
}
35-
}
3635

37-
impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
3836
fn apply_statement_effect(
3937
&mut self,
4038
trans: &mut Self::Domain,

compiler/rustc_mir_dataflow/src/impls/initialized.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ use crate::elaborate_drops::DropFlagState;
1111
use crate::framework::SwitchIntEdgeEffects;
1212
use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex};
1313
use crate::{
14-
Analysis, AnalysisDomain, GenKill, MaybeReachable, drop_flag_effects,
15-
drop_flag_effects_for_function_entry, drop_flag_effects_for_location, lattice,
16-
on_all_children_bits, on_lookup_result_bits,
14+
Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry,
15+
drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits,
1716
};
1817

1918
/// `MaybeInitializedPlaces` tracks all places that might be
@@ -270,7 +269,7 @@ impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
270269

271270
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
272271
fn update_bits(
273-
trans: &mut <Self as AnalysisDomain<'tcx>>::Domain,
272+
trans: &mut <Self as Analysis<'tcx>>::Domain,
274273
path: MovePathIndex,
275274
state: DropFlagState,
276275
) {
@@ -283,7 +282,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
283282

284283
impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
285284
fn update_bits(
286-
trans: &mut <Self as AnalysisDomain<'tcx>>::Domain,
285+
trans: &mut <Self as Analysis<'tcx>>::Domain,
287286
path: MovePathIndex,
288287
state: DropFlagState,
289288
) {
@@ -296,7 +295,7 @@ impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
296295

297296
impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
298297
fn update_bits(
299-
trans: &mut <Self as AnalysisDomain<'tcx>>::Domain,
298+
trans: &mut <Self as Analysis<'tcx>>::Domain,
300299
path: MovePathIndex,
301300
state: DropFlagState,
302301
) {
@@ -307,7 +306,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
307306
}
308307
}
309308

310-
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
309+
impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
311310
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
312311
/// We use a chunked bitset to avoid paying too high a memory footprint.
313312
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
@@ -327,9 +326,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
327326
state.gen_(path);
328327
});
329328
}
330-
}
331329

332-
impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
333330
fn apply_statement_effect(
334331
&mut self,
335332
trans: &mut Self::Domain,
@@ -436,7 +433,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
436433
}
437434
}
438435

439-
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
436+
impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
440437
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
441438
/// We use a chunked bitset to avoid paying too high a memory footprint.
442439
type Domain = ChunkedBitSet<MovePathIndex>;
@@ -458,9 +455,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
458455
state.remove(path);
459456
});
460457
}
461-
}
462458

463-
impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
464459
fn apply_statement_effect(
465460
&mut self,
466461
trans: &mut Self::Domain,
@@ -559,7 +554,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
559554
}
560555
}
561556

562-
impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
557+
impl<'a, 'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
563558
/// Use set intersection as the join operator.
564559
type Domain = lattice::Dual<BitSet<MovePathIndex>>;
565560

@@ -579,9 +574,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
579574
state.0.insert(path);
580575
});
581576
}
582-
}
583577

584-
impl<'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
585578
fn apply_statement_effect(
586579
&mut self,
587580
trans: &mut Self::Domain,
@@ -625,7 +618,7 @@ impl<'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
625618
}
626619
}
627620

628-
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
621+
impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
629622
/// There can be many more `InitIndex` than there are locals in a MIR body.
630623
/// We use a chunked bitset to avoid paying too high a memory footprint.
631624
type Domain = ChunkedBitSet<InitIndex>;
@@ -642,9 +635,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
642635
state.insert(InitIndex::new(arg_init));
643636
}
644637
}
645-
}
646638

647-
impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
648639
#[instrument(skip(self, trans), level = "debug")]
649640
fn apply_statement_effect(
650641
&mut self,

compiler/rustc_mir_dataflow/src/impls/liveness.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_middle::mir::{
44
self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges,
55
};
66

7-
use crate::{Analysis, AnalysisDomain, Backward, GenKill};
7+
use crate::{Analysis, Backward, GenKill};
88

99
/// A [live-variable dataflow analysis][liveness].
1010
///
@@ -25,7 +25,7 @@ use crate::{Analysis, AnalysisDomain, Backward, GenKill};
2525
/// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis
2626
pub struct MaybeLiveLocals;
2727

28-
impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
28+
impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
2929
type Domain = BitSet<Local>;
3030
type Direction = Backward;
3131

@@ -39,9 +39,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
3939
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
4040
// No variables are live until we observe a use
4141
}
42-
}
4342

44-
impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
4543
fn apply_statement_effect(
4644
&mut self,
4745
trans: &mut Self::Domain,
@@ -219,7 +217,7 @@ impl<'a> MaybeTransitiveLiveLocals<'a> {
219217
}
220218
}
221219

222-
impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
220+
impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
223221
type Domain = BitSet<Local>;
224222
type Direction = Backward;
225223

@@ -233,9 +231,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
233231
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
234232
// No variables are live until we observe a use
235233
}
236-
}
237234

238-
impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
239235
fn apply_statement_effect(
240236
&mut self,
241237
trans: &mut Self::Domain,

0 commit comments

Comments
 (0)