Skip to content

Commit

Permalink
Unrolled build for rust-lang#131225
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#131225 - nnethercote:rustc_borrowck-mm, r=lqd

`rustc_borrowck` memory management tweaks

Minor cleanups in `rustc_borrowck` relating to memory management.

r? `@lqd`
  • Loading branch information
rust-timer authored Oct 7, 2024
2 parents 7caad69 + c69d174 commit 02fcdd2
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 70 deletions.
8 changes: 3 additions & 5 deletions compiler/rustc_borrowck/src/consumers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! This file provides API for compiler consumers.
use std::rc::Rc;

use rustc_hir::def_id::LocalDefId;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::{Body, Promoted};
Expand Down Expand Up @@ -65,10 +63,10 @@ pub struct BodyWithBorrowckFacts<'tcx> {
/// The mir bodies of promoteds.
pub promoted: IndexVec<Promoted, Body<'tcx>>,
/// The set of borrows occurring in `body` with data about them.
pub borrow_set: Rc<BorrowSet<'tcx>>,
pub borrow_set: BorrowSet<'tcx>,
/// Context generated during borrowck, intended to be passed to
/// [`calculate_borrows_out_of_scope_at_location`].
pub region_inference_context: Rc<RegionInferenceContext<'tcx>>,
pub region_inference_context: RegionInferenceContext<'tcx>,
/// The table that maps Polonius points to locations in the table.
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
/// or [`ConsumerOptions::PoloniusOutputFacts`].
Expand All @@ -79,7 +77,7 @@ pub struct BodyWithBorrowckFacts<'tcx> {
pub input_facts: Option<Box<PoloniusInput>>,
/// Polonius output facts. Populated when using
/// [`ConsumerOptions::PoloniusOutputFacts`].
pub output_facts: Option<Rc<PoloniusOutput>>,
pub output_facts: Option<Box<PoloniusOutput>>,
}

/// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// for the branching codepaths that aren't covered, to point at them.
let map = self.infcx.tcx.hir();
let body = map.body_owned_by(self.mir_def_id());
let mut visitor =
ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] };
let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] };
visitor.visit_body(&body);
let spans = visitor.spans;

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

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

impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
impl<'v, 'tcx> Visitor<'v> for ConditionVisitor<'tcx> {
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
match ex.kind {
hir::ExprKind::If(cond, body, None) => {
// `if` expressions with no `else` that initialize the binding might be missing an
// `else` arm.
if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() {
if ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break() {
self.errors.push((
cond.span,
format!(
Expand All @@ -4495,8 +4495,8 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
hir::ExprKind::If(cond, body, Some(other)) => {
// `if` expressions where the binding is only initialized in one of the two arms
// might be missing a binding initialization.
let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break();
let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break();
let a = ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break();
let b = ReferencedStatementsVisitor(&self.spans).visit_expr(other).is_break();
match (a, b) {
(true, true) | (false, false) => {}
(true, false) => {
Expand Down Expand Up @@ -4536,7 +4536,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
// arms might be missing an initialization.
let results: Vec<bool> = arms
.iter()
.map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break())
.map(|arm| ReferencedStatementsVisitor(&self.spans).visit_arm(arm).is_break())
.collect();
if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
for (arm, seen) in arms.iter().zip(results) {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/find_use.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::collections::VecDeque;
use std::rc::Rc;

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

pub(crate) fn find<'tcx>(
body: &Body<'tcx>,
regioncx: &Rc<RegionInferenceContext<'tcx>>,
regioncx: &RegionInferenceContext<'tcx>,
tcx: TyCtxt<'tcx>,
region_vid: RegionVid,
start_point: Location,
Expand All @@ -23,7 +22,7 @@ pub(crate) fn find<'tcx>(

struct UseFinder<'a, 'tcx> {
body: &'a Body<'tcx>,
regioncx: &'a Rc<RegionInferenceContext<'tcx>>,
regioncx: &'a RegionInferenceContext<'tcx>,
tcx: TyCtxt<'tcx>,
region_vid: RegionVid,
start_point: Location,
Expand Down
36 changes: 14 additions & 22 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use std::cell::RefCell;
use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::rc::Rc;

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

let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
let borrow_set =
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data));
let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);

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

let regioncx = Rc::new(regioncx);

let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set)
.into_engine(tcx, body)
.pass_name("borrowck")
Expand Down Expand Up @@ -288,10 +284,10 @@ fn do_mir_borrowck<'tcx>(
access_place_error_reported: Default::default(),
reservation_error_reported: Default::default(),
uninitialized_error_reported: Default::default(),
regioncx: regioncx.clone(),
regioncx: &regioncx,
used_mut: Default::default(),
used_mut_upvars: SmallVec::new(),
borrow_set: Rc::clone(&borrow_set),
borrow_set: &borrow_set,
upvars: &[],
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
region_names: RefCell::default(),
Expand Down Expand Up @@ -329,10 +325,10 @@ fn do_mir_borrowck<'tcx>(
access_place_error_reported: Default::default(),
reservation_error_reported: Default::default(),
uninitialized_error_reported: Default::default(),
regioncx: Rc::clone(&regioncx),
regioncx: &regioncx,
used_mut: Default::default(),
used_mut_upvars: SmallVec::new(),
borrow_set: Rc::clone(&borrow_set),
borrow_set: &borrow_set,
upvars: tcx.closure_captures(def),
local_names,
region_names: RefCell::default(),
Expand Down Expand Up @@ -569,10 +565,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
used_mut_upvars: SmallVec<[FieldIdx; 8]>,
/// Region inference context. This contains the results from region inference and lets us e.g.
/// find out which CFG points are contained in each borrow region.
regioncx: Rc<RegionInferenceContext<'tcx>>,
regioncx: &'a RegionInferenceContext<'tcx>,

/// The set of borrows extracted from the MIR
borrow_set: Rc<BorrowSet<'tcx>>,
borrow_set: &'a BorrowSet<'tcx>,

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

/// Results of Polonius analysis.
polonius_output: Option<Rc<PoloniusOutput>>,
polonius_output: Option<Box<PoloniusOutput>>,

diags: diags::BorrowckDiags<'infcx, 'tcx>,
move_errors: Vec<MoveError<'tcx>>,
Expand Down Expand Up @@ -800,9 +796,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
if self.movable_coroutine {
// Look for any active borrows to locals
let borrow_set = self.borrow_set.clone();
for i in state.borrows.iter() {
let borrow = &borrow_set[i];
let borrow = &self.borrow_set[i];
self.check_for_local_borrow(borrow, span);
}
}
Expand All @@ -816,9 +811,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
// Often, the storage will already have been killed by an explicit
// StorageDead, but we don't always emit those (notably on unwind paths),
// so this "extra check" serves as a kind of backup.
let borrow_set = self.borrow_set.clone();
for i in state.borrows.iter() {
let borrow = &borrow_set[i];
let borrow = &self.borrow_set[i];
self.check_for_invalidation_at_exit(loc, borrow, span);
}
}
Expand Down Expand Up @@ -1037,13 +1031,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
state: &BorrowckDomain<'a, 'tcx>,
) -> bool {
let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set);

// Use polonius output if it has been enabled.
let mut polonius_output;
let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
let location = self.location_table.start_index(location);
polonius_output = BitSet::new_empty(borrow_set.len());
polonius_output = BitSet::new_empty(self.borrow_set.len());
for &idx in polonius.errors_at(location) {
polonius_output.insert(idx);
}
Expand All @@ -1057,7 +1050,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
self.infcx.tcx,
self.body,
(sd, place_span.0),
&borrow_set,
self.borrow_set,
|borrow_index| borrows_in_scope.contains(borrow_index),
|this, borrow_index, borrow| match (rw, borrow.kind) {
// Obviously an activation is compatible with its own
Expand Down Expand Up @@ -1580,9 +1573,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
// another borrow.
let borrow_set = self.borrow_set.clone();
for &borrow_index in borrow_set.activations_at_location(location) {
let borrow = &borrow_set[borrow_index];
for &borrow_index in self.borrow_set.activations_at_location(location) {
let borrow = &self.borrow_set[borrow_index];

// only mutable borrows should be 2-phase
assert!(match borrow.kind {
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(crate) struct NllOutput<'tcx> {
pub regioncx: RegionInferenceContext<'tcx>,
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub polonius_input: Option<Box<AllFacts>>,
pub polonius_output: Option<Rc<PoloniusOutput>>,
pub polonius_output: Option<Box<PoloniusOutput>>,
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
pub nll_errors: RegionErrors<'tcx>,
}
Expand Down Expand Up @@ -98,7 +98,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(

let universal_regions = Rc::new(universal_regions);

let elements = &Rc::new(DenseLocationMap::new(body));
let elements = Rc::new(DenseLocationMap::new(body));

// Run the MIR type-checker.
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
Expand All @@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
param_env,
body,
promoted,
&universal_regions,
universal_regions.clone(),
location_table,
borrow_set,
&mut all_facts,
flow_inits,
move_data,
elements,
elements.clone(),
upvars,
);

Expand Down Expand Up @@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
universe_causes,
type_tests,
liveness_constraints,
elements,
elements.clone(),
);

// If requested: dump NLL facts, and run legacy polonius analysis.
Expand All @@ -184,7 +184,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
let algorithm = Algorithm::from_str(&algorithm).unwrap();
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis");
Some(Rc::new(Output::compute(all_facts, algorithm, false)))
Some(Box::new(Output::compute(all_facts, algorithm, false)))
} else {
None
}
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues,
elements: &Rc<DenseLocationMap>,
elements: Rc<DenseLocationMap>,
) -> Self {
debug!("universal_regions: {:#?}", universal_regions);
debug!("outlives constraints: {:#?}", outlives_constraints);
Expand All @@ -430,7 +430,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}

let mut scc_values =
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
RegionValues::new(elements, universal_regions.len(), placeholder_indices);

for region in liveness_constraints.regions() {
let scc = constraint_sccs.scc(region);
Expand Down Expand Up @@ -637,7 +637,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&mut self,
infcx: &InferCtxt<'tcx>,
body: &Body<'tcx>,
polonius_output: Option<Rc<PoloniusOutput>>,
polonius_output: Option<Box<PoloniusOutput>>,
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
let mir_def_id = body.source.def_id();
self.propagate_constraints();
Expand All @@ -663,7 +663,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.check_polonius_subset_errors(
outlives_requirements.as_mut(),
&mut errors_buffer,
polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
polonius_output
.as_ref()
.expect("Polonius output is unavailable despite `-Z polonius`"),
);
} else {
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
Expand Down Expand Up @@ -1411,7 +1413,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut RegionErrors<'tcx>,
polonius_output: Rc<PoloniusOutput>,
polonius_output: &PoloniusOutput,
) {
debug!(
"check_polonius_subset_errors: {} subset_errors",
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,16 @@ impl<N: Idx> RegionValues<N> {
/// Each of the regions in num_region_variables will be initialized with an
/// empty set of points and no causal information.
pub(crate) fn new(
elements: &Rc<DenseLocationMap>,
elements: Rc<DenseLocationMap>,
num_universal_regions: usize,
placeholder_indices: &Rc<PlaceholderIndices>,
placeholder_indices: Rc<PlaceholderIndices>,
) -> Self {
let num_points = elements.num_points();
let num_placeholders = placeholder_indices.len();
Self {
elements: elements.clone(),
points: SparseIntervalMatrix::new(elements.num_points()),
placeholder_indices: placeholder_indices.clone(),
elements,
points: SparseIntervalMatrix::new(num_points),
placeholder_indices,
free_regions: SparseBitMatrix::new(num_universal_regions),
placeholders: SparseBitMatrix::new(num_placeholders),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ pub(crate) fn create<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
universal_regions: &Rc<UniversalRegions<'tcx>>,
universal_regions: Rc<UniversalRegions<'tcx>>,
constraints: &mut MirTypeckRegionConstraints<'tcx>,
) -> CreateResult<'tcx> {
UniversalRegionRelationsBuilder {
infcx,
param_env,
implicit_region_bound,
constraints,
universal_regions: universal_regions.clone(),
universal_regions,
region_bound_pairs: Default::default(),
outlives: Default::default(),
inverse_outlives: Default::default(),
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_borrowck/src/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::rc::Rc;

use itertools::{Either, Itertools};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::mir::visit::{TyContext, Visitor};
Expand Down Expand Up @@ -33,7 +31,7 @@ mod trace;
pub(super) fn generate<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>,
elements: &DenseLocationMap,
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>,
) {
Expand Down
Loading

0 comments on commit 02fcdd2

Please sign in to comment.