Skip to content

Commit 5c81dbf

Browse files
authored
Rollup merge of #132134 - nnethercote:rm-ResultsVisitable, r=cjgillot
Remove `ResultsVisitable` `ResultsVisitable` has annoyed me for a while. This PR removes it. Details in the individual commits. r? `@cjgillot.`
2 parents 07b0336 + c904c6a commit 5c81dbf

11 files changed

Lines changed: 261 additions & 274 deletions

File tree

‎compiler/rustc_borrowck/src/dataflow.rs‎

Lines changed: 119 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,171 @@
1+
use std::fmt;
2+
13
use rustc_data_structures::fx::FxIndexMap;
24
use rustc_data_structures::graph;
35
use rustc_index::bit_set::BitSet;
4-
use rustc_middle::mir::{self,BasicBlock,Body,Location,Place,TerminatorEdges};
6+
use rustc_middle::mir::{
7+
self,BasicBlock,Body,CallReturnPlaces,Location,Place,TerminatorEdges,
8+
};
59
use rustc_middle::ty::{RegionVid,TyCtxt};
610
use rustc_mir_dataflow::fmt::DebugWithContext;
711
use rustc_mir_dataflow::impls::{EverInitializedPlaces,MaybeUninitializedPlaces};
8-
use rustc_mir_dataflow::{Analysis,Forward,GenKill,Results,ResultsVisitable};
12+
use rustc_mir_dataflow::{Analysis,GenKill,JoinSemiLattice,SwitchIntEdgeEffects};
913
use tracing::debug;
1014

1115
usecrate::{BorrowSet,PlaceConflictBias,PlaceExt,RegionInferenceContext, places_conflict};
1216

13-
/// The results of the dataflow analyses used by the borrow checker.
14-
pub(crate)structBorrowckResults<'a,'tcx>{
15-
pub(crate)borrows:Results<'tcx,Borrows<'a,'tcx>>,
16-
pub(crate)uninits:Results<'tcx,MaybeUninitializedPlaces<'a,'tcx>>,
17-
pub(crate)ever_inits:Results<'tcx,EverInitializedPlaces<'a,'tcx>>,
18-
}
19-
20-
/// The transient state of the dataflow analyses used by the borrow checker.
21-
#[derive(Debug)]
22-
pub(crate)structBorrowckDomain<'a,'tcx>{
23-
pub(crate)borrows: <Borrows<'a,'tcx>asAnalysis<'tcx>>::Domain,
24-
pub(crate)uninits: <MaybeUninitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain,
25-
pub(crate)ever_inits: <EverInitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain,
17+
// This analysis is different to most others. Its results aren't computed with
18+
// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are
19+
// computed individually with `iterate_to_fixpoint`.
20+
pub(crate)structBorrowck<'a,'tcx>{
21+
pub(crate)borrows:Borrows<'a,'tcx>,
22+
pub(crate)uninits:MaybeUninitializedPlaces<'a,'tcx>,
23+
pub(crate)ever_inits:EverInitializedPlaces<'a,'tcx>,
2624
}
2725

28-
impl<'a,'tcx>ResultsVisitable<'tcx>forBorrowckResults<'a,'tcx>{
29-
typeDirection = Forward;
26+
impl<'a,'tcx>Analysis<'tcx>forBorrowck<'a,'tcx>{
3027
typeDomain = BorrowckDomain<'a,'tcx>;
3128

29+
constNAME:&'staticstr = "borrowck";
30+
3231
fnbottom_value(&self,body:&mir::Body<'tcx>) -> Self::Domain{
3332
BorrowckDomain{
34-
borrows:self.borrows.analysis.bottom_value(body),
35-
uninits:self.uninits.analysis.bottom_value(body),
36-
ever_inits:self.ever_inits.analysis.bottom_value(body),
33+
borrows:self.borrows.bottom_value(body),
34+
uninits:self.uninits.bottom_value(body),
35+
ever_inits:self.ever_inits.bottom_value(body),
3736
}
3837
}
3938

40-
fnreset_to_block_entry(&self,state:&mutSelf::Domain,block:BasicBlock){
41-
state.borrows.clone_from(self.borrows.entry_set_for_block(block));
42-
state.uninits.clone_from(self.uninits.entry_set_for_block(block));
43-
state.ever_inits.clone_from(self.ever_inits.entry_set_for_block(block));
39+
fninitialize_start_block(&self,_body:&mir::Body<'tcx>,_state:&mutSelf::Domain){
40+
// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
41+
unreachable!();
4442
}
4543

46-
fnreconstruct_before_statement_effect(
44+
fnapply_before_statement_effect(
4745
&mutself,
4846
state:&mutSelf::Domain,
4947
stmt:&mir::Statement<'tcx>,
5048
loc:Location,
5149
){
52-
self.borrows.analysis.apply_before_statement_effect(&mut state.borrows, stmt, loc);
53-
self.uninits.analysis.apply_before_statement_effect(&mut state.uninits, stmt, loc);
54-
self.ever_inits.analysis.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
50+
self.borrows.apply_before_statement_effect(&mut state.borrows, stmt, loc);
51+
self.uninits.apply_before_statement_effect(&mut state.uninits, stmt, loc);
52+
self.ever_inits.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
5553
}
5654

57-
fnreconstruct_statement_effect(
55+
fnapply_statement_effect(
5856
&mutself,
5957
state:&mutSelf::Domain,
6058
stmt:&mir::Statement<'tcx>,
6159
loc:Location,
6260
){
63-
self.borrows.analysis.apply_statement_effect(&mut state.borrows, stmt, loc);
64-
self.uninits.analysis.apply_statement_effect(&mut state.uninits, stmt, loc);
65-
self.ever_inits.analysis.apply_statement_effect(&mut state.ever_inits, stmt, loc);
61+
self.borrows.apply_statement_effect(&mut state.borrows, stmt, loc);
62+
self.uninits.apply_statement_effect(&mut state.uninits, stmt, loc);
63+
self.ever_inits.apply_statement_effect(&mut state.ever_inits, stmt, loc);
6664
}
6765

68-
fnreconstruct_before_terminator_effect(
66+
fnapply_before_terminator_effect(
6967
&mutself,
7068
state:&mutSelf::Domain,
7169
term:&mir::Terminator<'tcx>,
7270
loc:Location,
7371
){
74-
self.borrows.analysis.apply_before_terminator_effect(&mut state.borrows, term, loc);
75-
self.uninits.analysis.apply_before_terminator_effect(&mut state.uninits, term, loc);
76-
self.ever_inits.analysis.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
72+
self.borrows.apply_before_terminator_effect(&mut state.borrows, term, loc);
73+
self.uninits.apply_before_terminator_effect(&mut state.uninits, term, loc);
74+
self.ever_inits.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
7775
}
7876

79-
fnreconstruct_terminator_effect(
77+
fnapply_terminator_effect<'mir>(
8078
&mutself,
8179
state:&mutSelf::Domain,
82-
term:&mir::Terminator<'tcx>,
80+
term:&'mirmir::Terminator<'tcx>,
8381
loc:Location,
82+
) -> TerminatorEdges<'mir,'tcx>{
83+
self.borrows.apply_terminator_effect(&mut state.borrows, term, loc);
84+
self.uninits.apply_terminator_effect(&mut state.uninits, term, loc);
85+
self.ever_inits.apply_terminator_effect(&mut state.ever_inits, term, loc);
86+
87+
// This return value doesn't matter. It's only used by `iterate_to_fixpoint`, which this
88+
// analysis doesn't use.
89+
TerminatorEdges::None
90+
}
91+
92+
fnapply_call_return_effect(
93+
&mutself,
94+
_state:&mutSelf::Domain,
95+
_block:BasicBlock,
96+
_return_places:CallReturnPlaces<'_,'tcx>,
97+
){
98+
// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
99+
unreachable!();
100+
}
101+
102+
fnapply_switch_int_edge_effects(
103+
&mutself,
104+
_block:BasicBlock,
105+
_discr:&mir::Operand<'tcx>,
106+
_apply_edge_effects:&mutimplSwitchIntEdgeEffects<Self::Domain>,
84107
){
85-
self.borrows.analysis.apply_terminator_effect(&mut state.borrows, term, loc);
86-
self.uninits.analysis.apply_terminator_effect(&mut state.uninits, term, loc);
87-
self.ever_inits.analysis.apply_terminator_effect(&mut state.ever_inits, term, loc);
108+
// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
109+
unreachable!();
88110
}
89111
}
90112

113+
implJoinSemiLatticeforBorrowckDomain<'_,'_>{
114+
fnjoin(&mutself,_other:&Self) -> bool{
115+
// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
116+
unreachable!();
117+
}
118+
}
119+
120+
impl<'tcx,C>DebugWithContext<C>forBorrowckDomain<'_,'tcx>
121+
where
122+
C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>,
123+
{
124+
fnfmt_with(&self,ctxt:&C,f:&mut fmt::Formatter<'_>) -> fmt::Result{
125+
f.write_str("borrows: ")?;
126+
self.borrows.fmt_with(ctxt, f)?;
127+
f.write_str(" uninits: ")?;
128+
self.uninits.fmt_with(ctxt, f)?;
129+
f.write_str(" ever_inits: ")?;
130+
self.ever_inits.fmt_with(ctxt, f)?;
131+
Ok(())
132+
}
133+
134+
fnfmt_diff_with(&self,old:&Self,ctxt:&C,f:&mut fmt::Formatter<'_>) -> fmt::Result{
135+
ifself == old {
136+
returnOk(());
137+
}
138+
139+
ifself.borrows != old.borrows{
140+
f.write_str("borrows: ")?;
141+
self.borrows.fmt_diff_with(&old.borrows, ctxt, f)?;
142+
f.write_str("\n")?;
143+
}
144+
145+
ifself.uninits != old.uninits{
146+
f.write_str("uninits: ")?;
147+
self.uninits.fmt_diff_with(&old.uninits, ctxt, f)?;
148+
f.write_str("\n")?;
149+
}
150+
151+
ifself.ever_inits != old.ever_inits{
152+
f.write_str("ever_inits: ")?;
153+
self.ever_inits.fmt_diff_with(&old.ever_inits, ctxt, f)?;
154+
f.write_str("\n")?;
155+
}
156+
157+
Ok(())
158+
}
159+
}
160+
161+
/// The transient state of the dataflow analyses used by the borrow checker.
162+
#[derive(Clone,Debug,PartialEq,Eq)]
163+
pub(crate)structBorrowckDomain<'a,'tcx>{
164+
pub(crate)borrows: <Borrows<'a,'tcx>asAnalysis<'tcx>>::Domain,
165+
pub(crate)uninits: <MaybeUninitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain,
166+
pub(crate)ever_inits: <EverInitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain,
167+
}
168+
91169
rustc_index::newtype_index! {
92170
#[orderable]
93171
#[debug_format = "bw{}"]

‎compiler/rustc_borrowck/src/lib.rs‎

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ use rustc_middle::mir::*;
3636
use rustc_middle::query::Providers;
3737
use rustc_middle::ty::{self,ParamEnv,RegionVid,TyCtxt,TypingMode};
3838
use rustc_middle::{bug, span_bug};
39-
use rustc_mir_dataflow::Analysis;
4039
use rustc_mir_dataflow::impls::{
4140
EverInitializedPlaces,MaybeInitializedPlaces,MaybeUninitializedPlaces,
4241
};
4342
use rustc_mir_dataflow::move_paths::{
4443
InitIndex,InitLocation,LookupResult,MoveData,MoveOutIndex,MovePathIndex,
4544
};
45+
use rustc_mir_dataflow::{Analysis,EntrySets,Results,ResultsVisitor, visit_results};
4646
use rustc_session::lint::builtin::UNUSED_MUT;
4747
use rustc_span::{Span,Symbol};
4848
use smallvec::SmallVec;
4949
use tracing::{debug, instrument};
5050

5151
usecrate::borrow_set::{BorrowData,BorrowSet};
5252
usecrate::consumers::{BodyWithBorrowckFacts,ConsumerOptions};
53-
usecrate::dataflow::{BorrowIndex,BorrowckDomain,BorrowckResults,Borrows};
53+
usecrate::dataflow::{BorrowIndex,Borrowck,BorrowckDomain,Borrows};
5454
usecrate::diagnostics::{AccessKind,IllegalMoveOriginKind,MoveError,RegionName};
5555
usecrate::location::LocationTable;
5656
usecrate::nll::PoloniusOutput;
@@ -221,6 +221,10 @@ fn do_mir_borrowck<'tcx>(
221221
consumer_options,
222222
);
223223

224+
// `flow_inits` is large, so we drop it as soon as possible. This reduces
225+
// peak memory usage significantly on some benchmarks.
226+
drop(flow_inits);
227+
224228
// Dump MIR results into a file, if that is enabled. This let us
225229
// write unit-tests, as well as helping with debugging.
226230
nll::dump_nll_mir(&infcx, body,&regioncx,&opt_closure_req,&borrow_set);
@@ -229,27 +233,6 @@ fn do_mir_borrowck<'tcx>(
229233
// information.
230234
nll::dump_annotation(&infcx, body,&regioncx,&opt_closure_req,&opaque_type_values, diags);
231235

232-
// The various `flow_*` structures can be large. We drop `flow_inits` here
233-
// so it doesn't overlap with the others below. This reduces peak memory
234-
// usage significantly on some benchmarks.
235-
drop(flow_inits);
236-
237-
let flow_borrows = Borrows::new(tcx, body,&regioncx,&borrow_set).iterate_to_fixpoint(
238-
tcx,
239-
body,
240-
Some("borrowck"),
241-
);
242-
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body,&move_data).iterate_to_fixpoint(
243-
tcx,
244-
body,
245-
Some("borrowck"),
246-
);
247-
let flow_ever_inits = EverInitializedPlaces::new(body,&move_data).iterate_to_fixpoint(
248-
tcx,
249-
body,
250-
Some("borrowck"),
251-
);
252-
253236
let movable_coroutine =
254237
// The first argument is the coroutine type passed by value
255238
ifletSome(local) = body.local_decls.raw.get(1)
@@ -334,16 +317,11 @@ fn do_mir_borrowck<'tcx>(
334317
// Compute and report region errors, if any.
335318
mbcx.report_region_errors(nll_errors);
336319

337-
letmut results = BorrowckResults{
338-
ever_inits: flow_ever_inits,
339-
uninits: flow_uninits,
340-
borrows: flow_borrows,
341-
};
342-
343-
rustc_mir_dataflow::visit_results(
320+
letmut flow_results = get_flow_results(tcx, body,&move_data,&borrow_set,&regioncx);
321+
visit_results(
344322
body,
345323
traversal::reverse_postorder(body).map(|(bb, _)| bb),
346-
&mutresults,
324+
&mutflow_results,
347325
&mut mbcx,
348326
);
349327

@@ -426,6 +404,47 @@ fn do_mir_borrowck<'tcx>(
426404
(result, body_with_facts)
427405
}
428406

407+
fnget_flow_results<'a,'tcx>(
408+
tcx:TyCtxt<'tcx>,
409+
body:&'aBody<'tcx>,
410+
move_data:&'aMoveData<'tcx>,
411+
borrow_set:&'aBorrowSet<'tcx>,
412+
regioncx:&RegionInferenceContext<'tcx>,
413+
) -> Results<'tcx,Borrowck<'a,'tcx>>{
414+
// We compute these three analyses individually, but them combine them into
415+
// a single results so that `mbcx` can visit them all together.
416+
let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
417+
tcx,
418+
body,
419+
Some("borrowck"),
420+
);
421+
let uninits = MaybeUninitializedPlaces::new(tcx, body, move_data).iterate_to_fixpoint(
422+
tcx,
423+
body,
424+
Some("borrowck"),
425+
);
426+
let ever_inits = EverInitializedPlaces::new(body, move_data).iterate_to_fixpoint(
427+
tcx,
428+
body,
429+
Some("borrowck"),
430+
);
431+
432+
let analysis = Borrowck{
433+
borrows: borrows.analysis,
434+
uninits: uninits.analysis,
435+
ever_inits: ever_inits.analysis,
436+
};
437+
438+
assert_eq!(borrows.entry_sets.len(), uninits.entry_sets.len());
439+
assert_eq!(borrows.entry_sets.len(), ever_inits.entry_sets.len());
440+
let entry_sets:EntrySets<'_,Borrowck<'_,'_>> =
441+
itertools::izip!(borrows.entry_sets, uninits.entry_sets, ever_inits.entry_sets)
442+
.map(|(borrows, uninits, ever_inits)| BorrowckDomain{ borrows, uninits, ever_inits })
443+
.collect();
444+
445+
Results{ analysis, entry_sets }
446+
}
447+
429448
pub(crate)structBorrowckInferCtxt<'tcx>{
430449
pub(crate)infcx:InferCtxt<'tcx>,
431450
pub(crate)reg_var_to_origin:RefCell<FxIndexMap<ty::RegionVid,RegionCtxt>>,
@@ -588,14 +607,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
588607
// 2. loans made in overlapping scopes do not conflict
589608
// 3. assignments do not affect things loaned out as immutable
590609
// 4. moves do not affect things loaned out in any way
591-
impl<'a,'tcx,R> rustc_mir_dataflow::ResultsVisitor<'a,'tcx,R>
592-
forMirBorrowckCtxt<'a,'_,'tcx>
593-
{
594-
typeDomain = BorrowckDomain<'a,'tcx>;
595-
610+
impl<'a,'tcx>ResultsVisitor<'a,'tcx,Borrowck<'a,'tcx>>forMirBorrowckCtxt<'a,'_,'tcx>{
596611
fnvisit_statement_before_primary_effect(
597612
&mutself,
598-
_results:&mutR,
613+
_results:&mutResults<'tcx,Borrowck<'a,'tcx>>,
599614
state:&BorrowckDomain<'a,'tcx>,
600615
stmt:&'aStatement<'tcx>,
601616
location:Location,
@@ -667,7 +682,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
667682

668683
fnvisit_terminator_before_primary_effect(
669684
&mutself,
670-
_results:&mutR,
685+
_results:&mutResults<'tcx,Borrowck<'a,'tcx>>,
671686
state:&BorrowckDomain<'a,'tcx>,
672687
term:&'aTerminator<'tcx>,
673688
loc:Location,
@@ -780,7 +795,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
780795

781796
fnvisit_terminator_after_primary_effect(
782797
&mutself,
783-
_results:&mutR,
798+
_results:&mutResults<'tcx,Borrowck<'a,'tcx>>,
784799
state:&BorrowckDomain<'a,'tcx>,
785800
term:&'aTerminator<'tcx>,
786801
loc:Location,

0 commit comments

Comments
 (0)