Skip to content

Commit 9c4732a

Browse files
Rollup merge of #131225 - nnethercote:rustc_borrowck-mm, r=lqd
`rustc_borrowck` memory management tweaks Minor cleanups in `rustc_borrowck` relating to memory management. r? `@lqd`
2 parents 31fbf67 + c69d174 commit 9c4732a

File tree

11 files changed

+58
-70
lines changed

11 files changed

+58
-70
lines changed

compiler/rustc_borrowck/src/consumers.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! This file provides API for compiler consumers.
22
3-
use std::rc::Rc;
4-
53
use rustc_hir::def_id::LocalDefId;
64
use rustc_index::{IndexSlice, IndexVec};
75
use rustc_middle::mir::{Body, Promoted};
@@ -65,10 +63,10 @@ pub struct BodyWithBorrowckFacts<'tcx> {
6563
/// The mir bodies of promoteds.
6664
pub promoted: IndexVec<Promoted, Body<'tcx>>,
6765
/// The set of borrows occurring in `body` with data about them.
68-
pub borrow_set: Rc<BorrowSet<'tcx>>,
66+
pub borrow_set: BorrowSet<'tcx>,
6967
/// Context generated during borrowck, intended to be passed to
7068
/// [`calculate_borrows_out_of_scope_at_location`].
71-
pub region_inference_context: Rc<RegionInferenceContext<'tcx>>,
69+
pub region_inference_context: RegionInferenceContext<'tcx>,
7270
/// The table that maps Polonius points to locations in the table.
7371
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
7472
/// or [`ConsumerOptions::PoloniusOutputFacts`].
@@ -79,7 +77,7 @@ pub struct BodyWithBorrowckFacts<'tcx> {
7977
pub input_facts: Option<Box<PoloniusInput>>,
8078
/// Polonius output facts. Populated when using
8179
/// [`ConsumerOptions::PoloniusOutputFacts`].
82-
pub output_facts: Option<Rc<PoloniusOutput>>,
80+
pub output_facts: Option<Box<PoloniusOutput>>,
8381
}
8482

8583
/// This function computes borrowck facts for the given body. The [`ConsumerOptions`]

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -708,9 +708,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
708708
// for the branching codepaths that aren't covered, to point at them.
709709
let map = self.infcx.tcx.hir();
710710
let body = map.body_owned_by(self.mir_def_id());
711-
let mut visitor =
712-
ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] };
711+
let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] };
713712
visitor.visit_body(&body);
713+
let spans = visitor.spans;
714714

715715
let mut show_assign_sugg = false;
716716
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
@@ -4465,20 +4465,20 @@ impl<'hir> Visitor<'hir> for BreakFinder {
44654465

44664466
/// Given a set of spans representing statements initializing the relevant binding, visit all the
44674467
/// function expressions looking for branching code paths that *do not* initialize the binding.
4468-
struct ConditionVisitor<'b, 'tcx> {
4468+
struct ConditionVisitor<'tcx> {
44694469
tcx: TyCtxt<'tcx>,
4470-
spans: &'b [Span],
4471-
name: &'b str,
4470+
spans: Vec<Span>,
4471+
name: String,
44724472
errors: Vec<(Span, String)>,
44734473
}
44744474

4475-
impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
4475+
impl<'v, 'tcx> Visitor<'v> for ConditionVisitor<'tcx> {
44764476
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
44774477
match ex.kind {
44784478
hir::ExprKind::If(cond, body, None) => {
44794479
// `if` expressions with no `else` that initialize the binding might be missing an
44804480
// `else` arm.
4481-
if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() {
4481+
if ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break() {
44824482
self.errors.push((
44834483
cond.span,
44844484
format!(
@@ -4495,8 +4495,8 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
44954495
hir::ExprKind::If(cond, body, Some(other)) => {
44964496
// `if` expressions where the binding is only initialized in one of the two arms
44974497
// might be missing a binding initialization.
4498-
let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break();
4499-
let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break();
4498+
let a = ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break();
4499+
let b = ReferencedStatementsVisitor(&self.spans).visit_expr(other).is_break();
45004500
match (a, b) {
45014501
(true, true) | (false, false) => {}
45024502
(true, false) => {
@@ -4536,7 +4536,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
45364536
// arms might be missing an initialization.
45374537
let results: Vec<bool> = arms
45384538
.iter()
4539-
.map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break())
4539+
.map(|arm| ReferencedStatementsVisitor(&self.spans).visit_arm(arm).is_break())
45404540
.collect();
45414541
if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
45424542
for (arm, seen) in arms.iter().zip(results) {

compiler/rustc_borrowck/src/diagnostics/find_use.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::collections::VecDeque;
2-
use std::rc::Rc;
32

43
use rustc_data_structures::fx::FxIndexSet;
54
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
@@ -11,7 +10,7 @@ use crate::region_infer::{Cause, RegionInferenceContext};
1110

1211
pub(crate) fn find<'tcx>(
1312
body: &Body<'tcx>,
14-
regioncx: &Rc<RegionInferenceContext<'tcx>>,
13+
regioncx: &RegionInferenceContext<'tcx>,
1514
tcx: TyCtxt<'tcx>,
1615
region_vid: RegionVid,
1716
start_point: Location,
@@ -23,7 +22,7 @@ pub(crate) fn find<'tcx>(
2322

2423
struct UseFinder<'a, 'tcx> {
2524
body: &'a Body<'tcx>,
26-
regioncx: &'a Rc<RegionInferenceContext<'tcx>>,
25+
regioncx: &'a RegionInferenceContext<'tcx>,
2726
tcx: TyCtxt<'tcx>,
2827
region_vid: RegionVid,
2928
start_point: Location,

compiler/rustc_borrowck/src/lib.rs

+14-22
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use std::cell::RefCell;
1919
use std::collections::BTreeMap;
2020
use std::marker::PhantomData;
2121
use std::ops::Deref;
22-
use std::rc::Rc;
2322

2423
use consumers::{BodyWithBorrowckFacts, ConsumerOptions};
2524
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -200,8 +199,7 @@ fn do_mir_borrowck<'tcx>(
200199
.into_results_cursor(body);
201200

202201
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
203-
let borrow_set =
204-
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data));
202+
let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);
205203

206204
// Compute non-lexical lifetimes.
207205
let nll::NllOutput {
@@ -245,8 +243,6 @@ fn do_mir_borrowck<'tcx>(
245243
// usage significantly on some benchmarks.
246244
drop(flow_inits);
247245

248-
let regioncx = Rc::new(regioncx);
249-
250246
let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set)
251247
.into_engine(tcx, body)
252248
.pass_name("borrowck")
@@ -288,10 +284,10 @@ fn do_mir_borrowck<'tcx>(
288284
access_place_error_reported: Default::default(),
289285
reservation_error_reported: Default::default(),
290286
uninitialized_error_reported: Default::default(),
291-
regioncx: regioncx.clone(),
287+
regioncx: &regioncx,
292288
used_mut: Default::default(),
293289
used_mut_upvars: SmallVec::new(),
294-
borrow_set: Rc::clone(&borrow_set),
290+
borrow_set: &borrow_set,
295291
upvars: &[],
296292
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
297293
region_names: RefCell::default(),
@@ -329,10 +325,10 @@ fn do_mir_borrowck<'tcx>(
329325
access_place_error_reported: Default::default(),
330326
reservation_error_reported: Default::default(),
331327
uninitialized_error_reported: Default::default(),
332-
regioncx: Rc::clone(&regioncx),
328+
regioncx: &regioncx,
333329
used_mut: Default::default(),
334330
used_mut_upvars: SmallVec::new(),
335-
borrow_set: Rc::clone(&borrow_set),
331+
borrow_set: &borrow_set,
336332
upvars: tcx.closure_captures(def),
337333
local_names,
338334
region_names: RefCell::default(),
@@ -569,10 +565,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
569565
used_mut_upvars: SmallVec<[FieldIdx; 8]>,
570566
/// Region inference context. This contains the results from region inference and lets us e.g.
571567
/// find out which CFG points are contained in each borrow region.
572-
regioncx: Rc<RegionInferenceContext<'tcx>>,
568+
regioncx: &'a RegionInferenceContext<'tcx>,
573569

574570
/// The set of borrows extracted from the MIR
575-
borrow_set: Rc<BorrowSet<'tcx>>,
571+
borrow_set: &'a BorrowSet<'tcx>,
576572

577573
/// Information about upvars not necessarily preserved in types or MIR
578574
upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
@@ -588,7 +584,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
588584
next_region_name: RefCell<usize>,
589585

590586
/// Results of Polonius analysis.
591-
polonius_output: Option<Rc<PoloniusOutput>>,
587+
polonius_output: Option<Box<PoloniusOutput>>,
592588

593589
diags: diags::BorrowckDiags<'infcx, 'tcx>,
594590
move_errors: Vec<MoveError<'tcx>>,
@@ -800,9 +796,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
800796
TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
801797
if self.movable_coroutine {
802798
// Look for any active borrows to locals
803-
let borrow_set = self.borrow_set.clone();
804799
for i in state.borrows.iter() {
805-
let borrow = &borrow_set[i];
800+
let borrow = &self.borrow_set[i];
806801
self.check_for_local_borrow(borrow, span);
807802
}
808803
}
@@ -816,9 +811,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
816811
// Often, the storage will already have been killed by an explicit
817812
// StorageDead, but we don't always emit those (notably on unwind paths),
818813
// so this "extra check" serves as a kind of backup.
819-
let borrow_set = self.borrow_set.clone();
820814
for i in state.borrows.iter() {
821-
let borrow = &borrow_set[i];
815+
let borrow = &self.borrow_set[i];
822816
self.check_for_invalidation_at_exit(loc, borrow, span);
823817
}
824818
}
@@ -1037,13 +1031,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
10371031
state: &BorrowckDomain<'a, 'tcx>,
10381032
) -> bool {
10391033
let mut error_reported = false;
1040-
let borrow_set = Rc::clone(&self.borrow_set);
10411034

10421035
// Use polonius output if it has been enabled.
10431036
let mut polonius_output;
10441037
let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
10451038
let location = self.location_table.start_index(location);
1046-
polonius_output = BitSet::new_empty(borrow_set.len());
1039+
polonius_output = BitSet::new_empty(self.borrow_set.len());
10471040
for &idx in polonius.errors_at(location) {
10481041
polonius_output.insert(idx);
10491042
}
@@ -1057,7 +1050,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
10571050
self.infcx.tcx,
10581051
self.body,
10591052
(sd, place_span.0),
1060-
&borrow_set,
1053+
self.borrow_set,
10611054
|borrow_index| borrows_in_scope.contains(borrow_index),
10621055
|this, borrow_index, borrow| match (rw, borrow.kind) {
10631056
// Obviously an activation is compatible with its own
@@ -1580,9 +1573,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
15801573
// Two-phase borrow support: For each activation that is newly
15811574
// generated at this statement, check if it interferes with
15821575
// another borrow.
1583-
let borrow_set = self.borrow_set.clone();
1584-
for &borrow_index in borrow_set.activations_at_location(location) {
1585-
let borrow = &borrow_set[borrow_index];
1576+
for &borrow_index in self.borrow_set.activations_at_location(location) {
1577+
let borrow = &self.borrow_set[borrow_index];
15861578

15871579
// only mutable borrows should be 2-phase
15881580
assert!(match borrow.kind {

compiler/rustc_borrowck/src/nll.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub(crate) struct NllOutput<'tcx> {
4242
pub regioncx: RegionInferenceContext<'tcx>,
4343
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
4444
pub polonius_input: Option<Box<AllFacts>>,
45-
pub polonius_output: Option<Rc<PoloniusOutput>>,
45+
pub polonius_output: Option<Box<PoloniusOutput>>,
4646
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
4747
pub nll_errors: RegionErrors<'tcx>,
4848
}
@@ -98,7 +98,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
9898

9999
let universal_regions = Rc::new(universal_regions);
100100

101-
let elements = &Rc::new(DenseLocationMap::new(body));
101+
let elements = Rc::new(DenseLocationMap::new(body));
102102

103103
// Run the MIR type-checker.
104104
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
@@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
107107
param_env,
108108
body,
109109
promoted,
110-
&universal_regions,
110+
universal_regions.clone(),
111111
location_table,
112112
borrow_set,
113113
&mut all_facts,
114114
flow_inits,
115115
move_data,
116-
elements,
116+
elements.clone(),
117117
upvars,
118118
);
119119

@@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
165165
universe_causes,
166166
type_tests,
167167
liveness_constraints,
168-
elements,
168+
elements.clone(),
169169
);
170170

171171
// If requested: dump NLL facts, and run legacy polonius analysis.
@@ -184,7 +184,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
184184
let algorithm = Algorithm::from_str(&algorithm).unwrap();
185185
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
186186
let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis");
187-
Some(Rc::new(Output::compute(all_facts, algorithm, false)))
187+
Some(Box::new(Output::compute(all_facts, algorithm, false)))
188188
} else {
189189
None
190190
}

compiler/rustc_borrowck/src/region_infer/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
407407
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
408408
type_tests: Vec<TypeTest<'tcx>>,
409409
liveness_constraints: LivenessValues,
410-
elements: &Rc<DenseLocationMap>,
410+
elements: Rc<DenseLocationMap>,
411411
) -> Self {
412412
debug!("universal_regions: {:#?}", universal_regions);
413413
debug!("outlives constraints: {:#?}", outlives_constraints);
@@ -430,7 +430,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
430430
}
431431

432432
let mut scc_values =
433-
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
433+
RegionValues::new(elements, universal_regions.len(), placeholder_indices);
434434

435435
for region in liveness_constraints.regions() {
436436
let scc = constraint_sccs.scc(region);
@@ -637,7 +637,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
637637
&mut self,
638638
infcx: &InferCtxt<'tcx>,
639639
body: &Body<'tcx>,
640-
polonius_output: Option<Rc<PoloniusOutput>>,
640+
polonius_output: Option<Box<PoloniusOutput>>,
641641
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
642642
let mir_def_id = body.source.def_id();
643643
self.propagate_constraints();
@@ -663,7 +663,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
663663
self.check_polonius_subset_errors(
664664
outlives_requirements.as_mut(),
665665
&mut errors_buffer,
666-
polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
666+
polonius_output
667+
.as_ref()
668+
.expect("Polonius output is unavailable despite `-Z polonius`"),
667669
);
668670
} else {
669671
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
@@ -1411,7 +1413,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14111413
&self,
14121414
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
14131415
errors_buffer: &mut RegionErrors<'tcx>,
1414-
polonius_output: Rc<PoloniusOutput>,
1416+
polonius_output: &PoloniusOutput,
14151417
) {
14161418
debug!(
14171419
"check_polonius_subset_errors: {} subset_errors",

compiler/rustc_borrowck/src/region_infer/values.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,16 @@ impl<N: Idx> RegionValues<N> {
275275
/// Each of the regions in num_region_variables will be initialized with an
276276
/// empty set of points and no causal information.
277277
pub(crate) fn new(
278-
elements: &Rc<DenseLocationMap>,
278+
elements: Rc<DenseLocationMap>,
279279
num_universal_regions: usize,
280-
placeholder_indices: &Rc<PlaceholderIndices>,
280+
placeholder_indices: Rc<PlaceholderIndices>,
281281
) -> Self {
282+
let num_points = elements.num_points();
282283
let num_placeholders = placeholder_indices.len();
283284
Self {
284-
elements: elements.clone(),
285-
points: SparseIntervalMatrix::new(elements.num_points()),
286-
placeholder_indices: placeholder_indices.clone(),
285+
elements,
286+
points: SparseIntervalMatrix::new(num_points),
287+
placeholder_indices,
287288
free_regions: SparseBitMatrix::new(num_universal_regions),
288289
placeholders: SparseBitMatrix::new(num_placeholders),
289290
}

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ pub(crate) fn create<'tcx>(
5454
infcx: &InferCtxt<'tcx>,
5555
param_env: ty::ParamEnv<'tcx>,
5656
implicit_region_bound: ty::Region<'tcx>,
57-
universal_regions: &Rc<UniversalRegions<'tcx>>,
57+
universal_regions: Rc<UniversalRegions<'tcx>>,
5858
constraints: &mut MirTypeckRegionConstraints<'tcx>,
5959
) -> CreateResult<'tcx> {
6060
UniversalRegionRelationsBuilder {
6161
infcx,
6262
param_env,
6363
implicit_region_bound,
6464
constraints,
65-
universal_regions: universal_regions.clone(),
65+
universal_regions,
6666
region_bound_pairs: Default::default(),
6767
outlives: Default::default(),
6868
inverse_outlives: Default::default(),

compiler/rustc_borrowck/src/type_check/liveness/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::rc::Rc;
2-
31
use itertools::{Either, Itertools};
42
use rustc_data_structures::fx::FxHashSet;
53
use rustc_middle::mir::visit::{TyContext, Visitor};
@@ -33,7 +31,7 @@ mod trace;
3331
pub(super) fn generate<'a, 'tcx>(
3432
typeck: &mut TypeChecker<'_, 'tcx>,
3533
body: &Body<'tcx>,
36-
elements: &Rc<DenseLocationMap>,
34+
elements: &DenseLocationMap,
3735
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
3836
move_data: &MoveData<'tcx>,
3937
) {

0 commit comments

Comments
 (0)