diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /compiler/rustc_borrowck/src/consumers.rs | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/consumers.rs')
-rw-r--r-- | compiler/rustc_borrowck/src/consumers.rs | 99 |
1 files changed, 87 insertions, 12 deletions
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index cb1a65222..d25714537 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -3,22 +3,96 @@ //! This file provides API for compiler consumers. use rustc_hir::def_id::LocalDefId; -use rustc_index::vec::IndexSlice; -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; -use rustc_middle::mir::Body; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_index::{IndexSlice, IndexVec}; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::mir::{Body, Promoted}; +use rustc_middle::traits::DefiningAnchor; +use rustc_middle::ty::TyCtxt; +use std::rc::Rc; + +use crate::borrow_set::BorrowSet; pub use super::{ + constraints::OutlivesConstraint, + dataflow::{calculate_borrows_out_of_scope_at_location, BorrowIndex, Borrows}, facts::{AllFacts as PoloniusInput, RustcFacts}, location::{LocationTable, RichLocation}, nll::PoloniusOutput, - BodyWithBorrowckFacts, + place_ext::PlaceExt, + places_conflict::{places_conflict, PlaceConflictBias}, + region_infer::RegionInferenceContext, }; -/// This function computes Polonius facts for the given body. It makes a copy of -/// the body because it needs to regenerate the region identifiers. This function -/// should never be invoked during a typical compilation session due to performance -/// issues with Polonius. +/// Options determining the output behavior of [`get_body_with_borrowck_facts`]. +/// +/// If executing under `-Z polonius` the choice here has no effect, and everything as if +/// [`PoloniusOutputFacts`](ConsumerOptions::PoloniusOutputFacts) had been selected +/// will be retrieved. +#[derive(Debug, Copy, Clone)] +pub enum ConsumerOptions { + /// Retrieve the [`Body`] along with the [`BorrowSet`](super::borrow_set::BorrowSet) + /// and [`RegionInferenceContext`]. If you would like the body only, use + /// [`TyCtxt::mir_promoted`]. + /// + /// These can be used in conjunction with [`calculate_borrows_out_of_scope_at_location`]. + RegionInferenceContext, + /// The recommended option. Retrieves the maximal amount of information + /// without significant slowdowns. + /// + /// Implies [`RegionInferenceContext`](ConsumerOptions::RegionInferenceContext), + /// and additionally retrieve the [`LocationTable`] and [`PoloniusInput`] that + /// would be given to Polonius. Critically, this does not run Polonius, which + /// one may want to avoid due to performance issues on large bodies. + PoloniusInputFacts, + /// Implies [`PoloniusInputFacts`](ConsumerOptions::PoloniusInputFacts), + /// and additionally runs Polonius to calculate the [`PoloniusOutput`]. + PoloniusOutputFacts, +} + +impl ConsumerOptions { + /// Should the Polonius input facts be computed? + pub(crate) fn polonius_input(&self) -> bool { + matches!(self, Self::PoloniusInputFacts | Self::PoloniusOutputFacts) + } + /// Should we run Polonius and collect the output facts? + pub(crate) fn polonius_output(&self) -> bool { + matches!(self, Self::PoloniusOutputFacts) + } +} + +/// A `Body` with information computed by the borrow checker. This struct is +/// intended to be consumed by compiler consumers. +/// +/// We need to include the MIR body here because the region identifiers must +/// match the ones in the Polonius facts. +pub struct BodyWithBorrowckFacts<'tcx> { + /// A mir body that contains region identifiers. + pub body: Body<'tcx>, + /// The mir bodies of promoteds. + pub promoted: IndexVec<Promoted, Body<'tcx>>, + /// The set of borrows occurring in `body` with data about them. + pub borrow_set: Rc<BorrowSet<'tcx>>, + /// Context generated during borrowck, intended to be passed to + /// [`calculate_borrows_out_of_scope_at_location`]. + pub region_inference_context: Rc<RegionInferenceContext<'tcx>>, + /// The table that maps Polonius points to locations in the table. + /// Populated when using [`ConsumerOptions::PoloniusInputFacts`] + /// or [`ConsumerOptions::PoloniusOutputFacts`]. + pub location_table: Option<LocationTable>, + /// Polonius input facts. + /// Populated when using [`ConsumerOptions::PoloniusInputFacts`] + /// or [`ConsumerOptions::PoloniusOutputFacts`]. + pub input_facts: Option<Box<PoloniusInput>>, + /// Polonius output facts. Populated when using + /// [`ConsumerOptions::PoloniusOutputFacts`]. + pub output_facts: Option<Rc<PoloniusOutput>>, +} + +/// This function computes borrowck facts for the given body. The [`ConsumerOptions`] +/// determine which facts are returned. This function makes a copy of the body because +/// it needs to regenerate the region identifiers. It should never be invoked during a +/// typical compilation session due to the unnecessary overhead of returning +/// [`BodyWithBorrowckFacts`]. /// /// Note: /// * This function will panic if the required body was already stolen. This @@ -30,11 +104,12 @@ pub use super::{ /// * Polonius is highly unstable, so expect regular changes in its signature or other details. pub fn get_body_with_borrowck_facts( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, + options: ConsumerOptions, ) -> BodyWithBorrowckFacts<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build(); + let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexSlice<_, _> = &promoted.borrow(); - *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() + *super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap() } |