]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_borrowck/src/consumers.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_borrowck / src / consumers.rs
index cb1a65222237096efe7c715c369d2aedd4cad3eb..d257145373f72e9a562c4f7802771b966387c2d0 100644 (file)
@@ -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()
 }