@@ -42,12 +42,14 @@ use self::diagnostics::{AccessKind, RegionName};
42
42
use self :: location:: LocationTable ;
43
43
use self :: prefixes:: PrefixSet ;
44
44
use self :: MutateMode :: { JustWrite , WriteAndRead } ;
45
+ use facts:: AllFacts ;
45
46
46
47
use self :: path_utils:: * ;
47
48
48
49
mod borrow_set;
49
50
mod constraint_generation;
50
51
mod constraints;
52
+ pub mod consumers;
51
53
mod def_use;
52
54
mod diagnostics;
53
55
mod facts;
@@ -108,22 +110,33 @@ fn mir_borrowck<'tcx>(
108
110
let opt_closure_req = tcx. infer_ctxt ( ) . enter ( |infcx| {
109
111
let input_body: & Body < ' _ > = & input_body. borrow ( ) ;
110
112
let promoted: & IndexVec < _ , _ > = & promoted. borrow ( ) ;
111
- do_mir_borrowck ( & infcx, input_body, promoted)
113
+ do_mir_borrowck ( & infcx, input_body, promoted, false ) . 0
112
114
} ) ;
113
115
debug ! ( "mir_borrowck done" ) ;
114
116
115
117
tcx. arena . alloc ( opt_closure_req)
116
118
}
117
119
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.
118
125
fn do_mir_borrowck < ' a , ' tcx > (
119
126
infcx : & InferCtxt < ' a , ' tcx > ,
120
127
input_body : & Body < ' tcx > ,
121
128
input_promoted : & IndexVec < Promoted , Body < ' tcx > > ,
122
- ) -> BorrowCheckResult < ' tcx > {
129
+ return_body_with_facts : bool ,
130
+ ) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
123
131
let def = input_body. source . with_opt_param ( ) . as_local ( ) . unwrap ( ) ;
124
132
125
133
debug ! ( "do_mir_borrowck(def = {:?})" , def) ;
126
134
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
+
127
140
let tcx = infcx. tcx ;
128
141
let param_env = tcx. param_env ( def. did ) ;
129
142
let id = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ;
@@ -169,12 +182,14 @@ fn do_mir_borrowck<'a, 'tcx>(
169
182
// requires first making our own copy of the MIR. This copy will
170
183
// be modified (in place) to contain non-lexical lifetimes. It
171
184
// will have a lifetime tied to the inference context.
172
- let mut body = input_body. clone ( ) ;
185
+ let mut body_owned = input_body. clone ( ) ;
173
186
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
176
190
177
- let location_table = & LocationTable :: new ( & body) ;
191
+ let location_table_owned = LocationTable :: new ( body) ;
192
+ let location_table = & location_table_owned;
178
193
179
194
let mut errors_buffer = Vec :: new ( ) ;
180
195
let ( move_data, move_errors) : ( MoveData < ' tcx > , Vec < ( Place < ' tcx > , MoveError < ' tcx > ) > ) =
@@ -202,6 +217,7 @@ fn do_mir_borrowck<'a, 'tcx>(
202
217
let nll:: NllOutput {
203
218
regioncx,
204
219
opaque_type_values,
220
+ polonius_input,
205
221
polonius_output,
206
222
opt_closure_req,
207
223
nll_errors,
@@ -446,9 +462,37 @@ fn do_mir_borrowck<'a, 'tcx>(
446
462
used_mut_upvars : mbcx. used_mut_upvars ,
447
463
} ;
448
464
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
+
449
477
debug ! ( "do_mir_borrowck: result = {:#?}" , result) ;
450
478
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 ,
452
496
}
453
497
454
498
crate struct MirBorrowckCtxt < ' cx , ' tcx > {
0 commit comments