@@ -42,12 +42,14 @@ use self::diagnostics::{AccessKind, RegionName};
4242use self :: location:: LocationTable ;
4343use self :: prefixes:: PrefixSet ;
4444use self :: MutateMode :: { JustWrite , WriteAndRead } ;
45+ use facts:: AllFacts ;
4546
4647use self :: path_utils:: * ;
4748
4849mod borrow_set;
4950mod constraint_generation;
5051mod constraints;
52+ pub mod consumers;
5153mod def_use;
5254mod diagnostics;
5355mod facts;
@@ -108,22 +110,33 @@ fn mir_borrowck<'tcx>(
108110 let opt_closure_req = tcx. infer_ctxt ( ) . enter ( |infcx| {
109111 let input_body: & Body < ' _ > = & input_body. borrow ( ) ;
110112 let promoted: & IndexVec < _ , _ > = & promoted. borrow ( ) ;
111- do_mir_borrowck ( & infcx, input_body, promoted)
113+ do_mir_borrowck ( & infcx, input_body, promoted, false ) . 0
112114 } ) ;
113115 debug ! ( "mir_borrowck done" ) ;
114116
115117 tcx. arena . alloc ( opt_closure_req)
116118}
117119
120+ /// Perform the actual borrow checking.
121+ ///
122+ /// If `return_body_with_facts` is true, then return the body with non-erased
123+ /// region ids on which the borrow checking was performed together with Polonius
124+ /// facts.
118125fn do_mir_borrowck < ' a , ' tcx > (
119126 infcx : & InferCtxt < ' a , ' tcx > ,
120127 input_body : & Body < ' tcx > ,
121128 input_promoted : & IndexVec < Promoted , Body < ' tcx > > ,
122- ) -> BorrowCheckResult < ' tcx > {
129+ return_body_with_facts : bool ,
130+ ) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
123131 let def = input_body. source . with_opt_param ( ) . as_local ( ) . unwrap ( ) ;
124132
125133 debug ! ( "do_mir_borrowck(def = {:?})" , def) ;
126134
135+ assert ! (
136+ !return_body_with_facts || infcx. tcx. sess. opts. debugging_opts. polonius,
137+ "borrowck facts can be requested only when Polonius is enabled"
138+ ) ;
139+
127140 let tcx = infcx. tcx ;
128141 let param_env = tcx. param_env ( def. did ) ;
129142 let id = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ;
@@ -169,12 +182,14 @@ fn do_mir_borrowck<'a, 'tcx>(
169182 // requires first making our own copy of the MIR. This copy will
170183 // be modified (in place) to contain non-lexical lifetimes. It
171184 // will have a lifetime tied to the inference context.
172- let mut body = input_body. clone ( ) ;
185+ let mut body_owned = input_body. clone ( ) ;
173186 let mut promoted = input_promoted. clone ( ) ;
174- let free_regions = nll:: replace_regions_in_mir ( infcx, param_env, & mut body, & mut promoted) ;
175- let body = & body; // no further changes
187+ let free_regions =
188+ nll:: replace_regions_in_mir ( infcx, param_env, & mut body_owned, & mut promoted) ;
189+ let body = & body_owned; // no further changes
176190
177- let location_table = & LocationTable :: new ( & body) ;
191+ let location_table_owned = LocationTable :: new ( body) ;
192+ let location_table = & location_table_owned;
178193
179194 let mut errors_buffer = Vec :: new ( ) ;
180195 let ( move_data, move_errors) : ( MoveData < ' tcx > , Vec < ( Place < ' tcx > , MoveError < ' tcx > ) > ) =
@@ -202,6 +217,7 @@ fn do_mir_borrowck<'a, 'tcx>(
202217 let nll:: NllOutput {
203218 regioncx,
204219 opaque_type_values,
220+ polonius_input,
205221 polonius_output,
206222 opt_closure_req,
207223 nll_errors,
@@ -446,9 +462,37 @@ fn do_mir_borrowck<'a, 'tcx>(
446462 used_mut_upvars : mbcx. used_mut_upvars ,
447463 } ;
448464
465+ let body_with_facts = if return_body_with_facts {
466+ let output_facts = mbcx. polonius_output . expect ( "Polonius output was not computed" ) ;
467+ Some ( box BodyWithBorrowckFacts {
468+ body : body_owned,
469+ input_facts : * polonius_input. expect ( "Polonius input facts were not generated" ) ,
470+ output_facts,
471+ location_table : location_table_owned,
472+ } )
473+ } else {
474+ None
475+ } ;
476+
449477 debug ! ( "do_mir_borrowck: result = {:#?}" , result) ;
450478
451- result
479+ ( result, body_with_facts)
480+ }
481+
482+ /// A `Body` with information computed by the borrow checker. This struct is
483+ /// intended to be consumed by compiler consumers.
484+ ///
485+ /// We need to include the MIR body here because the region identifiers must
486+ /// match the ones in the Polonius facts.
487+ pub struct BodyWithBorrowckFacts < ' tcx > {
488+ /// A mir body that contains region identifiers.
489+ pub body : Body < ' tcx > ,
490+ /// Polonius input facts.
491+ pub input_facts : AllFacts ,
492+ /// Polonius output facts.
493+ pub output_facts : Rc < self :: nll:: PoloniusOutput > ,
494+ /// The table that maps Polonius points to locations in the table.
495+ pub location_table : LocationTable ,
452496}
453497
454498crate struct MirBorrowckCtxt < ' cx , ' tcx > {
0 commit comments