33//! This file provides API for compiler consumers.
44
55use rustc_hir:: def_id:: LocalDefId ;
6- use rustc_index:: IndexSlice ;
6+ use rustc_index:: { IndexSlice , IndexVec } ;
77use rustc_infer:: infer:: { DefiningAnchor , TyCtxtInferExt } ;
8- use rustc_middle:: mir:: Body ;
8+ use rustc_middle:: mir:: { Body , Promoted } ;
99use rustc_middle:: ty:: TyCtxt ;
10+ use std:: rc:: Rc ;
11+
12+ use crate :: borrow_set:: BorrowSet ;
1013
1114pub use super :: {
15+ constraints:: OutlivesConstraint ,
16+ dataflow:: { calculate_borrows_out_of_scope_at_location, BorrowIndex , Borrows } ,
1217 facts:: { AllFacts as PoloniusInput , RustcFacts } ,
1318 location:: { LocationTable , RichLocation } ,
1419 nll:: PoloniusOutput ,
15- BodyWithBorrowckFacts ,
20+ place_ext:: PlaceExt ,
21+ places_conflict:: { places_conflict, PlaceConflictBias } ,
22+ region_infer:: RegionInferenceContext ,
1623} ;
1724
18- /// This function computes Polonius facts for the given body. It makes a copy of
19- /// the body because it needs to regenerate the region identifiers. This function
20- /// should never be invoked during a typical compilation session due to performance
21- /// issues with Polonius.
25+ /// Options determining the output behavior of [`get_body_with_borrowck_facts`].
26+ ///
27+ /// If executing under `-Z polonius` the choice here has no effect, and everything as if
28+ /// [`PoloniusOutputFacts`](ConsumerOptions::PoloniusOutputFacts) had been selected
29+ /// will be retrieved.
30+ #[ derive( Debug , Copy , Clone ) ]
31+ pub enum ConsumerOptions {
32+ /// Retrieve the [`Body`] along with the [`BorrowSet`](super::borrow_set::BorrowSet)
33+ /// and [`RegionInferenceContext`]. If you would like the body only, use
34+ /// [`TyCtxt::mir_promoted`].
35+ ///
36+ /// These can be used in conjunction with [`calculate_borrows_out_of_scope_at_location`].
37+ RegionInferenceContext ,
38+ /// The recommended option. Retrieves the maximal amount of information
39+ /// without significant slowdowns.
40+ ///
41+ /// Implies [`RegionInferenceContext`](ConsumerOptions::RegionInferenceContext),
42+ /// and additionally retrieve the [`LocationTable`] and [`PoloniusInput`] that
43+ /// would be given to Polonius. Critically, this does not run Polonius, which
44+ /// one may want to avoid due to performance issues on large bodies.
45+ PoloniusInputFacts ,
46+ /// Implies [`PoloniusInputFacts`](ConsumerOptions::PoloniusInputFacts),
47+ /// and additionally runs Polonius to calculate the [`PoloniusOutput`].
48+ PoloniusOutputFacts ,
49+ }
50+
51+ impl ConsumerOptions {
52+ /// Should the Polonius input facts be computed?
53+ pub ( crate ) fn polonius_input ( & self ) -> bool {
54+ matches ! ( self , Self :: PoloniusInputFacts | Self :: PoloniusOutputFacts )
55+ }
56+ /// Should we run Polonius and collect the output facts?
57+ pub ( crate ) fn polonius_output ( & self ) -> bool {
58+ matches ! ( self , Self :: PoloniusOutputFacts )
59+ }
60+ }
61+
62+ /// A `Body` with information computed by the borrow checker. This struct is
63+ /// intended to be consumed by compiler consumers.
64+ ///
65+ /// We need to include the MIR body here because the region identifiers must
66+ /// match the ones in the Polonius facts.
67+ pub struct BodyWithBorrowckFacts < ' tcx > {
68+ /// A mir body that contains region identifiers.
69+ pub body : Body < ' tcx > ,
70+ /// The mir bodies of promoteds.
71+ pub promoted : IndexVec < Promoted , Body < ' tcx > > ,
72+ /// The set of borrows occurring in `body` with data about them.
73+ pub borrow_set : Rc < BorrowSet < ' tcx > > ,
74+ /// Context generated during borrowck, intended to be passed to
75+ /// [`calculate_borrows_out_of_scope_at_location`].
76+ pub region_inference_context : Rc < RegionInferenceContext < ' tcx > > ,
77+ /// The table that maps Polonius points to locations in the table.
78+ /// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
79+ /// or [`ConsumerOptions::PoloniusOutputFacts`].
80+ pub location_table : Option < LocationTable > ,
81+ /// Polonius input facts.
82+ /// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
83+ /// or [`ConsumerOptions::PoloniusOutputFacts`].
84+ pub input_facts : Option < Box < PoloniusInput > > ,
85+ /// Polonius output facts. Populated when using
86+ /// [`ConsumerOptions::PoloniusOutputFacts`].
87+ pub output_facts : Option < Rc < PoloniusOutput > > ,
88+ }
89+
90+ /// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
91+ /// determine which facts are returned. This function makes a copy of the body because
92+ /// it needs to regenerate the region identifiers. It should never be invoked during a
93+ /// typical compilation session due to the unnecessary overhead of returning
94+ /// [`BodyWithBorrowckFacts`].
2295///
2396/// Note:
2497/// * This function will panic if the required body was already stolen. This
@@ -28,10 +101,14 @@ pub use super::{
28101/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
29102///
30103/// * Polonius is highly unstable, so expect regular changes in its signature or other details.
31- pub fn get_body_with_borrowck_facts ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> BodyWithBorrowckFacts < ' _ > {
104+ pub fn get_body_with_borrowck_facts (
105+ tcx : TyCtxt < ' _ > ,
106+ def : LocalDefId ,
107+ options : ConsumerOptions ,
108+ ) -> BodyWithBorrowckFacts < ' _ > {
32109 let ( input_body, promoted) = tcx. mir_promoted ( def) ;
33110 let infcx = tcx. infer_ctxt ( ) . with_opaque_type_inference ( DefiningAnchor :: Bind ( def) ) . build ( ) ;
34111 let input_body: & Body < ' _ > = & input_body. borrow ( ) ;
35112 let promoted: & IndexSlice < _ , _ > = & promoted. borrow ( ) ;
36- * super :: do_mir_borrowck ( & infcx, input_body, promoted, true ) . 1 . unwrap ( )
113+ * super :: do_mir_borrowck ( & infcx, input_body, promoted, Some ( options ) ) . 1 . unwrap ( )
37114}
0 commit comments