use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use crate::rustc_data_structures::fx::FxHashMap;
use crate::rustc_hir::def_id::LocalDefId;
use crate::rustc_index::IndexVec;
use crate::bug;
use crate::rustc_middle::mir::{Body, Promoted};
use crate::rustc_middle::ty::TyCtxt;
pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
pub use super::constraints::OutlivesConstraint;
pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location};
pub use super::place_ext::PlaceExt;
pub use super::places_conflict::{PlaceConflictBias, places_conflict};
pub use super::polonius::legacy::{
PoloniusFacts as PoloniusInput, PoloniusLocationTable, PoloniusOutput, PoloniusRegionVid,
RichLocation, RustcFacts,
};
pub use super::region_infer::RegionInferenceContext;
use crate::rustc_borrowck::BorrowCheckRootCtxt;
pub(crate) struct BorrowckConsumer<'tcx> {
options: ConsumerOptions,
bodies: FxHashMap<LocalDefId, BodyWithBorrowckFacts<'tcx>>,
}
impl<'tcx> BorrowckConsumer<'tcx> {
pub(crate) fn new(options: ConsumerOptions) -> Self {
Self { options, bodies: Default::default() }
}
pub(crate) fn insert_body(&mut self, def_id: LocalDefId, body: BodyWithBorrowckFacts<'tcx>) {
if self.bodies.insert(def_id, body).is_some() {
bug!("unexpected previous body for {def_id:?}");
}
}
pub(crate) fn polonius_input(&self) -> bool {
matches!(
self.options,
ConsumerOptions::PoloniusInputFacts | ConsumerOptions::PoloniusOutputFacts
)
}
pub(crate) fn polonius_output(&self) -> bool {
matches!(self.options, ConsumerOptions::PoloniusOutputFacts)
}
}
#[derive(Debug, Copy, Clone)]
pub enum ConsumerOptions {
RegionInferenceContext,
PoloniusInputFacts,
PoloniusOutputFacts,
}
pub struct BodyWithBorrowckFacts<'tcx> {
pub body: Body<'tcx>,
pub promoted: IndexVec<Promoted, Body<'tcx>>,
pub borrow_set: BorrowSet<'tcx>,
pub region_inference_context: RegionInferenceContext<'tcx>,
pub location_table: Option<PoloniusLocationTable>,
pub input_facts: Option<Box<PoloniusInput>>,
pub output_facts: Option<Box<PoloniusOutput>>,
}
pub fn get_bodies_with_borrowck_facts(
tcx: TyCtxt<'_>,
root_def_id: LocalDefId,
options: ConsumerOptions,
) -> FxHashMap<LocalDefId, BodyWithBorrowckFacts<'_>> {
let tainted_by_errors = Default::default();
let mut root_cx = BorrowCheckRootCtxt::new(
tcx,
root_def_id,
Some(BorrowckConsumer::new(options)),
&tainted_by_errors,
);
root_cx.do_mir_borrowck();
root_cx.consumer.unwrap().bodies
}