Parametrize gather_moves by filter.
This commit is contained in:
parent
4bedd7de6e
commit
252c64722f
6 changed files with 89 additions and 65 deletions
|
@ -219,10 +219,10 @@ fn do_mir_borrowck<'tcx>(
|
||||||
let location_table_owned = LocationTable::new(body);
|
let location_table_owned = LocationTable::new(body);
|
||||||
let location_table = &location_table_owned;
|
let location_table = &location_table_owned;
|
||||||
|
|
||||||
let move_data = MoveData::gather_moves(&body, tcx, param_env);
|
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
|
||||||
let promoted_move_data = promoted
|
let promoted_move_data = promoted
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env)));
|
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env, |_| true)));
|
||||||
|
|
||||||
let mdpe = MoveDataParamEnv { move_data, param_env };
|
let mdpe = MoveDataParamEnv { move_data, param_env };
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::mir::tcx::RvalueInitializationState;
|
use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -12,19 +12,49 @@ use super::{
|
||||||
LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
|
LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MoveDataBuilder<'a, 'tcx> {
|
struct MoveDataBuilder<'a, 'tcx, F> {
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
data: MoveData<'tcx>,
|
data: MoveData<'tcx>,
|
||||||
|
filter: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
|
||||||
fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
|
where
|
||||||
|
F: Fn(Ty<'tcx>) -> bool,
|
||||||
|
{
|
||||||
|
fn new(
|
||||||
|
body: &'a Body<'tcx>,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
filter: F,
|
||||||
|
) -> Self {
|
||||||
let mut move_paths = IndexVec::new();
|
let mut move_paths = IndexVec::new();
|
||||||
let mut path_map = IndexVec::new();
|
let mut path_map = IndexVec::new();
|
||||||
let mut init_path_map = IndexVec::new();
|
let mut init_path_map = IndexVec::new();
|
||||||
|
|
||||||
|
let locals = body
|
||||||
|
.local_decls
|
||||||
|
.iter_enumerated()
|
||||||
|
.map(|(i, l)| {
|
||||||
|
if l.is_deref_temp() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if filter(l.ty) {
|
||||||
|
Some(new_move_path(
|
||||||
|
&mut move_paths,
|
||||||
|
&mut path_map,
|
||||||
|
&mut init_path_map,
|
||||||
|
None,
|
||||||
|
Place::from(i),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
MoveDataBuilder {
|
MoveDataBuilder {
|
||||||
body,
|
body,
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -33,23 +63,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||||
moves: IndexVec::new(),
|
moves: IndexVec::new(),
|
||||||
loc_map: LocationMap::new(body),
|
loc_map: LocationMap::new(body),
|
||||||
rev_lookup: MovePathLookup {
|
rev_lookup: MovePathLookup {
|
||||||
locals: body
|
locals,
|
||||||
.local_decls
|
|
||||||
.iter_enumerated()
|
|
||||||
.map(|(i, l)| {
|
|
||||||
if l.is_deref_temp() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Self::new_move_path(
|
|
||||||
&mut move_paths,
|
|
||||||
&mut path_map,
|
|
||||||
&mut init_path_map,
|
|
||||||
None,
|
|
||||||
Place::from(i),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
projections: Default::default(),
|
projections: Default::default(),
|
||||||
un_derefer: Default::default(),
|
un_derefer: Default::default(),
|
||||||
},
|
},
|
||||||
|
@ -59,32 +73,33 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||||
init_loc_map: LocationMap::new(body),
|
init_loc_map: LocationMap::new(body),
|
||||||
init_path_map,
|
init_path_map,
|
||||||
},
|
},
|
||||||
|
filter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn new_move_path(
|
fn new_move_path<'tcx>(
|
||||||
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
|
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
|
||||||
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
|
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
|
||||||
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
|
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
|
||||||
parent: Option<MovePathIndex>,
|
parent: Option<MovePathIndex>,
|
||||||
place: Place<'tcx>,
|
place: Place<'tcx>,
|
||||||
) -> MovePathIndex {
|
) -> MovePathIndex {
|
||||||
let move_path =
|
let move_path =
|
||||||
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
|
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
|
||||||
|
|
||||||
if let Some(parent) = parent {
|
if let Some(parent) = parent {
|
||||||
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
|
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
|
||||||
move_paths[move_path].next_sibling = next_sibling;
|
move_paths[move_path].next_sibling = next_sibling;
|
||||||
}
|
|
||||||
|
|
||||||
let path_map_ent = path_map.push(smallvec![]);
|
|
||||||
assert_eq!(path_map_ent, move_path);
|
|
||||||
|
|
||||||
let init_path_map_ent = init_path_map.push(smallvec![]);
|
|
||||||
assert_eq!(init_path_map_ent, move_path);
|
|
||||||
|
|
||||||
move_path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let path_map_ent = path_map.push(smallvec![]);
|
||||||
|
assert_eq!(path_map_ent, move_path);
|
||||||
|
|
||||||
|
let init_path_map_ent = init_path_map.push(smallvec![]);
|
||||||
|
assert_eq!(init_path_map_ent, move_path);
|
||||||
|
|
||||||
|
move_path
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MovePathResult {
|
enum MovePathResult {
|
||||||
|
@ -93,7 +108,10 @@ enum MovePathResult {
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
|
||||||
|
where
|
||||||
|
F: Fn(Ty<'tcx>) -> bool,
|
||||||
|
{
|
||||||
/// This creates a MovePath for a given place, returning an `MovePathError`
|
/// This creates a MovePath for a given place, returning an `MovePathError`
|
||||||
/// if that place can't be moved from.
|
/// if that place can't be moved from.
|
||||||
///
|
///
|
||||||
|
@ -214,11 +232,15 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
| ProjectionElem::Subtype(_)
|
| ProjectionElem::Subtype(_)
|
||||||
| ProjectionElem::Downcast(_, _) => (),
|
| ProjectionElem::Downcast(_, _) => (),
|
||||||
}
|
}
|
||||||
|
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
|
||||||
|
if !(self.builder.filter)(elem_ty) {
|
||||||
|
return MovePathResult::Error;
|
||||||
|
}
|
||||||
if union_path.is_none() {
|
if union_path.is_none() {
|
||||||
// inlined from add_move_path because of a borrowck conflict with the iterator
|
// inlined from add_move_path because of a borrowck conflict with the iterator
|
||||||
base =
|
base =
|
||||||
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
|
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
|
||||||
MoveDataBuilder::new_move_path(
|
new_move_path(
|
||||||
&mut data.move_paths,
|
&mut data.move_paths,
|
||||||
&mut data.path_map,
|
&mut data.path_map,
|
||||||
&mut data.init_path_map,
|
&mut data.init_path_map,
|
||||||
|
@ -249,13 +271,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
..
|
..
|
||||||
} = self.builder;
|
} = self.builder;
|
||||||
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
|
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
|
||||||
MoveDataBuilder::new_move_path(
|
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
|
||||||
move_paths,
|
|
||||||
path_map,
|
|
||||||
init_path_map,
|
|
||||||
Some(base),
|
|
||||||
mk_place(*tcx),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +282,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
|
||||||
fn finalize(self) -> MoveData<'tcx> {
|
fn finalize(self) -> MoveData<'tcx> {
|
||||||
debug!("{}", {
|
debug!("{}", {
|
||||||
debug!("moves for {:?}:", self.body.span);
|
debug!("moves for {:?}:", self.body.span);
|
||||||
|
@ -288,8 +304,9 @@ pub(super) fn gather_moves<'tcx>(
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
filter: impl Fn(Ty<'tcx>) -> bool,
|
||||||
) -> MoveData<'tcx> {
|
) -> MoveData<'tcx> {
|
||||||
let mut builder = MoveDataBuilder::new(body, tcx, param_env);
|
let mut builder = MoveDataBuilder::new(body, tcx, param_env, filter);
|
||||||
|
|
||||||
builder.gather_args();
|
builder.gather_args();
|
||||||
|
|
||||||
|
@ -306,7 +323,10 @@ pub(super) fn gather_moves<'tcx>(
|
||||||
builder.finalize()
|
builder.finalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
|
||||||
|
where
|
||||||
|
F: Fn(Ty<'tcx>) -> bool,
|
||||||
|
{
|
||||||
fn gather_args(&mut self) {
|
fn gather_args(&mut self) {
|
||||||
for arg in self.body.args_iter() {
|
for arg in self.body.args_iter() {
|
||||||
if let Some(path) = self.data.rev_lookup.find_local(arg) {
|
if let Some(path) = self.data.rev_lookup.find_local(arg) {
|
||||||
|
@ -334,12 +354,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Gatherer<'b, 'a, 'tcx> {
|
struct Gatherer<'b, 'a, 'tcx, F> {
|
||||||
builder: &'b mut MoveDataBuilder<'a, 'tcx>,
|
builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
|
||||||
|
where
|
||||||
|
F: Fn(Ty<'tcx>) -> bool,
|
||||||
|
{
|
||||||
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
|
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::un_derefer::UnDerefer;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_index::{IndexSlice, IndexVec};
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{ParamEnv, TyCtxt};
|
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -351,8 +351,9 @@ impl<'tcx> MoveData<'tcx> {
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
|
filter: impl Fn(Ty<'tcx>) -> bool,
|
||||||
) -> MoveData<'tcx> {
|
) -> MoveData<'tcx> {
|
||||||
builder::gather_moves(body, tcx, param_env)
|
builder::gather_moves(body, tcx, param_env, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For the move path `mpi`, returns the root local variable (if any) that starts the path.
|
/// For the move path `mpi`, returns the root local variable (if any) that starts the path.
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
|
||||||
}
|
}
|
||||||
|
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
let move_data = MoveData::gather_moves(body, tcx, param_env);
|
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
|
||||||
let mdpe = MoveDataParamEnv { move_data, param_env };
|
let mdpe = MoveDataParamEnv { move_data, param_env };
|
||||||
|
|
||||||
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
|
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||||
|
|
||||||
let def_id = body.source.def_id();
|
let def_id = body.source.def_id();
|
||||||
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
||||||
let move_data = MoveData::gather_moves(body, tcx, param_env);
|
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
|
||||||
let elaborate_patch = {
|
let elaborate_patch = {
|
||||||
let env = MoveDataParamEnv { move_data, param_env };
|
let env = MoveDataParamEnv { move_data, param_env };
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct RemoveUninitDrops;
|
||||||
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
|
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
|
||||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let param_env = tcx.param_env(body.source.def_id());
|
let param_env = tcx.param_env(body.source.def_id());
|
||||||
let move_data = MoveData::gather_moves(body, tcx, param_env);
|
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
|
||||||
|
|
||||||
let mdpe = MoveDataParamEnv { move_data, param_env };
|
let mdpe = MoveDataParamEnv { move_data, param_env };
|
||||||
let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
|
let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue