1
Fork 0

Rollup merge of #135250 - lqd:simple-cleanups, r=matthewjasper

A couple simple borrowck cleanups

This PR has a couple simple renamings:
- it's been a long time since the mapping from `Location`s to `PointIndex`es was extracted from `RegionElements` into the `DenseLocationMap`, but only the types were renamed at the time. borrowck still refers to this map as `elements`. That's confusing, especially since sometimes we also use the mapping via `LivenessValues`, and makes more sense as `location_map` instead.
- to clarify `LocationTable` is not as general as it sounds, and is only for datalog polonius. In this branch I didn't rename the handful of `location_table` fields and params to `polonius_table`, but can do that to differentiate it even more from `location_map`. I did try it locally and it looks worthwhile, so if you'd prefer I can also push it here. (Or we could even switch these datalog types and fields to even more explicit names)
- to clarify the incomprehensible `AllFacts`, it is renamed to `PoloniusFacts`. These can be referred to as `facts` within the legacy polonius module, but as `polonius_facts` outside of it to make it clear that they're not about NLLs (nor are they about in-tree polonius but that'll be magically fixed when they're removed in the future)

r? `@matthewjasper`
This commit is contained in:
Matthias Krüger 2025-01-08 18:21:02 +01:00 committed by GitHub
commit 9ea76e44e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 153 additions and 146 deletions

View file

@ -11,8 +11,8 @@ pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_a
pub use super::place_ext::PlaceExt; pub use super::place_ext::PlaceExt;
pub use super::places_conflict::{PlaceConflictBias, places_conflict}; pub use super::places_conflict::{PlaceConflictBias, places_conflict};
pub use super::polonius::legacy::{ pub use super::polonius::legacy::{
AllFacts as PoloniusInput, LocationTable, PoloniusOutput, PoloniusRegionVid, RichLocation, PoloniusFacts as PoloniusInput, PoloniusLocationTable, PoloniusOutput, PoloniusRegionVid,
RustcFacts, RichLocation, RustcFacts,
}; };
pub use super::region_infer::RegionInferenceContext; pub use super::region_infer::RegionInferenceContext;
@ -33,7 +33,7 @@ pub enum ConsumerOptions {
/// without significant slowdowns. /// without significant slowdowns.
/// ///
/// Implies [`RegionInferenceContext`](ConsumerOptions::RegionInferenceContext), /// Implies [`RegionInferenceContext`](ConsumerOptions::RegionInferenceContext),
/// and additionally retrieve the [`LocationTable`] and [`PoloniusInput`] that /// and additionally retrieve the [`PoloniusLocationTable`] and [`PoloniusInput`] that
/// would be given to Polonius. Critically, this does not run Polonius, which /// would be given to Polonius. Critically, this does not run Polonius, which
/// one may want to avoid due to performance issues on large bodies. /// one may want to avoid due to performance issues on large bodies.
PoloniusInputFacts, PoloniusInputFacts,
@ -71,7 +71,7 @@ pub struct BodyWithBorrowckFacts<'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`].
pub location_table: Option<LocationTable>, pub location_table: Option<PoloniusLocationTable>,
/// Polonius input facts. /// Polonius input facts.
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`] /// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
/// or [`ConsumerOptions::PoloniusOutputFacts`]. /// or [`ConsumerOptions::PoloniusOutputFacts`].

View file

@ -57,7 +57,7 @@ use crate::diagnostics::{
use crate::path_utils::*; use crate::path_utils::*;
use crate::place_ext::PlaceExt; use crate::place_ext::PlaceExt;
use crate::places_conflict::{PlaceConflictBias, places_conflict}; use crate::places_conflict::{PlaceConflictBias, places_conflict};
use crate::polonius::legacy::{LocationTable, PoloniusOutput}; use crate::polonius::legacy::{PoloniusLocationTable, PoloniusOutput};
use crate::prefixes::PrefixSet; use crate::prefixes::PrefixSet;
use crate::region_infer::RegionInferenceContext; use crate::region_infer::RegionInferenceContext;
use crate::renumber::RegionCtxt; use crate::renumber::RegionCtxt;
@ -176,7 +176,7 @@ fn do_mir_borrowck<'tcx>(
infcx.register_predefined_opaques_for_next_solver(def); infcx.register_predefined_opaques_for_next_solver(def);
} }
let location_table = LocationTable::new(body); let location_table = PoloniusLocationTable::new(body);
let move_data = MoveData::gather_moves(body, tcx, |_| true); let move_data = MoveData::gather_moves(body, tcx, |_| true);
let promoted_move_data = promoted let promoted_move_data = promoted
@ -247,7 +247,8 @@ fn do_mir_borrowck<'tcx>(
infcx: &infcx, infcx: &infcx,
body: promoted_body, body: promoted_body,
move_data: &move_data, move_data: &move_data,
location_table: &location_table, // no need to create a real one for the promoted, it is not used // no need to create a real location table for the promoted, it is not used
location_table: &location_table,
movable_coroutine, movable_coroutine,
fn_self_span_reported: Default::default(), fn_self_span_reported: Default::default(),
locals_are_invalidated_at_exit, locals_are_invalidated_at_exit,
@ -513,7 +514,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
/// Map from MIR `Location` to `LocationIndex`; created /// Map from MIR `Location` to `LocationIndex`; created
/// when MIR borrowck begins. /// when MIR borrowck begins.
location_table: &'a LocationTable, location_table: &'a PoloniusLocationTable,
movable_coroutine: bool, movable_coroutine: bool,
/// This keeps track of whether local variables are free-ed when the function /// This keeps track of whether local variables are free-ed when the function

View file

@ -28,7 +28,9 @@ use crate::borrow_set::BorrowSet;
use crate::consumers::ConsumerOptions; use crate::consumers::ConsumerOptions;
use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors}; use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
use crate::polonius::LocalizedOutlivesConstraintSet; use crate::polonius::LocalizedOutlivesConstraintSet;
use crate::polonius::legacy::{AllFacts, AllFactsExt, LocationTable, PoloniusOutput}; use crate::polonius::legacy::{
PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
};
use crate::region_infer::RegionInferenceContext; use crate::region_infer::RegionInferenceContext;
use crate::type_check::{self, MirTypeckResults}; use crate::type_check::{self, MirTypeckResults};
use crate::universal_regions::UniversalRegions; use crate::universal_regions::UniversalRegions;
@ -39,7 +41,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber};
pub(crate) struct NllOutput<'tcx> { 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<PoloniusFacts>>,
pub polonius_output: Option<Box<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>,
@ -80,7 +82,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
universal_regions: UniversalRegions<'tcx>, universal_regions: UniversalRegions<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
@ -91,10 +93,10 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|| is_polonius_legacy_enabled; || is_polonius_legacy_enabled;
let polonius_output = consumer_options.map(|c| c.polonius_output()).unwrap_or_default() let polonius_output = consumer_options.map(|c| c.polonius_output()).unwrap_or_default()
|| is_polonius_legacy_enabled; || is_polonius_legacy_enabled;
let mut all_facts = let mut polonius_facts =
(polonius_input || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default()); (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default());
let elements = Rc::new(DenseLocationMap::new(body)); let location_map = Rc::new(DenseLocationMap::new(body));
// Run the MIR type-checker. // Run the MIR type-checker.
let MirTypeckResults { let MirTypeckResults {
@ -109,10 +111,10 @@ pub(crate) fn compute_regions<'a, 'tcx>(
universal_regions, universal_regions,
location_table, location_table,
borrow_set, borrow_set,
&mut all_facts, &mut polonius_facts,
flow_inits, flow_inits,
move_data, move_data,
Rc::clone(&elements), Rc::clone(&location_map),
); );
// Create the region inference context, taking ownership of the // Create the region inference context, taking ownership of the
@ -122,7 +124,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
// If requested, emit legacy polonius facts. // If requested, emit legacy polonius facts.
polonius::legacy::emit_facts( polonius::legacy::emit_facts(
&mut all_facts, &mut polonius_facts,
infcx.tcx, infcx.tcx,
location_table, location_table,
body, body,
@ -137,7 +139,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
var_infos, var_infos,
constraints, constraints,
universal_region_relations, universal_region_relations,
elements, location_map,
); );
// If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives
@ -147,13 +149,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
}); });
// If requested: dump NLL facts, and run legacy polonius analysis. // If requested: dump NLL facts, and run legacy polonius analysis.
let polonius_output = all_facts.as_ref().and_then(|all_facts| { let polonius_output = polonius_facts.as_ref().and_then(|polonius_facts| {
if infcx.tcx.sess.opts.unstable_opts.nll_facts { if infcx.tcx.sess.opts.unstable_opts.nll_facts {
let def_id = body.source.def_id(); let def_id = body.source.def_id();
let def_path = infcx.tcx.def_path(def_id); let def_path = infcx.tcx.def_path(def_id);
let dir_path = PathBuf::from(&infcx.tcx.sess.opts.unstable_opts.nll_facts_dir) let dir_path = PathBuf::from(&infcx.tcx.sess.opts.unstable_opts.nll_facts_dir)
.join(def_path.to_filename_friendly_no_crate()); .join(def_path.to_filename_friendly_no_crate());
all_facts.write_to_dir(dir_path, location_table).unwrap(); polonius_facts.write_to_dir(dir_path, location_table).unwrap();
} }
if polonius_output { if polonius_output {
@ -162,7 +164,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(Box::new(Output::compute(all_facts, algorithm, false))) Some(Box::new(Output::compute(polonius_facts, algorithm, false)))
} else { } else {
None None
} }
@ -182,7 +184,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
NllOutput { NllOutput {
regioncx, regioncx,
opaque_type_values: remapped_opaque_tys, opaque_type_values: remapped_opaque_tys,
polonius_input: all_facts.map(Box::new), polonius_input: polonius_facts.map(Box::new),
polonius_output, polonius_output,
opt_closure_req: closure_region_requirements, opt_closure_req: closure_region_requirements,
nll_errors, nll_errors,

View file

@ -4,16 +4,16 @@ use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData}; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData};
use tracing::debug; use tracing::debug;
use super::{AllFacts, LocationIndex, LocationTable}; use super::{LocationIndex, PoloniusFacts, PoloniusLocationTable};
use crate::def_use::{self, DefUse}; use crate::def_use::{self, DefUse};
use crate::universal_regions::UniversalRegions; use crate::universal_regions::UniversalRegions;
/// Emit polonius facts for variable defs, uses, drops, and path accesses. /// Emit polonius facts for variable defs, uses, drops, and path accesses.
pub(crate) fn emit_access_facts<'tcx>( pub(crate) fn emit_access_facts<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
facts: &mut AllFacts, facts: &mut PoloniusFacts,
body: &Body<'tcx>, body: &Body<'tcx>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
universal_regions: &UniversalRegions<'tcx>, universal_regions: &UniversalRegions<'tcx>,
) { ) {
@ -31,9 +31,9 @@ pub(crate) fn emit_access_facts<'tcx>(
/// MIR visitor extracting point-wise facts about accesses. /// MIR visitor extracting point-wise facts about accesses.
struct AccessFactsExtractor<'a, 'tcx> { struct AccessFactsExtractor<'a, 'tcx> {
facts: &'a mut AllFacts, facts: &'a mut PoloniusFacts,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
location_table: &'a LocationTable, location_table: &'a PoloniusLocationTable,
} }
impl<'tcx> AccessFactsExtractor<'_, 'tcx> { impl<'tcx> AccessFactsExtractor<'_, 'tcx> {

View file

@ -4,13 +4,13 @@ use std::fs::{self, File};
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use polonius_engine::{AllFacts as PoloniusFacts, Atom, Output}; use polonius_engine::{AllFacts, Atom, Output};
use rustc_macros::extension; use rustc_macros::extension;
use rustc_middle::mir::Local; use rustc_middle::mir::Local;
use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_middle::ty::{RegionVid, TyCtxt};
use rustc_mir_dataflow::move_paths::MovePathIndex; use rustc_mir_dataflow::move_paths::MovePathIndex;
use super::{LocationIndex, LocationTable}; use super::{LocationIndex, PoloniusLocationTable};
use crate::BorrowIndex; use crate::BorrowIndex;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -49,11 +49,11 @@ impl polonius_engine::FactTypes for RustcFacts {
type Path = MovePathIndex; type Path = MovePathIndex;
} }
pub type AllFacts = PoloniusFacts<RustcFacts>; pub type PoloniusFacts = AllFacts<RustcFacts>;
#[extension(pub(crate) trait AllFactsExt)] #[extension(pub(crate) trait PoloniusFactsExt)]
impl AllFacts { impl PoloniusFacts {
/// Returns `true` if there is a need to gather `AllFacts` given the /// Returns `true` if there is a need to gather `PoloniusFacts` given the
/// current `-Z` flags. /// current `-Z` flags.
fn enabled(tcx: TyCtxt<'_>) -> bool { fn enabled(tcx: TyCtxt<'_>) -> bool {
tcx.sess.opts.unstable_opts.nll_facts tcx.sess.opts.unstable_opts.nll_facts
@ -63,7 +63,7 @@ impl AllFacts {
fn write_to_dir( fn write_to_dir(
&self, &self,
dir: impl AsRef<Path>, dir: impl AsRef<Path>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let dir: &Path = dir.as_ref(); let dir: &Path = dir.as_ref();
fs::create_dir_all(dir)?; fs::create_dir_all(dir)?;
@ -119,7 +119,7 @@ impl Atom for LocationIndex {
} }
struct FactWriter<'w> { struct FactWriter<'w> {
location_table: &'w LocationTable, location_table: &'w PoloniusLocationTable,
dir: &'w Path, dir: &'w Path,
} }
@ -141,7 +141,7 @@ trait FactRow {
fn write( fn write(
&self, &self,
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>>; ) -> Result<(), Box<dyn Error>>;
} }
@ -149,7 +149,7 @@ impl FactRow for PoloniusRegionVid {
fn write( fn write(
&self, &self,
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
write_row(out, location_table, &[self]) write_row(out, location_table, &[self])
} }
@ -163,7 +163,7 @@ where
fn write( fn write(
&self, &self,
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
write_row(out, location_table, &[&self.0, &self.1]) write_row(out, location_table, &[&self.0, &self.1])
} }
@ -178,7 +178,7 @@ where
fn write( fn write(
&self, &self,
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
write_row(out, location_table, &[&self.0, &self.1, &self.2]) write_row(out, location_table, &[&self.0, &self.1, &self.2])
} }
@ -194,7 +194,7 @@ where
fn write( fn write(
&self, &self,
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3]) write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3])
} }
@ -202,7 +202,7 @@ where
fn write_row( fn write_row(
out: &mut dyn Write, out: &mut dyn Write,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
columns: &[&dyn FactCell], columns: &[&dyn FactCell],
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
for (index, c) in columns.iter().enumerate() { for (index, c) in columns.iter().enumerate() {
@ -213,41 +213,41 @@ fn write_row(
} }
trait FactCell { trait FactCell {
fn to_string(&self, location_table: &LocationTable) -> String; fn to_string(&self, location_table: &PoloniusLocationTable) -> String;
} }
impl FactCell for BorrowIndex { impl FactCell for BorrowIndex {
fn to_string(&self, _location_table: &LocationTable) -> String { fn to_string(&self, _location_table: &PoloniusLocationTable) -> String {
format!("{self:?}") format!("{self:?}")
} }
} }
impl FactCell for Local { impl FactCell for Local {
fn to_string(&self, _location_table: &LocationTable) -> String { fn to_string(&self, _location_table: &PoloniusLocationTable) -> String {
format!("{self:?}") format!("{self:?}")
} }
} }
impl FactCell for MovePathIndex { impl FactCell for MovePathIndex {
fn to_string(&self, _location_table: &LocationTable) -> String { fn to_string(&self, _location_table: &PoloniusLocationTable) -> String {
format!("{self:?}") format!("{self:?}")
} }
} }
impl FactCell for PoloniusRegionVid { impl FactCell for PoloniusRegionVid {
fn to_string(&self, _location_table: &LocationTable) -> String { fn to_string(&self, _location_table: &PoloniusLocationTable) -> String {
format!("{self:?}") format!("{self:?}")
} }
} }
impl FactCell for RegionVid { impl FactCell for RegionVid {
fn to_string(&self, _location_table: &LocationTable) -> String { fn to_string(&self, _location_table: &PoloniusLocationTable) -> String {
format!("{self:?}") format!("{self:?}")
} }
} }
impl FactCell for LocationIndex { impl FactCell for LocationIndex {
fn to_string(&self, location_table: &LocationTable) -> String { fn to_string(&self, location_table: &PoloniusLocationTable) -> String {
format!("{:?}", location_table.to_rich_location(*self)) format!("{:?}", location_table.to_rich_location(*self))
} }
} }

View file

@ -11,7 +11,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::debug; use tracing::debug;
use super::{AllFacts, LocationTable}; use super::{PoloniusFacts, PoloniusLocationTable};
use crate::borrow_set::BorrowSet; use crate::borrow_set::BorrowSet;
use crate::path_utils::*; use crate::path_utils::*;
use crate::{ use crate::{
@ -22,9 +22,9 @@ use crate::{
/// Emit `loan_invalidated_at` facts. /// Emit `loan_invalidated_at` facts.
pub(super) fn emit_loan_invalidations<'tcx>( pub(super) fn emit_loan_invalidations<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
facts: &mut AllFacts, facts: &mut PoloniusFacts,
body: &Body<'tcx>, body: &Body<'tcx>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
) { ) {
let dominators = body.basic_blocks.dominators(); let dominators = body.basic_blocks.dominators();
@ -35,9 +35,9 @@ pub(super) fn emit_loan_invalidations<'tcx>(
struct LoanInvalidationsGenerator<'a, 'tcx> { struct LoanInvalidationsGenerator<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
facts: &'a mut AllFacts, facts: &'a mut PoloniusFacts,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
location_table: &'a LocationTable, location_table: &'a PoloniusLocationTable,
dominators: &'a Dominators<BasicBlock>, dominators: &'a Dominators<BasicBlock>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
} }

View file

@ -6,16 +6,16 @@ use rustc_middle::mir::{
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::debug; use tracing::debug;
use super::{AllFacts, LocationTable}; use super::{PoloniusFacts, PoloniusLocationTable};
use crate::borrow_set::BorrowSet; use crate::borrow_set::BorrowSet;
use crate::places_conflict; use crate::places_conflict;
/// Emit `loan_killed_at` and `cfg_edge` facts at the same time. /// Emit `loan_killed_at` and `cfg_edge` facts at the same time.
pub(super) fn emit_loan_kills<'tcx>( pub(super) fn emit_loan_kills<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
facts: &mut AllFacts, facts: &mut PoloniusFacts,
body: &Body<'tcx>, body: &Body<'tcx>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
) { ) {
let mut visitor = LoanKillsGenerator { borrow_set, tcx, location_table, facts, body }; let mut visitor = LoanKillsGenerator { borrow_set, tcx, location_table, facts, body };
@ -26,8 +26,8 @@ pub(super) fn emit_loan_kills<'tcx>(
struct LoanKillsGenerator<'a, 'tcx> { struct LoanKillsGenerator<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
facts: &'a mut AllFacts, facts: &'a mut PoloniusFacts,
location_table: &'a LocationTable, location_table: &'a PoloniusLocationTable,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
} }

View file

@ -13,7 +13,7 @@ use tracing::debug;
/// granularity through outlives relations; however, the rich location /// granularity through outlives relations; however, the rich location
/// table serves another purpose: it compresses locations from /// table serves another purpose: it compresses locations from
/// multiple words into a single u32. /// multiple words into a single u32.
pub struct LocationTable { pub struct PoloniusLocationTable {
num_points: usize, num_points: usize,
statements_before_block: IndexVec<BasicBlock, usize>, statements_before_block: IndexVec<BasicBlock, usize>,
} }
@ -30,7 +30,7 @@ pub enum RichLocation {
Mid(Location), Mid(Location),
} }
impl LocationTable { impl PoloniusLocationTable {
pub(crate) fn new(body: &Body<'_>) -> Self { pub(crate) fn new(body: &Body<'_>) -> Self {
let mut num_points = 0; let mut num_points = 0;
let statements_before_block = body let statements_before_block = body
@ -43,8 +43,8 @@ impl LocationTable {
}) })
.collect(); .collect();
debug!("LocationTable(statements_before_block={:#?})", statements_before_block); debug!("PoloniusLocationTable(statements_before_block={:#?})", statements_before_block);
debug!("LocationTable: num_points={:#?}", num_points); debug!("PoloniusLocationTable: num_points={:#?}", num_points);
Self { num_points, statements_before_block } Self { num_points, statements_before_block }
} }

View file

@ -36,16 +36,16 @@ pub use self::facts::*;
/// ///
/// The rest of the facts are emitted during typeck and liveness. /// The rest of the facts are emitted during typeck and liveness.
pub(crate) fn emit_facts<'tcx>( pub(crate) fn emit_facts<'tcx>(
all_facts: &mut Option<AllFacts>, facts: &mut Option<PoloniusFacts>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
body: &Body<'tcx>, body: &Body<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
universal_region_relations: &UniversalRegionRelations<'tcx>, universal_region_relations: &UniversalRegionRelations<'tcx>,
constraints: &MirTypeckRegionConstraints<'tcx>, constraints: &MirTypeckRegionConstraints<'tcx>,
) { ) {
let Some(facts) = all_facts else { let Some(facts) = facts else {
// We don't do anything if there are no facts to fill. // We don't do anything if there are no facts to fill.
return; return;
}; };
@ -67,9 +67,9 @@ pub(crate) fn emit_facts<'tcx>(
/// Emit facts needed for move/init analysis: moves and assignments. /// Emit facts needed for move/init analysis: moves and assignments.
fn emit_move_facts( fn emit_move_facts(
facts: &mut AllFacts, facts: &mut PoloniusFacts,
body: &Body<'_>, body: &Body<'_>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
move_data: &MoveData<'_>, move_data: &MoveData<'_>,
) { ) {
facts.path_is_var.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l))); facts.path_is_var.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
@ -139,7 +139,7 @@ fn emit_move_facts(
/// Emit universal regions facts, and their relations. /// Emit universal regions facts, and their relations.
fn emit_universal_region_facts( fn emit_universal_region_facts(
facts: &mut AllFacts, facts: &mut PoloniusFacts,
borrow_set: &BorrowSet<'_>, borrow_set: &BorrowSet<'_>,
universal_region_relations: &UniversalRegionRelations<'_>, universal_region_relations: &UniversalRegionRelations<'_>,
) { ) {
@ -187,10 +187,10 @@ pub(crate) fn emit_drop_facts<'tcx>(
local: Local, local: Local,
kind: &GenericArg<'tcx>, kind: &GenericArg<'tcx>,
universal_regions: &UniversalRegions<'tcx>, universal_regions: &UniversalRegions<'tcx>,
all_facts: &mut Option<AllFacts>, facts: &mut Option<PoloniusFacts>,
) { ) {
debug!("emit_drop_facts(local={:?}, kind={:?}", local, kind); debug!("emit_drop_facts(local={:?}, kind={:?}", local, kind);
let Some(facts) = all_facts.as_mut() else { return }; let Some(facts) = facts.as_mut() else { return };
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation"); let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
tcx.for_each_free_region(kind, |drop_live_region| { tcx.for_each_free_region(kind, |drop_live_region| {
let region_vid = universal_regions.to_region_vid(drop_live_region); let region_vid = universal_regions.to_region_vid(drop_live_region);
@ -201,8 +201,8 @@ pub(crate) fn emit_drop_facts<'tcx>(
/// Emit facts about the outlives constraints: the `subset` base relation, i.e. not a transitive /// Emit facts about the outlives constraints: the `subset` base relation, i.e. not a transitive
/// closure. /// closure.
fn emit_outlives_facts<'tcx>( fn emit_outlives_facts<'tcx>(
facts: &mut AllFacts, facts: &mut PoloniusFacts,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
constraints: &MirTypeckRegionConstraints<'tcx>, constraints: &MirTypeckRegionConstraints<'tcx>,
) { ) {
facts.subset_base.extend(constraints.outlives_constraints.outlives().iter().flat_map( facts.subset_base.extend(constraints.outlives_constraints.outlives().iter().flat_map(

View file

@ -392,7 +392,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
var_infos: VarInfos, var_infos: VarInfos,
constraints: MirTypeckRegionConstraints<'tcx>, constraints: MirTypeckRegionConstraints<'tcx>,
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
elements: Rc<DenseLocationMap>, location_map: Rc<DenseLocationMap>,
) -> Self { ) -> Self {
let universal_regions = &universal_region_relations.universal_regions; let universal_regions = &universal_region_relations.universal_regions;
let MirTypeckRegionConstraints { let MirTypeckRegionConstraints {
@ -436,7 +436,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
let mut scc_values = let mut scc_values =
RegionValues::new(elements, universal_regions.len(), placeholder_indices); RegionValues::new(location_map, 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);

View file

@ -38,7 +38,7 @@ pub(crate) enum RegionElement {
/// an interval matrix storing liveness ranges for each region-vid. /// an interval matrix storing liveness ranges for each region-vid.
pub(crate) struct LivenessValues { pub(crate) struct LivenessValues {
/// The map from locations to points. /// The map from locations to points.
elements: Rc<DenseLocationMap>, location_map: Rc<DenseLocationMap>,
/// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and /// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and
/// currently only used for validating promoteds (which don't care about more precise tracking). /// currently only used for validating promoteds (which don't care about more precise tracking).
@ -77,11 +77,11 @@ impl LiveLoans {
impl LivenessValues { impl LivenessValues {
/// Create an empty map of regions to locations where they're live. /// Create an empty map of regions to locations where they're live.
pub(crate) fn with_specific_points(elements: Rc<DenseLocationMap>) -> Self { pub(crate) fn with_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
LivenessValues { LivenessValues {
live_regions: None, live_regions: None,
points: Some(SparseIntervalMatrix::new(elements.num_points())), points: Some(SparseIntervalMatrix::new(location_map.num_points())),
elements, location_map,
loans: None, loans: None,
} }
} }
@ -90,11 +90,11 @@ impl LivenessValues {
/// ///
/// Unlike `with_specific_points`, does not track exact locations where something is live, only /// Unlike `with_specific_points`, does not track exact locations where something is live, only
/// which regions are live. /// which regions are live.
pub(crate) fn without_specific_points(elements: Rc<DenseLocationMap>) -> Self { pub(crate) fn without_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
LivenessValues { LivenessValues {
live_regions: Some(Default::default()), live_regions: Some(Default::default()),
points: None, points: None,
elements, location_map,
loans: None, loans: None,
} }
} }
@ -122,11 +122,11 @@ impl LivenessValues {
/// Records `region` as being live at the given `location`. /// Records `region` as being live at the given `location`.
pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) { pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
let point = self.elements.point_from_location(location); let point = self.location_map.point_from_location(location);
debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location); debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
if let Some(points) = &mut self.points { if let Some(points) = &mut self.points {
points.insert(region, point); points.insert(region, point);
} else if self.elements.point_in_range(point) { } else if self.location_map.point_in_range(point) {
self.live_regions.as_mut().unwrap().insert(region); self.live_regions.as_mut().unwrap().insert(region);
} }
@ -143,7 +143,7 @@ impl LivenessValues {
debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points); debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
if let Some(this) = &mut self.points { if let Some(this) = &mut self.points {
this.union_row(region, points); this.union_row(region, points);
} else if points.iter().any(|point| self.elements.point_in_range(point)) { } else if points.iter().any(|point| self.location_map.point_in_range(point)) {
self.live_regions.as_mut().unwrap().insert(region); self.live_regions.as_mut().unwrap().insert(region);
} }
@ -170,7 +170,7 @@ impl LivenessValues {
/// Returns whether `region` is marked live at the given `location`. /// Returns whether `region` is marked live at the given `location`.
pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool { pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool {
let point = self.elements.point_from_location(location); let point = self.location_map.point_from_location(location);
if let Some(points) = &self.points { if let Some(points) = &self.points {
points.row(region).is_some_and(|r| r.contains(point)) points.row(region).is_some_and(|r| r.contains(point))
} else { } else {
@ -191,25 +191,26 @@ impl LivenessValues {
.row(region) .row(region)
.into_iter() .into_iter()
.flat_map(|set| set.iter()) .flat_map(|set| set.iter())
.take_while(|&p| self.elements.point_in_range(p)) .take_while(|&p| self.location_map.point_in_range(p))
} }
/// For debugging purposes, returns a pretty-printed string of the points where the `region` is /// For debugging purposes, returns a pretty-printed string of the points where the `region` is
/// live. /// live.
pub(crate) fn pretty_print_live_points(&self, region: RegionVid) -> String { pub(crate) fn pretty_print_live_points(&self, region: RegionVid) -> String {
pretty_print_region_elements( pretty_print_region_elements(
self.live_points(region).map(|p| RegionElement::Location(self.elements.to_location(p))), self.live_points(region)
.map(|p| RegionElement::Location(self.location_map.to_location(p))),
) )
} }
#[inline] #[inline]
pub(crate) fn point_from_location(&self, location: Location) -> PointIndex { pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
self.elements.point_from_location(location) self.location_map.point_from_location(location)
} }
#[inline] #[inline]
pub(crate) fn location_from_point(&self, point: PointIndex) -> Location { pub(crate) fn location_from_point(&self, point: PointIndex) -> Location {
self.elements.to_location(point) self.location_map.to_location(point)
} }
/// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`. /// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`.
@ -272,7 +273,7 @@ impl PlaceholderIndices {
/// because (since it is returned) it must live for at least `'a`. But /// because (since it is returned) it must live for at least `'a`. But
/// it would also contain various points from within the function. /// it would also contain various points from within the function.
pub(crate) struct RegionValues<N: Idx> { pub(crate) struct RegionValues<N: Idx> {
elements: Rc<DenseLocationMap>, location_map: Rc<DenseLocationMap>,
placeholder_indices: PlaceholderIndices, placeholder_indices: PlaceholderIndices,
points: SparseIntervalMatrix<N, PointIndex>, points: SparseIntervalMatrix<N, PointIndex>,
free_regions: SparseBitMatrix<N, RegionVid>, free_regions: SparseBitMatrix<N, RegionVid>,
@ -287,14 +288,14 @@ 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>, location_map: Rc<DenseLocationMap>,
num_universal_regions: usize, num_universal_regions: usize,
placeholder_indices: PlaceholderIndices, placeholder_indices: PlaceholderIndices,
) -> Self { ) -> Self {
let num_points = elements.num_points(); let num_points = location_map.num_points();
let num_placeholders = placeholder_indices.len(); let num_placeholders = placeholder_indices.len();
Self { Self {
elements, location_map,
points: SparseIntervalMatrix::new(num_points), points: SparseIntervalMatrix::new(num_points),
placeholder_indices, placeholder_indices,
free_regions: SparseBitMatrix::new(num_universal_regions), free_regions: SparseBitMatrix::new(num_universal_regions),
@ -336,7 +337,7 @@ impl<N: Idx> RegionValues<N> {
end: usize, end: usize,
) -> Option<usize> { ) -> Option<usize> {
let row = self.points.row(r)?; let row = self.points.row(r)?;
let block = self.elements.entry_point(block); let block = self.location_map.entry_point(block);
let start = block.plus(start); let start = block.plus(start);
let end = block.plus(end); let end = block.plus(end);
let first_unset = row.first_unset_in(start..=end)?; let first_unset = row.first_unset_in(start..=end)?;
@ -375,8 +376,8 @@ impl<N: Idx> RegionValues<N> {
pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator<Item = Location> + 'a { pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator<Item = Location> + 'a {
self.points.row(r).into_iter().flat_map(move |set| { self.points.row(r).into_iter().flat_map(move |set| {
set.iter() set.iter()
.take_while(move |&p| self.elements.point_in_range(p)) .take_while(move |&p| self.location_map.point_in_range(p))
.map(move |p| self.elements.to_location(p)) .map(move |p| self.location_map.to_location(p))
}) })
} }
@ -430,12 +431,12 @@ pub(crate) trait ToElementIndex: Debug + Copy {
impl ToElementIndex for Location { impl ToElementIndex for Location {
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool { fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
let index = values.elements.point_from_location(self); let index = values.location_map.point_from_location(self);
values.points.insert(row, index) values.points.insert(row, index)
} }
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool { fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
let index = values.elements.point_from_location(self); let index = values.location_map.point_from_location(self);
values.points.contains(row, index) values.points.contains(row, index)
} }
} }
@ -464,14 +465,14 @@ impl ToElementIndex for ty::PlaceholderRegion {
/// For debugging purposes, returns a pretty-printed string of the given points. /// For debugging purposes, returns a pretty-printed string of the given points.
pub(crate) fn pretty_print_points( pub(crate) fn pretty_print_points(
elements: &DenseLocationMap, location_map: &DenseLocationMap,
points: impl IntoIterator<Item = PointIndex>, points: impl IntoIterator<Item = PointIndex>,
) -> String { ) -> String {
pretty_print_region_elements( pretty_print_region_elements(
points points
.into_iter() .into_iter()
.take_while(|&p| elements.point_in_range(p)) .take_while(|&p| location_map.point_in_range(p))
.map(|p| elements.to_location(p)) .map(|p| location_map.to_location(p))
.map(RegionElement::Location), .map(RegionElement::Location),
) )
} }

View file

@ -82,7 +82,7 @@ impl<'a> Iterator for AppearancesIter<'a> {
impl LocalUseMap { impl LocalUseMap {
pub(crate) fn build( pub(crate) fn build(
live_locals: &[Local], live_locals: &[Local],
elements: &DenseLocationMap, location_map: &DenseLocationMap,
body: &Body<'_>, body: &Body<'_>,
) -> Self { ) -> Self {
let nones = IndexVec::from_elem(None, &body.local_decls); let nones = IndexVec::from_elem(None, &body.local_decls);
@ -101,7 +101,7 @@ impl LocalUseMap {
IndexVec::from_elem(false, &body.local_decls); IndexVec::from_elem(false, &body.local_decls);
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true); live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data } LocalUseMapBuild { local_use_map: &mut local_use_map, location_map, locals_with_use_data }
.visit_body(body); .visit_body(body);
local_use_map local_use_map
@ -125,7 +125,7 @@ impl LocalUseMap {
struct LocalUseMapBuild<'me> { struct LocalUseMapBuild<'me> {
local_use_map: &'me mut LocalUseMap, local_use_map: &'me mut LocalUseMap,
elements: &'me DenseLocationMap, location_map: &'me DenseLocationMap,
// Vector used in `visit_local` to signal which `Local`s do we need // Vector used in `visit_local` to signal which `Local`s do we need
// def/use/drop information on, constructed from `live_locals` (that // def/use/drop information on, constructed from `live_locals` (that
@ -147,7 +147,7 @@ impl Visitor<'_> for LocalUseMapBuild<'_> {
DefUse::Use => &mut self.local_use_map.first_use_at[local], DefUse::Use => &mut self.local_use_map.first_use_at[local],
DefUse::Drop => &mut self.local_use_map.first_drop_at[local], DefUse::Drop => &mut self.local_use_map.first_drop_at[local],
}; };
let point_index = self.elements.point_from_location(location); let point_index = self.location_map.point_from_location(location);
let appearance_index = self let appearance_index = self
.local_use_map .local_use_map
.appearances .appearances

View file

@ -32,7 +32,7 @@ mod trace;
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: &DenseLocationMap, location_map: &DenseLocationMap,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
) { ) {
@ -49,7 +49,7 @@ pub(super) fn generate<'a, 'tcx>(
trace::trace( trace::trace(
typeck, typeck,
body, body,
elements, location_map,
flow_inits, flow_inits,
move_data, move_data,
relevant_live_locals, relevant_live_locals,

View file

@ -37,13 +37,13 @@ use crate::type_check::{NormalizeLocation, TypeChecker};
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: &DenseLocationMap, location_map: &DenseLocationMap,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>, relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>, boring_locals: Vec<Local>,
) { ) {
let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body); let local_use_map = &LocalUseMap::build(&relevant_live_locals, location_map, body);
// When using `-Zpolonius=next`, compute the set of loans that can reach a given region. // When using `-Zpolonius=next`, compute the set of loans that can reach a given region.
if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() { if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() {
@ -79,7 +79,7 @@ pub(super) fn trace<'a, 'tcx>(
typeck, typeck,
body, body,
flow_inits, flow_inits,
elements, location_map,
local_use_map, local_use_map,
move_data, move_data,
drop_data: FxIndexMap::default(), drop_data: FxIndexMap::default(),
@ -100,7 +100,7 @@ struct LivenessContext<'a, 'typeck, 'b, 'tcx> {
typeck: &'a mut TypeChecker<'typeck, 'tcx>, typeck: &'a mut TypeChecker<'typeck, 'tcx>,
/// Defines the `PointIndex` mapping /// Defines the `PointIndex` mapping
elements: &'a DenseLocationMap, location_map: &'a DenseLocationMap,
/// MIR we are analyzing. /// MIR we are analyzing.
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
@ -149,7 +149,7 @@ struct LivenessResults<'a, 'typeck, 'b, 'tcx> {
impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
fn new(cx: LivenessContext<'a, 'typeck, 'b, 'tcx>) -> Self { fn new(cx: LivenessContext<'a, 'typeck, 'b, 'tcx>) -> Self {
let num_points = cx.elements.num_points(); let num_points = cx.location_map.num_points();
LivenessResults { LivenessResults {
cx, cx,
defs: BitSet::new_empty(num_points), defs: BitSet::new_empty(num_points),
@ -213,14 +213,14 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) { fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) {
// This collect is more necessary than immediately apparent // This collect is more necessary than immediately apparent
// because these facts go into `add_drop_live_facts_for()`, // because these facts go into `add_drop_live_facts_for()`,
// which also writes to `all_facts`, and so this is genuinely // which also writes to `polonius_facts`, and so this is genuinely
// a simultaneous overlapping mutable borrow. // a simultaneous overlapping mutable borrow.
// FIXME for future hackers: investigate whether this is // FIXME for future hackers: investigate whether this is
// actually necessary; these facts come from Polonius // actually necessary; these facts come from Polonius
// and probably maybe plausibly does not need to go back in. // and probably maybe plausibly does not need to go back in.
// It may be necessary to just pick out the parts of // It may be necessary to just pick out the parts of
// `add_drop_live_facts_for()` that make sense. // `add_drop_live_facts_for()` that make sense.
let Some(facts) = self.cx.typeck.all_facts.as_ref() else { return }; let Some(facts) = self.cx.typeck.polonius_facts.as_ref() else { return };
let facts_to_add: Vec<_> = { let facts_to_add: Vec<_> = {
let relevant_live_locals: FxIndexSet<_> = let relevant_live_locals: FxIndexSet<_> =
relevant_live_locals.iter().copied().collect(); relevant_live_locals.iter().copied().collect();
@ -240,7 +240,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
.collect() .collect()
}; };
let live_at = IntervalSet::new(self.cx.elements.num_points()); let live_at = IntervalSet::new(self.cx.location_map.num_points());
for (local, local_ty, location) in facts_to_add { for (local, local_ty, location) in facts_to_add {
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &live_at); self.cx.add_drop_live_facts_for(local, local_ty, &[location], &live_at);
} }
@ -279,7 +279,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// * Inclusively, the block start // * Inclusively, the block start
// * Exclusively, the previous definition (if it's in this block) // * Exclusively, the previous definition (if it's in this block)
// * Exclusively, the previous live_at setting (an optimization) // * Exclusively, the previous live_at setting (an optimization)
let block_start = self.cx.elements.to_block_start(p); let block_start = self.cx.location_map.to_block_start(p);
let previous_defs = self.defs.last_set_in(block_start..=p); let previous_defs = self.defs.last_set_in(block_start..=p);
let previous_live_at = self.use_live_at.last_set_in(block_start..=p); let previous_live_at = self.use_live_at.last_set_in(block_start..=p);
@ -303,12 +303,12 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// terminators of predecessor basic blocks. Push those onto the // terminators of predecessor basic blocks. Push those onto the
// stack so that the next iteration(s) will process them. // stack so that the next iteration(s) will process them.
let block = self.cx.elements.to_location(block_start).block; let block = self.cx.location_map.to_location(block_start).block;
self.stack.extend( self.stack.extend(
self.cx.body.basic_blocks.predecessors()[block] self.cx.body.basic_blocks.predecessors()[block]
.iter() .iter()
.map(|&pred_bb| self.cx.body.terminator_loc(pred_bb)) .map(|&pred_bb| self.cx.body.terminator_loc(pred_bb))
.map(|pred_loc| self.cx.elements.point_from_location(pred_loc)), .map(|pred_loc| self.cx.location_map.point_from_location(pred_loc)),
); );
} }
} }
@ -331,7 +331,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// Find the drops where `local` is initialized. // Find the drops where `local` is initialized.
for drop_point in self.cx.local_use_map.drops(local) { for drop_point in self.cx.local_use_map.drops(local) {
let location = self.cx.elements.to_location(drop_point); let location = self.cx.location_map.to_location(drop_point);
debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,); debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
if self.cx.initialized_at_terminator(location.block, mpi) if self.cx.initialized_at_terminator(location.block, mpi)
@ -367,7 +367,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
debug!( debug!(
"compute_drop_live_points_for_block(mpi={:?}, term_point={:?})", "compute_drop_live_points_for_block(mpi={:?}, term_point={:?})",
self.cx.move_data.move_paths[mpi].place, self.cx.move_data.move_paths[mpi].place,
self.cx.elements.to_location(term_point), self.cx.location_map.to_location(term_point),
); );
// We are only invoked with terminators where `mpi` is // We are only invoked with terminators where `mpi` is
@ -377,12 +377,15 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// Otherwise, scan backwards through the statements in the // Otherwise, scan backwards through the statements in the
// block. One of them may be either a definition or use // block. One of them may be either a definition or use
// live point. // live point.
let term_location = self.cx.elements.to_location(term_point); let term_location = self.cx.location_map.to_location(term_point);
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,); debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
let block = term_location.block; let block = term_location.block;
let entry_point = self.cx.elements.entry_point(term_location.block); let entry_point = self.cx.location_map.entry_point(term_location.block);
for p in (entry_point..term_point).rev() { for p in (entry_point..term_point).rev() {
debug!("compute_drop_live_points_for_block: p = {:?}", self.cx.elements.to_location(p)); debug!(
"compute_drop_live_points_for_block: p = {:?}",
self.cx.location_map.to_location(p)
);
if self.defs.contains(p) { if self.defs.contains(p) {
debug!("compute_drop_live_points_for_block: def site"); debug!("compute_drop_live_points_for_block: def site");
@ -428,7 +431,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
} }
let pred_term_loc = self.cx.body.terminator_loc(pred_block); let pred_term_loc = self.cx.body.terminator_loc(pred_block);
let pred_term_point = self.cx.elements.point_from_location(pred_term_loc); let pred_term_point = self.cx.location_map.point_from_location(pred_term_loc);
// If the terminator of this predecessor either *assigns* // If the terminator of this predecessor either *assigns*
// our value or is a "normal use", then stop. // our value or is a "normal use", then stop.
@ -523,7 +526,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
/// points `live_at`. /// points `live_at`.
fn add_use_live_facts_for(&mut self, value: Ty<'tcx>, live_at: &IntervalSet<PointIndex>) { fn add_use_live_facts_for(&mut self, value: Ty<'tcx>, live_at: &IntervalSet<PointIndex>) {
debug!("add_use_live_facts_for(value={:?})", value); debug!("add_use_live_facts_for(value={:?})", value);
Self::make_all_regions_live(self.elements, self.typeck, value, live_at); Self::make_all_regions_live(self.location_map, self.typeck, value, live_at);
} }
/// Some variable with type `live_ty` is "drop live" at `location` /// Some variable with type `live_ty` is "drop live" at `location`
@ -547,7 +550,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
dropped_local, dropped_local,
dropped_ty, dropped_ty,
drop_locations, drop_locations,
values::pretty_print_points(self.elements, live_at.iter()), values::pretty_print_points(self.location_map, live_at.iter()),
); );
let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({
@ -574,19 +577,19 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
// All things in the `outlives` array may be touched by // All things in the `outlives` array may be touched by
// the destructor and must be live at this point. // the destructor and must be live at this point.
for &kind in &drop_data.dropck_result.kinds { for &kind in &drop_data.dropck_result.kinds {
Self::make_all_regions_live(self.elements, self.typeck, kind, live_at); Self::make_all_regions_live(self.location_map, self.typeck, kind, live_at);
polonius::legacy::emit_drop_facts( polonius::legacy::emit_drop_facts(
self.typeck.tcx(), self.typeck.tcx(),
dropped_local, dropped_local,
&kind, &kind,
self.typeck.universal_regions, self.typeck.universal_regions,
self.typeck.all_facts, self.typeck.polonius_facts,
); );
} }
} }
fn make_all_regions_live( fn make_all_regions_live(
elements: &DenseLocationMap, location_map: &DenseLocationMap,
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
value: impl TypeVisitable<TyCtxt<'tcx>> + Relate<TyCtxt<'tcx>>, value: impl TypeVisitable<TyCtxt<'tcx>> + Relate<TyCtxt<'tcx>>,
live_at: &IntervalSet<PointIndex>, live_at: &IntervalSet<PointIndex>,
@ -594,7 +597,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
debug!("make_all_regions_live(value={:?})", value); debug!("make_all_regions_live(value={:?})", value);
debug!( debug!(
"make_all_regions_live: live_at={}", "make_all_regions_live: live_at={}",
values::pretty_print_points(elements, live_at.iter()), values::pretty_print_points(location_map, live_at.iter()),
); );
value.visit_with(&mut for_liveness::FreeRegionsVisitor { value.visit_with(&mut for_liveness::FreeRegionsVisitor {

View file

@ -49,7 +49,7 @@ use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet};
use crate::diagnostics::UniverseInfo; use crate::diagnostics::UniverseInfo;
use crate::member_constraints::MemberConstraintSet; use crate::member_constraints::MemberConstraintSet;
use crate::polonius::PoloniusContext; use crate::polonius::PoloniusContext;
use crate::polonius::legacy::{AllFacts, LocationTable}; use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable};
use crate::region_infer::TypeTest; use crate::region_infer::TypeTest;
use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices};
use crate::renumber::RegionCtxt; use crate::renumber::RegionCtxt;
@ -98,29 +98,29 @@ mod relate_tys;
/// - `body` -- MIR body to type-check /// - `body` -- MIR body to type-check
/// - `promoted` -- map of promoted constants within `body` /// - `promoted` -- map of promoted constants within `body`
/// - `universal_regions` -- the universal regions from `body`s function signature /// - `universal_regions` -- the universal regions from `body`s function signature
/// - `location_table` -- MIR location map of `body` /// - `location_table` -- for datalog polonius, the map between `Location`s and `RichLocation`s
/// - `borrow_set` -- information about borrows occurring in `body` /// - `borrow_set` -- information about borrows occurring in `body`
/// - `all_facts` -- when using Polonius, this is the generated set of Polonius facts /// - `polonius_facts` -- when using Polonius, this is the generated set of Polonius facts
/// - `flow_inits` -- results of a maybe-init dataflow analysis /// - `flow_inits` -- results of a maybe-init dataflow analysis
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
/// - `elements` -- MIR region map /// - `location_map` -- map between MIR `Location` and `PointIndex`
pub(crate) fn type_check<'a, 'tcx>( pub(crate) fn type_check<'a, 'tcx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
universal_regions: UniversalRegions<'tcx>, universal_regions: UniversalRegions<'tcx>,
location_table: &LocationTable, location_table: &PoloniusLocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>, polonius_facts: &mut Option<PoloniusFacts>,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
elements: Rc<DenseLocationMap>, location_map: Rc<DenseLocationMap>,
) -> 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);
let mut constraints = MirTypeckRegionConstraints { let mut constraints = MirTypeckRegionConstraints {
placeholder_indices: PlaceholderIndices::default(), placeholder_indices: PlaceholderIndices::default(),
placeholder_index_to_region: IndexVec::default(), placeholder_index_to_region: IndexVec::default(),
liveness_constraints: LivenessValues::with_specific_points(Rc::clone(&elements)), liveness_constraints: LivenessValues::with_specific_points(Rc::clone(&location_map)),
outlives_constraints: OutlivesConstraintSet::default(), outlives_constraints: OutlivesConstraintSet::default(),
member_constraints: MemberConstraintSet::default(), member_constraints: MemberConstraintSet::default(),
type_tests: Vec::default(), type_tests: Vec::default(),
@ -165,7 +165,7 @@ pub(crate) fn type_check<'a, 'tcx>(
reported_errors: Default::default(), reported_errors: Default::default(),
universal_regions: &universal_region_relations.universal_regions, universal_regions: &universal_region_relations.universal_regions,
location_table, location_table,
all_facts, polonius_facts,
borrow_set, borrow_set,
constraints: &mut constraints, constraints: &mut constraints,
polonius_context: &mut polonius_context, polonius_context: &mut polonius_context,
@ -180,7 +180,7 @@ pub(crate) fn type_check<'a, 'tcx>(
typeck.equate_inputs_and_outputs(body, &normalized_inputs_and_output); typeck.equate_inputs_and_outputs(body, &normalized_inputs_and_output);
typeck.check_signature_annotation(body); typeck.check_signature_annotation(body);
liveness::generate(&mut typeck, body, &elements, flow_inits, move_data); liveness::generate(&mut typeck, body, &location_map, flow_inits, move_data);
let opaque_type_values = let opaque_type_values =
opaque_types::take_opaques_and_register_member_constraints(&mut typeck); opaque_types::take_opaques_and_register_member_constraints(&mut typeck);
@ -495,14 +495,14 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
// Use new sets of constraints and closure bounds so that we can // Use new sets of constraints and closure bounds so that we can
// modify their locations. // modify their locations.
let all_facts = &mut None; let polonius_facts = &mut None;
let mut constraints = Default::default(); let mut constraints = Default::default();
let mut liveness_constraints = let mut liveness_constraints =
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body))); LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR // Don't try to add borrow_region facts for the promoted MIR
let mut swap_constraints = |this: &mut Self| { let mut swap_constraints = |this: &mut Self| {
mem::swap(this.typeck.all_facts, all_facts); mem::swap(this.typeck.polonius_facts, polonius_facts);
mem::swap(&mut this.typeck.constraints.outlives_constraints, &mut constraints); mem::swap(&mut this.typeck.constraints.outlives_constraints, &mut constraints);
mem::swap(&mut this.typeck.constraints.liveness_constraints, &mut liveness_constraints); mem::swap(&mut this.typeck.constraints.liveness_constraints, &mut liveness_constraints);
}; };
@ -560,8 +560,8 @@ struct TypeChecker<'a, 'tcx> {
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
universal_regions: &'a UniversalRegions<'tcx>, universal_regions: &'a UniversalRegions<'tcx>,
location_table: &'a LocationTable, location_table: &'a PoloniusLocationTable,
all_facts: &'a mut Option<AllFacts>, polonius_facts: &'a mut Option<PoloniusFacts>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
/// When using `-Zpolonius=next`, the helper data used to create polonius constraints. /// When using `-Zpolonius=next`, the helper data used to create polonius constraints.
@ -2341,18 +2341,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
borrowed_place: &Place<'tcx>, borrowed_place: &Place<'tcx>,
) { ) {
// These constraints are only meaningful during borrowck: // These constraints are only meaningful during borrowck:
let Self { borrow_set, location_table, all_facts, constraints, .. } = self; let Self { borrow_set, location_table, polonius_facts, constraints, .. } = self;
// In Polonius mode, we also push a `loan_issued_at` fact // In Polonius mode, we also push a `loan_issued_at` fact
// linking the loan to the region (in some cases, though, // linking the loan to the region (in some cases, though,
// there is no loan associated with this borrow expression -- // there is no loan associated with this borrow expression --
// that occurs when we are borrowing an unsafe place, for // that occurs when we are borrowing an unsafe place, for
// example). // example).
if let Some(all_facts) = all_facts { if let Some(polonius_facts) = polonius_facts {
let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
if let Some(borrow_index) = borrow_set.get_index_of(&location) { if let Some(borrow_index) = borrow_set.get_index_of(&location) {
let region_vid = borrow_region.as_var(); let region_vid = borrow_region.as_var();
all_facts.loan_issued_at.push(( polonius_facts.loan_issued_at.push((
region_vid.into(), region_vid.into(),
borrow_index, borrow_index,
location_table.mid_index(location), location_table.mid_index(location),