Skip to content

Commit 0d847ec

Browse files
committed
add LocalWithRegion NllLivenessMap
1 parent 43b69c2 commit 0d847ec

File tree

8 files changed

+76
-36
lines changed

8 files changed

+76
-36
lines changed

src/librustc/mir/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub mod traversal;
5252
pub mod visit;
5353

5454
/// Types for locals
55-
type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
55+
type LocalDecls<'tcx> = IndexVec<LocalWithRegion, LocalDecl<'tcx>>;
5656

5757
pub trait HasLocalDecls<'tcx> {
5858
fn local_decls(&self) -> &LocalDecls<'tcx>;
@@ -141,7 +141,7 @@ impl<'tcx> Mir<'tcx> {
141141
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
142142
promoted: IndexVec<Promoted, Mir<'tcx>>,
143143
yield_ty: Option<Ty<'tcx>>,
144-
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
144+
local_decls: IndexVec<LocalWithRegion, LocalDecl<'tcx>>,
145145
arg_count: usize,
146146
upvar_decls: Vec<UpvarDecl>,
147147
span: Span,
@@ -209,7 +209,7 @@ impl<'tcx> Mir<'tcx> {
209209
}
210210

211211
#[inline]
212-
pub fn local_kind(&self, local: Local) -> LocalKind {
212+
pub fn local_kind(&self, local: LocalWithRegion) -> LocalKind {
213213
let index = local.0 as usize;
214214
if index == 0 {
215215
debug_assert!(
@@ -234,9 +234,9 @@ impl<'tcx> Mir<'tcx> {
234234

235235
/// Returns an iterator over all temporaries.
236236
#[inline]
237-
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
237+
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
238238
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
239-
let local = Local::new(index);
239+
let local = LocalWithRegion::new(index);
240240
if self.local_decls[local].is_user_variable.is_some() {
241241
None
242242
} else {
@@ -247,9 +247,9 @@ impl<'tcx> Mir<'tcx> {
247247

248248
/// Returns an iterator over all user-declared locals.
249249
#[inline]
250-
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
250+
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
251251
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
252-
let local = Local::new(index);
252+
let local = LocalWithRegion::new(index);
253253
if self.local_decls[local].is_user_variable.is_some() {
254254
Some(local)
255255
} else {
@@ -260,9 +260,9 @@ impl<'tcx> Mir<'tcx> {
260260

261261
/// Returns an iterator over all user-declared mutable arguments and locals.
262262
#[inline]
263-
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
263+
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
264264
(1..self.local_decls.len()).filter_map(move |index| {
265-
let local = Local::new(index);
265+
let local = LocalWithRegion::new(index);
266266
let decl = &self.local_decls[local];
267267
if (decl.is_user_variable.is_some() || index < self.arg_count + 1)
268268
&& decl.mutability == Mutability::Mut
@@ -2932,3 +2932,5 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
29322932
}
29332933
}
29342934
}
2935+
2936+
newtype_index!(LocalWithRegion);

src/librustc/mir/visit.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ macro_rules! make_mir_visitor {
146146

147147
fn visit_user_assert_ty(&mut self,
148148
c_ty: & $($mutability)* CanonicalTy<'tcx>,
149-
local: & $($mutability)* Local,
149+
local: & $($mutability)* LocalWithRegion,
150150
location: Location) {
151151
self.super_user_assert_ty(c_ty, local, location);
152152
}
@@ -250,13 +250,13 @@ macro_rules! make_mir_visitor {
250250
}
251251

252252
fn visit_local_decl(&mut self,
253-
local: Local,
253+
local: LocalWithRegion,
254254
local_decl: & $($mutability)* LocalDecl<'tcx>) {
255255
self.super_local_decl(local, local_decl);
256256
}
257257

258258
fn visit_local(&mut self,
259-
_local: & $($mutability)* Local,
259+
_local: & $($mutability)* LocalWithRegion,
260260
_context: PlaceContext<'tcx>,
261261
_location: Location) {
262262
}
@@ -632,7 +632,7 @@ macro_rules! make_mir_visitor {
632632

633633
fn super_user_assert_ty(&mut self,
634634
_c_ty: & $($mutability)* CanonicalTy<'tcx>,
635-
local: & $($mutability)* Local,
635+
local: & $($mutability)* LocalWithRegion,
636636
location: Location) {
637637
self.visit_local(local, PlaceContext::Validate, location);
638638
}
@@ -708,7 +708,7 @@ macro_rules! make_mir_visitor {
708708
}
709709

710710
fn super_local_decl(&mut self,
711-
local: Local,
711+
local: LocalWithRegion,
712712
local_decl: & $($mutability)* LocalDecl<'tcx>) {
713713
let LocalDecl {
714714
mutability: _,

src/librustc_mir/borrow_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
278278
// Note that this set is expected to be small - only upvars from closures
279279
// would have a chance of erroneously adding non-user-defined mutable vars
280280
// to the set.
281-
let temporary_used_locals: FxHashSet<Local> = mbcx
281+
let temporary_used_locals: FxHashSet<LocalWithRegion> = mbcx
282282
.used_mut
283283
.iter()
284284
.filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some())

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use dataflow::FlowAtLocation;
1919
use dataflow::MaybeInitializedPlaces;
2020
use rustc::hir::def_id::DefId;
2121
use rustc::infer::InferCtxt;
22-
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, Local};
22+
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, LocalWithRegion};
2323
use rustc::ty::{self, RegionKind, RegionVid};
2424
use rustc::util::nodemap::FxHashMap;
2525
use std::collections::BTreeSet;
@@ -30,7 +30,7 @@ use std::path::PathBuf;
3030
use std::rc::Rc;
3131
use std::str::FromStr;
3232
use transform::MirSource;
33-
use util::liveness::{IdentityMap, LivenessResults, LocalSet};
33+
use util::liveness::{IdentityMap, LivenessResults, LocalSet, NllLivenessMap};
3434

3535
use self::mir_util::PassWhere;
3636
use polonius_engine::{Algorithm, Output};
@@ -103,7 +103,8 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
103103
let elements = &Rc::new(RegionValueElements::new(mir, universal_regions.len()));
104104

105105
// Run the MIR type-checker.
106-
let liveness = &LivenessResults::compute(mir, &IdentityMap::new(mir));
106+
let liveness_map = NllLivenessMap::compute(&mir);
107+
let liveness = LivenessResults::compute(mir, &liveness_map);
107108
let constraint_sets = type_check::type_check(
108109
infcx,
109110
param_env,
@@ -193,7 +194,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
193194
// write unit-tests, as well as helping with debugging.
194195
dump_mir_results(
195196
infcx,
196-
liveness,
197+
&liveness,
197198
MirSource::item(def_id),
198199
&mir,
199200
&regioncx,
@@ -209,7 +210,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
209210

210211
fn dump_mir_results<'a, 'gcx, 'tcx>(
211212
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
212-
liveness: &LivenessResults<Local>,
213+
liveness: &LivenessResults<LocalWithRegion>,
213214
source: MirSource,
214215
mir: &Mir<'tcx>,
215216
regioncx: &RegionInferenceContext,
@@ -407,7 +408,7 @@ impl ToRegionVid for RegionVid {
407408
}
408409
}
409410

410-
fn live_variable_set(regular: &LocalSet<Local>, drops: &LocalSet<Local>) -> String {
411+
fn live_variable_set(regular: &LocalSet<LocalWithRegion>, drops: &LocalSet<LocalWithRegion>) -> String {
411412
// sort and deduplicate:
412413
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
413414

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use dataflow::move_paths::{HasMoveData, MoveData};
1313
use dataflow::MaybeInitializedPlaces;
1414
use dataflow::{FlowAtLocation, FlowsAtLocation};
1515
use rustc::infer::canonical::QueryRegionConstraint;
16-
use rustc::mir::Local;
16+
use rustc::mir::{Local, LocalWithRegion};
1717
use rustc::mir::{BasicBlock, Location, Mir};
1818
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
1919
use rustc::traits::query::type_op::outlives::DropckOutlives;
@@ -36,7 +36,7 @@ use super::TypeChecker;
3636
pub(super) fn generate<'gcx, 'tcx>(
3737
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
3838
mir: &Mir<'tcx>,
39-
liveness: &LivenessResults<Local>,
39+
liveness: &LivenessResults<LocalWithRegion>,
4040
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
4141
move_data: &MoveData<'tcx>,
4242
) {
@@ -64,7 +64,7 @@ where
6464
{
6565
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
6666
mir: &'gen Mir<'tcx>,
67-
liveness: &'gen LivenessResults<Local>,
67+
liveness: &'gen LivenessResults<LocalWithRegion>,
6868
flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
6969
move_data: &'gen MoveData<'tcx>,
7070
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
@@ -93,7 +93,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
9393
}
9494
});
9595

96-
let mut all_live_locals: Vec<(Location, Vec<Local>)> = vec![];
96+
let mut all_live_locals: Vec<(Location, Vec<LocalWithRegion>)> = vec![];
9797
self.liveness
9898
.drop
9999
.simulate_block(self.mir, bb, self.map, |location, live_locals| {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
108108
mir_def_id: DefId,
109109
universal_regions: &UniversalRegions<'tcx>,
110110
location_table: &LocationTable,
111-
borrow_set: &BorrowSet<'tcx>,
112-
liveness: &LivenessResults,
111+
liveness: &LivenessResults<LocalWithRegion>,
113112
all_facts: &mut Option<AllFacts>,
114113
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
115114
move_data: &MoveData<'tcx>,

src/librustc_mir/dataflow/impls/borrowed_locals.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,34 @@ impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
3737
}
3838

3939
impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
40-
type Idx = Local;
40+
type Idx = LocalWithRegion;
4141
fn name() -> &'static str { "has_been_borrowed_locals" }
4242
fn bits_per_block(&self) -> usize {
4343
self.mir.local_decls.len()
4444
}
4545

46-
fn start_block_effect(&self, _sets: &mut IdxSet<Local>) {
46+
fn start_block_effect(&self, _sets: &mut IdxSet<LocalWithRegion>) {
4747
// Nothing is borrowed on function entry
4848
}
4949

5050
fn statement_effect(&self,
51-
sets: &mut BlockSets<Local>,
51+
sets: &mut BlockSets<LocalWithRegion>,
5252
loc: Location) {
5353
BorrowedLocalsVisitor {
5454
sets,
5555
}.visit_statement(loc.block, &self.mir[loc.block].statements[loc.statement_index], loc);
5656
}
5757

5858
fn terminator_effect(&self,
59-
sets: &mut BlockSets<Local>,
59+
sets: &mut BlockSets<LocalWithRegion>,
6060
loc: Location) {
6161
BorrowedLocalsVisitor {
6262
sets,
6363
}.visit_terminator(loc.block, self.mir[loc.block].terminator(), loc);
6464
}
6565

6666
fn propagate_call_return(&self,
67-
_in_out: &mut IdxSet<Local>,
67+
_in_out: &mut IdxSet<LocalWithRegion>,
6868
_call_bb: mir::BasicBlock,
6969
_dest_bb: mir::BasicBlock,
7070
_dest_place: &mir::Place) {
@@ -87,10 +87,10 @@ impl<'a, 'tcx> InitialFlow for HaveBeenBorrowedLocals<'a, 'tcx> {
8787
}
8888

8989
struct BorrowedLocalsVisitor<'b, 'c: 'b> {
90-
sets: &'b mut BlockSets<'c, Local>,
90+
sets: &'b mut BlockSets<'c, LocalWithRegion>,
9191
}
9292

93-
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
93+
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<LocalWithRegion> {
9494
match *place {
9595
Place::Local(l) => Some(l),
9696
Place::Static(..) => None,

src/librustc_mir/util/liveness.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ use rustc::mir::visit::MirVisitable;
3737
use rustc::mir::visit::{PlaceContext, Visitor};
3838
use rustc::mir::Local;
3939
use rustc::mir::*;
40-
use rustc::ty::item_path;
41-
use rustc::ty::TyCtxt;
40+
use rustc::ty::{item_path, TyCtxt, TypeFoldable};
4241
use rustc_data_structures::indexed_set::IdxSetBuf;
4342
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
4443
use rustc_data_structures::work_queue::WorkQueue;
@@ -545,3 +544,42 @@ pub fn write_mir_fn<'a, 'tcx, V: Idx>(
545544
writeln!(w, "}}")?;
546545
Ok(())
547546
}
547+
548+
crate struct NllLivenessMap {
549+
pub from_local: IndexVec<Local, Option<LocalWithRegion>>,
550+
pub to_local: IndexVec<LocalWithRegion, Local>,
551+
552+
}
553+
554+
impl LiveVariableMap for NllLivenessMap {
555+
type LiveVar = LocalWithRegion;
556+
557+
fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
558+
self.from_local[local]
559+
}
560+
561+
fn from_live_var(&self, local: Self::LiveVar) -> Local {
562+
self.to_local[local]
563+
}
564+
565+
fn num_variables(&self) -> usize {
566+
self.to_local.len()
567+
}
568+
}
569+
570+
impl NllLivenessMap {
571+
pub fn compute(mir: &Mir) -> Self {
572+
let mut to_local = IndexVec::default();
573+
let from_local: IndexVec<_,_> = mir.local.decls.iter_enumerated.map(|local, local_decl| {
574+
if local_decl.ty.has_free_regions() {
575+
Some(to_local.push(local))
576+
}
577+
else {
578+
None
579+
}
580+
}).collect();
581+
582+
Self { from_local, to_local }
583+
}
584+
}
585+

0 commit comments

Comments
 (0)