3
3
//! This file provides API for compiler consumers.
4
4
5
5
use rustc_hir:: def_id:: LocalDefId ;
6
- use rustc_index:: IndexSlice ;
6
+ use rustc_index:: { IndexSlice , IndexVec } ;
7
7
use rustc_infer:: infer:: { DefiningAnchor , TyCtxtInferExt } ;
8
- use rustc_middle:: mir:: Body ;
8
+ use rustc_middle:: mir:: { Body , Promoted } ;
9
9
use rustc_middle:: ty:: TyCtxt ;
10
+ use std:: rc:: Rc ;
11
+
12
+ use crate :: borrow_set:: BorrowSet ;
10
13
11
14
pub use super :: {
15
+ constraints:: OutlivesConstraint ,
16
+ dataflow:: { calculate_borrows_out_of_scope_at_location, BorrowIndex , Borrows } ,
12
17
facts:: { AllFacts as PoloniusInput , RustcFacts } ,
13
18
location:: { LocationTable , RichLocation } ,
14
19
nll:: PoloniusOutput ,
15
- BodyWithBorrowckFacts ,
20
+ place_ext:: PlaceExt ,
21
+ places_conflict:: { places_conflict, PlaceConflictBias } ,
22
+ region_infer:: RegionInferenceContext ,
16
23
} ;
17
24
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`].
22
95
///
23
96
/// Note:
24
97
/// * This function will panic if the required body was already stolen. This
@@ -28,10 +101,14 @@ pub use super::{
28
101
/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
29
102
///
30
103
/// * 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 < ' _ > {
32
109
let ( input_body, promoted) = tcx. mir_promoted ( def) ;
33
110
let infcx = tcx. infer_ctxt ( ) . with_opaque_type_inference ( DefiningAnchor :: Bind ( def) ) . build ( ) ;
34
111
let input_body: & Body < ' _ > = & input_body. borrow ( ) ;
35
112
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 ( )
37
114
}
0 commit comments