Skip to content

Commit 26f1c01

Browse files
committed
Add read_only fn to BodyCache<&mut...> impl, fix more Body -> (ReadOnly)BodyCache type errors
1 parent ab98c59 commit 26f1c01

File tree

6 files changed

+48
-40
lines changed

6 files changed

+48
-40
lines changed

src/librustc/mir/cache.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ impl<'a, 'tcx> BodyCache<&'a mut Body<'tcx>> {
205205
self.body
206206
}
207207

208+
#[inline]
209+
pub fn read_only(mut self) -> ReadOnlyBodyCache<'a, 'tcx> {
210+
self.cache.ensure_predecessors(self.body);
211+
ReadOnlyBodyCache {
212+
cache: self.cache,
213+
body: self.body,
214+
}
215+
}
216+
208217
#[inline]
209218
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
210219
&self.body.basic_blocks

src/librustc_mir/borrow_check/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ fn do_mir_borrowck<'a, 'tcx>(
163163
// be modified (in place) to contain non-lexical lifetimes. It
164164
// will have a lifetime tied to the inference context.
165165
let mut body: Body<'tcx> = input_body.clone();
166-
// TODO(pfaria) this very likely won't work because
167-
let promoted: IndexVec<Promoted, Body<'tcx>> = input_promoted.clone();
168-
let mut promoted_cache: IndexVec<Promoted, BodyCache<&mut Body<'tcx>>> = promoted.iter_mut().map(|body| BodyCache::new(body)).collect();
166+
let mut promoted = input_promoted.clone();
167+
let mut promoted_cache: IndexVec<Promoted, BodyCache<&mut Body<'tcx>>> = input_promoted.clone().iter_mut().map(|body| BodyCache::new(body)).collect();
169168
let mut body_cache = BodyCache::new(&mut body);
170169
let free_regions =
171170
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body_cache, &mut promoted_cache);
172171
let body_cache = BodyCache::new(&body).read_only(); // no further changes
172+
let promoted: IndexVec<Promoted, ReadOnlyBodyCache<'_, 'tcx>> = promoted_cache.into_iter().map(|body_cache| body_cache.read_only()).collect();
173173

174174
let location_table = &LocationTable::new(&body_cache);
175175

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
159159
def_id: DefId,
160160
universal_regions: UniversalRegions<'tcx>,
161161
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
162-
promoted: &IndexVec<Promoted, Body<'tcx>>,
162+
promoted_cache: &IndexVec<Promoted, ReadOnlyBodyCache<'_, 'tcx>>,
163163
local_names: &IndexVec<Local, Option<Symbol>>,
164164
upvars: &[Upvar],
165165
location_table: &LocationTable,
@@ -191,7 +191,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
191191
infcx,
192192
param_env,
193193
body_cache,
194-
promoted,
194+
promoted_cache,
195195
def_id,
196196
&universal_regions,
197197
location_table,

src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::borrow_check::nll::ToRegionVid;
77
use crate::dataflow::move_paths::MoveData;
88
use crate::dataflow::FlowAtLocation;
99
use crate::dataflow::MaybeInitializedPlaces;
10-
use rustc::mir::{Body, Local};
10+
use rustc::mir::{Body, Local, ReadOnlyBodyCache};
1111
use rustc::ty::{RegionVid, TyCtxt};
1212
use rustc_data_structures::fx::FxHashSet;
1313
use std::rc::Rc;
@@ -28,7 +28,7 @@ mod trace;
2828
/// performed before
2929
pub(super) fn generate<'tcx>(
3030
typeck: &mut TypeChecker<'_, 'tcx>,
31-
body: &Body<'tcx>,
31+
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
3232
elements: &Rc<RegionValueElements>,
3333
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
3434
move_data: &MoveData<'tcx>,
@@ -41,15 +41,14 @@ pub(super) fn generate<'tcx>(
4141
&typeck.borrowck_context.universal_regions,
4242
&typeck.borrowck_context.constraints.outlives_constraints,
4343
);
44-
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body);
44+
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, &body_cache);
4545
let facts_enabled = AllFacts::enabled(typeck.tcx());
4646

47-
4847
let polonius_drop_used = if facts_enabled {
4948
let mut drop_used = Vec::new();
5049
polonius::populate_access_facts(
5150
typeck,
52-
body,
51+
&body_cache,
5352
location_table,
5453
move_data,
5554
&mut drop_used,
@@ -62,7 +61,7 @@ pub(super) fn generate<'tcx>(
6261
if !live_locals.is_empty() || facts_enabled {
6362
trace::trace(
6463
typeck,
65-
body,
64+
body_cache,
6665
elements,
6766
flow_inits,
6867
move_data,

src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::dataflow::indexes::MovePathIndex;
77
use crate::dataflow::move_paths::MoveData;
88
use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
99
use rustc::infer::canonical::QueryRegionConstraints;
10-
use rustc::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
10+
use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, ReadOnlyBodyCache};
1111
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
1212
use rustc::traits::query::type_op::outlives::DropckOutlives;
1313
use rustc::traits::query::type_op::TypeOp;
@@ -32,7 +32,7 @@ use std::rc::Rc;
3232
/// this respects `#[may_dangle]` annotations).
3333
pub(super) fn trace(
3434
typeck: &mut TypeChecker<'_, 'tcx>,
35-
body: &Body<'tcx>,
35+
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
3636
elements: &Rc<RegionValueElements>,
3737
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
3838
move_data: &MoveData<'tcx>,
@@ -41,11 +41,11 @@ pub(super) fn trace(
4141
) {
4242
debug!("trace()");
4343

44-
let local_use_map = &LocalUseMap::build(&live_locals, elements, body);
44+
let local_use_map = &LocalUseMap::build(&live_locals, elements, &body_cache);
4545

4646
let cx = LivenessContext {
4747
typeck,
48-
body,
48+
body_cache,
4949
flow_inits,
5050
elements,
5151
local_use_map,
@@ -71,7 +71,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
7171
elements: &'me RegionValueElements,
7272

7373
/// MIR we are analyzing.
74-
body: &'me Body<'tcx>,
74+
body_cache: &'me ReadOnlyBodyCache<'me, 'tcx>,
7575

7676
/// Mapping to/from the various indices used for initialization tracking.
7777
move_data: &'me MoveData<'tcx>,
@@ -135,7 +135,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
135135
self.compute_use_live_points_for(local);
136136
self.compute_drop_live_points_for(local);
137137

138-
let local_ty = self.cx.body.local_decls[local].ty;
138+
let local_ty = self.cx.body_cache.local_decls[local].ty;
139139

140140
if !self.use_live_at.is_empty() {
141141
self.cx.add_use_live_facts_for(local_ty, &self.use_live_at);
@@ -165,7 +165,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
165165

166166
for (local, location) in drop_used {
167167
if !live_locals.contains(&local) {
168-
let local_ty = self.cx.body.local_decls[local].ty;
168+
let local_ty = self.cx.body_cache.local_decls[local].ty;
169169
if local_ty.has_free_regions() {
170170
self.cx.add_drop_live_facts_for(
171171
local,
@@ -211,7 +211,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
211211
}
212212

213213
if self.use_live_at.insert(p) {
214-
self.cx.elements.push_predecessors(self.cx.body, p, &mut self.stack)
214+
self.cx.elements.push_predecessors(&self.cx.body_cache, p, &mut self.stack)
215215
}
216216
}
217217
}
@@ -234,7 +234,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
234234
// Find the drops where `local` is initialized.
235235
for drop_point in self.cx.local_use_map.drops(local) {
236236
let location = self.cx.elements.to_location(drop_point);
237-
debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
237+
debug_assert_eq!(self.cx.body_cache.terminator_loc(location.block), location,);
238238

239239
if self.cx.initialized_at_terminator(location.block, mpi) {
240240
if self.drop_live_at.insert(drop_point) {
@@ -280,7 +280,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
280280
// block. One of them may be either a definition or use
281281
// live point.
282282
let term_location = self.cx.elements.to_location(term_point);
283-
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
283+
debug_assert_eq!(self.cx.body_cache.terminator_loc(term_location.block), term_location,);
284284
let block = term_location.block;
285285
let entry_point = self.cx.elements.entry_point(term_location.block);
286286
for p in (entry_point..term_point).rev() {
@@ -302,7 +302,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
302302
}
303303
}
304304

305-
for &pred_block in self.cx.body.predecessors_for(block).iter() {
305+
for &pred_block in self.cx.body_cache.predecessors_for(block).iter() {
306306
debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,);
307307

308308
// Check whether the variable is (at least partially)
@@ -328,7 +328,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
328328
continue;
329329
}
330330

331-
let pred_term_loc = self.cx.body.terminator_loc(pred_block);
331+
let pred_term_loc = self.cx.body_cache.terminator_loc(pred_block);
332332
let pred_term_point = self.cx.elements.point_from_location(pred_term_loc);
333333

334334
// If the terminator of this predecessor either *assigns*
@@ -399,7 +399,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
399399
// the effects of all statements. This is the only way to get
400400
// "just ahead" of a terminator.
401401
self.flow_inits.reset_to_entry_of(block);
402-
for statement_index in 0..self.body[block].statements.len() {
402+
for statement_index in 0..self.body_cache[block].statements.len() {
403403
let location = Location { block, statement_index };
404404
self.flow_inits.reconstruct_statement_effect(location);
405405
self.flow_inits.apply_local_effect(location);
@@ -471,7 +471,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
471471

472472
drop_data.dropck_result.report_overflows(
473473
self.typeck.infcx.tcx,
474-
self.body.source_info(*drop_locations.first().unwrap()).span,
474+
self.body_cache.source_info(*drop_locations.first().unwrap()).span,
475475
dropped_ty,
476476
);
477477

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub(crate) fn type_check<'tcx>(
116116
infcx: &InferCtxt<'_, 'tcx>,
117117
param_env: ty::ParamEnv<'tcx>,
118118
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
119-
promoted: &IndexVec<Promoted, Body<'tcx>>,
119+
promoted_cache: &IndexVec<Promoted, ReadOnlyBodyCache<'_, 'tcx>>,
120120
mir_def_id: DefId,
121121
universal_regions: &Rc<UniversalRegions<'tcx>>,
122122
location_table: &LocationTable,
@@ -162,7 +162,7 @@ pub(crate) fn type_check<'tcx>(
162162
mir_def_id,
163163
param_env,
164164
body_cache,
165-
promoted,
165+
promoted_cache,
166166
&region_bound_pairs,
167167
implicit_region_bound,
168168
&mut borrowck_context,
@@ -186,7 +186,7 @@ fn type_check_internal<'a, 'tcx, R>(
186186
mir_def_id: DefId,
187187
param_env: ty::ParamEnv<'tcx>,
188188
body_cache: &ReadOnlyBodyCache<'a, 'tcx>,
189-
promoted: &'a IndexVec<Promoted, Body<'tcx>>,
189+
promoted_cache: &'a IndexVec<Promoted, ReadOnlyBodyCache<'_, 'tcx>>,
190190
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
191191
implicit_region_bound: ty::Region<'tcx>,
192192
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
@@ -204,7 +204,7 @@ fn type_check_internal<'a, 'tcx, R>(
204204
universal_region_relations,
205205
);
206206
let errors_reported = {
207-
let mut verifier = TypeVerifier::new(&mut checker, body_cache, promoted);
207+
let mut verifier = TypeVerifier::new(&mut checker, body_cache, promoted_cache);
208208
verifier.visit_body(body_cache);
209209
verifier.errors_reported
210210
};
@@ -261,7 +261,7 @@ enum FieldAccessError {
261261
struct TypeVerifier<'a, 'b, 'tcx> {
262262
cx: &'a mut TypeChecker<'b, 'tcx>,
263263
body: &'b Body<'tcx>,
264-
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
264+
promoted_cache: &'b IndexVec<Promoted, ReadOnlyBodyCache<'b, 'tcx>>,
265265
last_span: Span,
266266
mir_def_id: DefId,
267267
errors_reported: bool,
@@ -401,11 +401,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
401401
fn new(
402402
cx: &'a mut TypeChecker<'b, 'tcx>,
403403
body: &'b Body<'tcx>,
404-
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
404+
promoted_cache: &'b IndexVec<Promoted, ReadOnlyBodyCache<'b, 'tcx>>,
405405
) -> Self {
406406
TypeVerifier {
407407
body,
408-
promoted,
408+
promoted_cache,
409409
mir_def_id: cx.mir_def_id,
410410
cx,
411411
last_span: body.span,
@@ -464,10 +464,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
464464
match kind {
465465
StaticKind::Promoted(promoted, _) => {
466466
if !self.errors_reported {
467-
let promoted_body = &self.promoted[*promoted];
468-
self.sanitize_promoted(promoted_body, location);
467+
let promoted_body_cache = &self.promoted_cache[*promoted];
468+
self.sanitize_promoted(promoted_body_cache, location);
469469

470-
let promoted_ty = promoted_body.return_ty();
470+
let promoted_ty = promoted_body_cache.return_ty();
471471
check_err(self, place, promoted_ty, san_ty);
472472
}
473473
}
@@ -535,20 +535,20 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
535535
place_ty
536536
}
537537

538-
fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
538+
fn sanitize_promoted(&mut self, promoted_body_cache: &ReadOnlyBodyCache<'b, 'tcx>, location: Location) {
539539
// Determine the constraints from the promoted MIR by running the type
540540
// checker on the promoted MIR, then transfer the constraints back to
541541
// the main MIR, changing the locations to the provided location.
542542

543-
let parent_body = mem::replace(&mut self.body, promoted_body);
543+
let parent_body = mem::replace(&mut self.body, &promoted_body_cache);
544544

545545
// Use new sets of constraints and closure bounds so that we can
546546
// modify their locations.
547547
let all_facts = &mut None;
548548
let mut constraints = Default::default();
549549
let mut closure_bounds = Default::default();
550550
let mut liveness_constraints = LivenessValues::new(
551-
Rc::new(RegionValueElements::new(promoted_body)),
551+
Rc::new(RegionValueElements::new(&promoted_body_cache)),
552552
);
553553
// Don't try to add borrow_region facts for the promoted MIR
554554

@@ -570,12 +570,12 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
570570

571571
swap_constraints(self);
572572

573-
self.visit_body(promoted_body);
573+
self.visit_body(promoted_body_cache);
574574

575575

576576
if !self.errors_reported {
577577
// if verifier failed, don't do further checks to avoid ICEs
578-
self.cx.typeck_mir(promoted_body);
578+
self.cx.typeck_mir(&promoted_body_cache);
579579
}
580580

581581
self.body = parent_body;

0 commit comments

Comments
 (0)