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`
This commit is contained in:
commit
9c4732a77d
@ -1,7 +1,5 @@
|
|||||||
//! This file provides API for compiler consumers.
|
//! This file provides API for compiler consumers.
|
||||||
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_index::{IndexSlice, IndexVec};
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_middle::mir::{Body, Promoted};
|
use rustc_middle::mir::{Body, Promoted};
|
||||||
@ -65,10 +63,10 @@ pub struct BodyWithBorrowckFacts<'tcx> {
|
|||||||
/// The mir bodies of promoteds.
|
/// The mir bodies of promoteds.
|
||||||
pub promoted: IndexVec<Promoted, Body<'tcx>>,
|
pub promoted: IndexVec<Promoted, Body<'tcx>>,
|
||||||
/// The set of borrows occurring in `body` with data about them.
|
/// 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
|
/// Context generated during borrowck, intended to be passed to
|
||||||
/// [`calculate_borrows_out_of_scope_at_location`].
|
/// [`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.
|
/// The table that maps Polonius points to locations in the table.
|
||||||
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
|
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
|
||||||
/// or [`ConsumerOptions::PoloniusOutputFacts`].
|
/// or [`ConsumerOptions::PoloniusOutputFacts`].
|
||||||
@ -79,7 +77,7 @@ pub struct BodyWithBorrowckFacts<'tcx> {
|
|||||||
pub input_facts: Option<Box<PoloniusInput>>,
|
pub input_facts: Option<Box<PoloniusInput>>,
|
||||||
/// Polonius output facts. Populated when using
|
/// Polonius output facts. Populated when using
|
||||||
/// [`ConsumerOptions::PoloniusOutputFacts`].
|
/// [`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`]
|
/// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
|
||||||
|
@ -708,9 +708,9 @@ fn report_use_of_uninitialized(
|
|||||||
// for the branching codepaths that aren't covered, to point at them.
|
// for the branching codepaths that aren't covered, to point at them.
|
||||||
let map = self.infcx.tcx.hir();
|
let map = self.infcx.tcx.hir();
|
||||||
let body = map.body_owned_by(self.mir_def_id());
|
let body = map.body_owned_by(self.mir_def_id());
|
||||||
let mut visitor =
|
let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] };
|
||||||
ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] };
|
|
||||||
visitor.visit_body(&body);
|
visitor.visit_body(&body);
|
||||||
|
let spans = visitor.spans;
|
||||||
|
|
||||||
let mut show_assign_sugg = false;
|
let mut show_assign_sugg = false;
|
||||||
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
|
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
|
||||||
@ -4465,20 +4465,20 @@ fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
|
|||||||
|
|
||||||
/// Given a set of spans representing statements initializing the relevant binding, visit all the
|
/// 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.
|
/// function expressions looking for branching code paths that *do not* initialize the binding.
|
||||||
struct ConditionVisitor<'b, 'tcx> {
|
struct ConditionVisitor<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
spans: &'b [Span],
|
spans: Vec<Span>,
|
||||||
name: &'b str,
|
name: String,
|
||||||
errors: Vec<(Span, 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>) {
|
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||||
match ex.kind {
|
match ex.kind {
|
||||||
hir::ExprKind::If(cond, body, None) => {
|
hir::ExprKind::If(cond, body, None) => {
|
||||||
// `if` expressions with no `else` that initialize the binding might be missing an
|
// `if` expressions with no `else` that initialize the binding might be missing an
|
||||||
// `else` arm.
|
// `else` arm.
|
||||||
if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() {
|
if ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break() {
|
||||||
self.errors.push((
|
self.errors.push((
|
||||||
cond.span,
|
cond.span,
|
||||||
format!(
|
format!(
|
||||||
@ -4495,8 +4495,8 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
|||||||
hir::ExprKind::If(cond, body, Some(other)) => {
|
hir::ExprKind::If(cond, body, Some(other)) => {
|
||||||
// `if` expressions where the binding is only initialized in one of the two arms
|
// `if` expressions where the binding is only initialized in one of the two arms
|
||||||
// might be missing a binding initialization.
|
// might be missing a binding initialization.
|
||||||
let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break();
|
let a = ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break();
|
||||||
let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break();
|
let b = ReferencedStatementsVisitor(&self.spans).visit_expr(other).is_break();
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(true, true) | (false, false) => {}
|
(true, true) | (false, false) => {}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
@ -4536,7 +4536,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
|||||||
// arms might be missing an initialization.
|
// arms might be missing an initialization.
|
||||||
let results: Vec<bool> = arms
|
let results: Vec<bool> = arms
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break())
|
.map(|arm| ReferencedStatementsVisitor(&self.spans).visit_arm(arm).is_break())
|
||||||
.collect();
|
.collect();
|
||||||
if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
|
if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
|
||||||
for (arm, seen) in arms.iter().zip(results) {
|
for (arm, seen) in arms.iter().zip(results) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
|
||||||
@ -11,7 +10,7 @@
|
|||||||
|
|
||||||
pub(crate) fn find<'tcx>(
|
pub(crate) fn find<'tcx>(
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
regioncx: &Rc<RegionInferenceContext<'tcx>>,
|
regioncx: &RegionInferenceContext<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
region_vid: RegionVid,
|
region_vid: RegionVid,
|
||||||
start_point: Location,
|
start_point: Location,
|
||||||
@ -23,7 +22,7 @@ pub(crate) fn find<'tcx>(
|
|||||||
|
|
||||||
struct UseFinder<'a, 'tcx> {
|
struct UseFinder<'a, 'tcx> {
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
regioncx: &'a Rc<RegionInferenceContext<'tcx>>,
|
regioncx: &'a RegionInferenceContext<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
region_vid: RegionVid,
|
region_vid: RegionVid,
|
||||||
start_point: Location,
|
start_point: Location,
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use consumers::{BodyWithBorrowckFacts, ConsumerOptions};
|
use consumers::{BodyWithBorrowckFacts, ConsumerOptions};
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
@ -200,8 +199,7 @@ fn do_mir_borrowck<'tcx>(
|
|||||||
.into_results_cursor(body);
|
.into_results_cursor(body);
|
||||||
|
|
||||||
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
|
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
|
||||||
let borrow_set =
|
let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);
|
||||||
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data));
|
|
||||||
|
|
||||||
// Compute non-lexical lifetimes.
|
// Compute non-lexical lifetimes.
|
||||||
let nll::NllOutput {
|
let nll::NllOutput {
|
||||||
@ -245,8 +243,6 @@ fn do_mir_borrowck<'tcx>(
|
|||||||
// usage significantly on some benchmarks.
|
// usage significantly on some benchmarks.
|
||||||
drop(flow_inits);
|
drop(flow_inits);
|
||||||
|
|
||||||
let regioncx = Rc::new(regioncx);
|
|
||||||
|
|
||||||
let flow_borrows = Borrows::new(tcx, body, ®ioncx, &borrow_set)
|
let flow_borrows = Borrows::new(tcx, body, ®ioncx, &borrow_set)
|
||||||
.into_engine(tcx, body)
|
.into_engine(tcx, body)
|
||||||
.pass_name("borrowck")
|
.pass_name("borrowck")
|
||||||
@ -288,10 +284,10 @@ fn do_mir_borrowck<'tcx>(
|
|||||||
access_place_error_reported: Default::default(),
|
access_place_error_reported: Default::default(),
|
||||||
reservation_error_reported: Default::default(),
|
reservation_error_reported: Default::default(),
|
||||||
uninitialized_error_reported: Default::default(),
|
uninitialized_error_reported: Default::default(),
|
||||||
regioncx: regioncx.clone(),
|
regioncx: ®ioncx,
|
||||||
used_mut: Default::default(),
|
used_mut: Default::default(),
|
||||||
used_mut_upvars: SmallVec::new(),
|
used_mut_upvars: SmallVec::new(),
|
||||||
borrow_set: Rc::clone(&borrow_set),
|
borrow_set: &borrow_set,
|
||||||
upvars: &[],
|
upvars: &[],
|
||||||
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
|
local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
|
||||||
region_names: RefCell::default(),
|
region_names: RefCell::default(),
|
||||||
@ -329,10 +325,10 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
|||||||
access_place_error_reported: Default::default(),
|
access_place_error_reported: Default::default(),
|
||||||
reservation_error_reported: Default::default(),
|
reservation_error_reported: Default::default(),
|
||||||
uninitialized_error_reported: Default::default(),
|
uninitialized_error_reported: Default::default(),
|
||||||
regioncx: Rc::clone(®ioncx),
|
regioncx: ®ioncx,
|
||||||
used_mut: Default::default(),
|
used_mut: Default::default(),
|
||||||
used_mut_upvars: SmallVec::new(),
|
used_mut_upvars: SmallVec::new(),
|
||||||
borrow_set: Rc::clone(&borrow_set),
|
borrow_set: &borrow_set,
|
||||||
upvars: tcx.closure_captures(def),
|
upvars: tcx.closure_captures(def),
|
||||||
local_names,
|
local_names,
|
||||||
region_names: RefCell::default(),
|
region_names: RefCell::default(),
|
||||||
@ -569,10 +565,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
|
|||||||
used_mut_upvars: SmallVec<[FieldIdx; 8]>,
|
used_mut_upvars: SmallVec<[FieldIdx; 8]>,
|
||||||
/// Region inference context. This contains the results from region inference and lets us e.g.
|
/// 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.
|
/// 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
|
/// 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
|
/// Information about upvars not necessarily preserved in types or MIR
|
||||||
upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
|
upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
|
||||||
@ -588,7 +584,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
|
|||||||
next_region_name: RefCell<usize>,
|
next_region_name: RefCell<usize>,
|
||||||
|
|
||||||
/// Results of Polonius analysis.
|
/// Results of Polonius analysis.
|
||||||
polonius_output: Option<Rc<PoloniusOutput>>,
|
polonius_output: Option<Box<PoloniusOutput>>,
|
||||||
|
|
||||||
diags: diags::BorrowckDiags<'infcx, 'tcx>,
|
diags: diags::BorrowckDiags<'infcx, 'tcx>,
|
||||||
move_errors: Vec<MoveError<'tcx>>,
|
move_errors: Vec<MoveError<'tcx>>,
|
||||||
@ -800,9 +796,8 @@ fn visit_terminator_after_primary_effect(
|
|||||||
TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
|
TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
|
||||||
if self.movable_coroutine {
|
if self.movable_coroutine {
|
||||||
// Look for any active borrows to locals
|
// Look for any active borrows to locals
|
||||||
let borrow_set = self.borrow_set.clone();
|
|
||||||
for i in state.borrows.iter() {
|
for i in state.borrows.iter() {
|
||||||
let borrow = &borrow_set[i];
|
let borrow = &self.borrow_set[i];
|
||||||
self.check_for_local_borrow(borrow, span);
|
self.check_for_local_borrow(borrow, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,9 +811,8 @@ fn visit_terminator_after_primary_effect(
|
|||||||
// Often, the storage will already have been killed by an explicit
|
// Often, the storage will already have been killed by an explicit
|
||||||
// StorageDead, but we don't always emit those (notably on unwind paths),
|
// StorageDead, but we don't always emit those (notably on unwind paths),
|
||||||
// so this "extra check" serves as a kind of backup.
|
// so this "extra check" serves as a kind of backup.
|
||||||
let borrow_set = self.borrow_set.clone();
|
|
||||||
for i in state.borrows.iter() {
|
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);
|
self.check_for_invalidation_at_exit(loc, borrow, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1037,13 +1031,12 @@ fn check_access_for_conflict(
|
|||||||
state: &BorrowckDomain<'a, 'tcx>,
|
state: &BorrowckDomain<'a, 'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut error_reported = false;
|
let mut error_reported = false;
|
||||||
let borrow_set = Rc::clone(&self.borrow_set);
|
|
||||||
|
|
||||||
// Use polonius output if it has been enabled.
|
// Use polonius output if it has been enabled.
|
||||||
let mut polonius_output;
|
let mut polonius_output;
|
||||||
let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
|
let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
|
||||||
let location = self.location_table.start_index(location);
|
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) {
|
for &idx in polonius.errors_at(location) {
|
||||||
polonius_output.insert(idx);
|
polonius_output.insert(idx);
|
||||||
}
|
}
|
||||||
@ -1057,7 +1050,7 @@ fn check_access_for_conflict(
|
|||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
self.body,
|
self.body,
|
||||||
(sd, place_span.0),
|
(sd, place_span.0),
|
||||||
&borrow_set,
|
self.borrow_set,
|
||||||
|borrow_index| borrows_in_scope.contains(borrow_index),
|
|borrow_index| borrows_in_scope.contains(borrow_index),
|
||||||
|this, borrow_index, borrow| match (rw, borrow.kind) {
|
|this, borrow_index, borrow| match (rw, borrow.kind) {
|
||||||
// Obviously an activation is compatible with its own
|
// Obviously an activation is compatible with its own
|
||||||
@ -1580,9 +1573,8 @@ fn check_activations(
|
|||||||
// Two-phase borrow support: For each activation that is newly
|
// Two-phase borrow support: For each activation that is newly
|
||||||
// generated at this statement, check if it interferes with
|
// generated at this statement, check if it interferes with
|
||||||
// another borrow.
|
// another borrow.
|
||||||
let borrow_set = self.borrow_set.clone();
|
for &borrow_index in self.borrow_set.activations_at_location(location) {
|
||||||
for &borrow_index in borrow_set.activations_at_location(location) {
|
let borrow = &self.borrow_set[borrow_index];
|
||||||
let borrow = &borrow_set[borrow_index];
|
|
||||||
|
|
||||||
// only mutable borrows should be 2-phase
|
// only mutable borrows should be 2-phase
|
||||||
assert!(match borrow.kind {
|
assert!(match borrow.kind {
|
||||||
|
@ -42,7 +42,7 @@ pub(crate) struct NllOutput<'tcx> {
|
|||||||
pub regioncx: RegionInferenceContext<'tcx>,
|
pub regioncx: RegionInferenceContext<'tcx>,
|
||||||
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
|
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
|
||||||
pub polonius_input: Option<Box<AllFacts>>,
|
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 opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
|
||||||
pub nll_errors: RegionErrors<'tcx>,
|
pub nll_errors: RegionErrors<'tcx>,
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
|||||||
|
|
||||||
let universal_regions = Rc::new(universal_regions);
|
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.
|
// Run the MIR type-checker.
|
||||||
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
|
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
|
||||||
@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
|||||||
param_env,
|
param_env,
|
||||||
body,
|
body,
|
||||||
promoted,
|
promoted,
|
||||||
&universal_regions,
|
universal_regions.clone(),
|
||||||
location_table,
|
location_table,
|
||||||
borrow_set,
|
borrow_set,
|
||||||
&mut all_facts,
|
&mut all_facts,
|
||||||
flow_inits,
|
flow_inits,
|
||||||
move_data,
|
move_data,
|
||||||
elements,
|
elements.clone(),
|
||||||
upvars,
|
upvars,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
|||||||
universe_causes,
|
universe_causes,
|
||||||
type_tests,
|
type_tests,
|
||||||
liveness_constraints,
|
liveness_constraints,
|
||||||
elements,
|
elements.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// If requested: dump NLL facts, and run legacy polonius analysis.
|
// If requested: dump NLL facts, and run legacy polonius analysis.
|
||||||
@ -184,7 +184,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
|||||||
let algorithm = Algorithm::from_str(&algorithm).unwrap();
|
let algorithm = Algorithm::from_str(&algorithm).unwrap();
|
||||||
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
|
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
|
||||||
let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis");
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ pub(crate) fn new(
|
|||||||
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
||||||
type_tests: Vec<TypeTest<'tcx>>,
|
type_tests: Vec<TypeTest<'tcx>>,
|
||||||
liveness_constraints: LivenessValues,
|
liveness_constraints: LivenessValues,
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: Rc<DenseLocationMap>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
debug!("universal_regions: {:#?}", universal_regions);
|
debug!("universal_regions: {:#?}", universal_regions);
|
||||||
debug!("outlives constraints: {:#?}", outlives_constraints);
|
debug!("outlives constraints: {:#?}", outlives_constraints);
|
||||||
@ -430,7 +430,7 @@ pub(crate) fn new(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut scc_values =
|
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() {
|
for region in liveness_constraints.regions() {
|
||||||
let scc = constraint_sccs.scc(region);
|
let scc = constraint_sccs.scc(region);
|
||||||
@ -637,7 +637,7 @@ pub(super) fn solve(
|
|||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
polonius_output: Option<Rc<PoloniusOutput>>,
|
polonius_output: Option<Box<PoloniusOutput>>,
|
||||||
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
|
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
|
||||||
let mir_def_id = body.source.def_id();
|
let mir_def_id = body.source.def_id();
|
||||||
self.propagate_constraints();
|
self.propagate_constraints();
|
||||||
@ -663,7 +663,9 @@ pub(super) fn solve(
|
|||||||
self.check_polonius_subset_errors(
|
self.check_polonius_subset_errors(
|
||||||
outlives_requirements.as_mut(),
|
outlives_requirements.as_mut(),
|
||||||
&mut errors_buffer,
|
&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 {
|
} else {
|
||||||
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
|
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
|
||||||
@ -1411,7 +1413,7 @@ fn check_polonius_subset_errors(
|
|||||||
&self,
|
&self,
|
||||||
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
||||||
errors_buffer: &mut RegionErrors<'tcx>,
|
errors_buffer: &mut RegionErrors<'tcx>,
|
||||||
polonius_output: Rc<PoloniusOutput>,
|
polonius_output: &PoloniusOutput,
|
||||||
) {
|
) {
|
||||||
debug!(
|
debug!(
|
||||||
"check_polonius_subset_errors: {} subset_errors",
|
"check_polonius_subset_errors: {} subset_errors",
|
||||||
|
@ -275,15 +275,16 @@ impl<N: Idx> RegionValues<N> {
|
|||||||
/// Each of the regions in num_region_variables will be initialized with an
|
/// Each of the regions in num_region_variables will be initialized with an
|
||||||
/// empty set of points and no causal information.
|
/// empty set of points and no causal information.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: Rc<DenseLocationMap>,
|
||||||
num_universal_regions: usize,
|
num_universal_regions: usize,
|
||||||
placeholder_indices: &Rc<PlaceholderIndices>,
|
placeholder_indices: Rc<PlaceholderIndices>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let num_points = elements.num_points();
|
||||||
let num_placeholders = placeholder_indices.len();
|
let num_placeholders = placeholder_indices.len();
|
||||||
Self {
|
Self {
|
||||||
elements: elements.clone(),
|
elements,
|
||||||
points: SparseIntervalMatrix::new(elements.num_points()),
|
points: SparseIntervalMatrix::new(num_points),
|
||||||
placeholder_indices: placeholder_indices.clone(),
|
placeholder_indices,
|
||||||
free_regions: SparseBitMatrix::new(num_universal_regions),
|
free_regions: SparseBitMatrix::new(num_universal_regions),
|
||||||
placeholders: SparseBitMatrix::new(num_placeholders),
|
placeholders: SparseBitMatrix::new(num_placeholders),
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ pub(crate) fn create<'tcx>(
|
|||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
implicit_region_bound: ty::Region<'tcx>,
|
implicit_region_bound: ty::Region<'tcx>,
|
||||||
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
universal_regions: Rc<UniversalRegions<'tcx>>,
|
||||||
constraints: &mut MirTypeckRegionConstraints<'tcx>,
|
constraints: &mut MirTypeckRegionConstraints<'tcx>,
|
||||||
) -> CreateResult<'tcx> {
|
) -> CreateResult<'tcx> {
|
||||||
UniversalRegionRelationsBuilder {
|
UniversalRegionRelationsBuilder {
|
||||||
@ -62,7 +62,7 @@ pub(crate) fn create<'tcx>(
|
|||||||
param_env,
|
param_env,
|
||||||
implicit_region_bound,
|
implicit_region_bound,
|
||||||
constraints,
|
constraints,
|
||||||
universal_regions: universal_regions.clone(),
|
universal_regions,
|
||||||
region_bound_pairs: Default::default(),
|
region_bound_pairs: Default::default(),
|
||||||
outlives: Default::default(),
|
outlives: Default::default(),
|
||||||
inverse_outlives: Default::default(),
|
inverse_outlives: Default::default(),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use itertools::{Either, Itertools};
|
use itertools::{Either, Itertools};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_middle::mir::visit::{TyContext, Visitor};
|
use rustc_middle::mir::visit::{TyContext, Visitor};
|
||||||
@ -33,7 +31,7 @@
|
|||||||
pub(super) fn generate<'a, 'tcx>(
|
pub(super) fn generate<'a, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: &DenseLocationMap,
|
||||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
) {
|
) {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::interval::IntervalSet;
|
use rustc_index::interval::IntervalSet;
|
||||||
@ -40,7 +38,7 @@
|
|||||||
pub(super) fn trace<'a, 'tcx>(
|
pub(super) fn trace<'a, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: &DenseLocationMap,
|
||||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
relevant_live_locals: Vec<Local>,
|
relevant_live_locals: Vec<Local>,
|
||||||
|
@ -121,13 +121,13 @@ pub(crate) fn type_check<'a, 'tcx>(
|
|||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||||
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
universal_regions: Rc<UniversalRegions<'tcx>>,
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
borrow_set: &BorrowSet<'tcx>,
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
all_facts: &mut Option<AllFacts>,
|
all_facts: &mut Option<AllFacts>,
|
||||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: Rc<DenseLocationMap>,
|
||||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||||
) -> MirTypeckResults<'tcx> {
|
) -> MirTypeckResults<'tcx> {
|
||||||
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
|
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
|
||||||
@ -150,14 +150,14 @@ pub(crate) fn type_check<'a, 'tcx>(
|
|||||||
infcx,
|
infcx,
|
||||||
param_env,
|
param_env,
|
||||||
implicit_region_bound,
|
implicit_region_bound,
|
||||||
universal_regions,
|
universal_regions.clone(),
|
||||||
&mut constraints,
|
&mut constraints,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(?normalized_inputs_and_output);
|
debug!(?normalized_inputs_and_output);
|
||||||
|
|
||||||
let mut borrowck_context = BorrowCheckContext {
|
let mut borrowck_context = BorrowCheckContext {
|
||||||
universal_regions,
|
universal_regions: &universal_regions,
|
||||||
location_table,
|
location_table,
|
||||||
borrow_set,
|
borrow_set,
|
||||||
all_facts,
|
all_facts,
|
||||||
@ -181,10 +181,10 @@ pub(crate) fn type_check<'a, 'tcx>(
|
|||||||
verifier.visit_body(body);
|
verifier.visit_body(body);
|
||||||
|
|
||||||
checker.typeck_mir(body);
|
checker.typeck_mir(body);
|
||||||
checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
|
checker.equate_inputs_and_outputs(body, &universal_regions, &normalized_inputs_and_output);
|
||||||
checker.check_signature_annotation(body);
|
checker.check_signature_annotation(body);
|
||||||
|
|
||||||
liveness::generate(&mut checker, body, elements, flow_inits, move_data);
|
liveness::generate(&mut checker, body, &elements, flow_inits, move_data);
|
||||||
|
|
||||||
translate_outlives_facts(&mut checker);
|
translate_outlives_facts(&mut checker);
|
||||||
let opaque_type_values = infcx.take_opaque_types();
|
let opaque_type_values = infcx.take_opaque_types();
|
||||||
|
Loading…
Reference in New Issue
Block a user