Skip to content

Commit 44c7ae9

Browse files
committed
Parametrize gather_moves by filter.
1 parent d05f70e commit 44c7ae9

File tree

6 files changed

+88
-64
lines changed

6 files changed

+88
-64
lines changed

compiler/rustc_borrowck/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,10 @@ fn do_mir_borrowck<'tcx>(
215215
let location_table_owned = LocationTable::new(body);
216216
let location_table = &location_table_owned;
217217

218-
let move_data = MoveData::gather_moves(&body, tcx, param_env);
218+
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
219219
let promoted_move_data = promoted
220220
.iter_enumerated()
221-
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env)));
221+
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env, |_| true)));
222222

223223
let mdpe = MoveDataParamEnv { move_data, param_env };
224224

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+80-57
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_index::IndexVec;
2-
use rustc_middle::mir::tcx::RvalueInitializationState;
2+
use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState};
33
use rustc_middle::mir::*;
4-
use rustc_middle::ty::{self, TyCtxt};
4+
use rustc_middle::ty::{self, Ty, TyCtxt};
55
use smallvec::{smallvec, SmallVec};
66

77
use std::mem;
@@ -12,19 +12,49 @@ use super::{
1212
LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
1313
};
1414

15-
struct MoveDataBuilder<'a, 'tcx> {
15+
struct MoveDataBuilder<'a, 'tcx, F> {
1616
body: &'a Body<'tcx>,
1717
tcx: TyCtxt<'tcx>,
1818
param_env: ty::ParamEnv<'tcx>,
1919
data: MoveData<'tcx>,
20+
filter: F,
2021
}
2122

22-
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
23-
fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
23+
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
24+
where
25+
F: Fn(Ty<'tcx>) -> bool,
26+
{
27+
fn new(
28+
body: &'a Body<'tcx>,
29+
tcx: TyCtxt<'tcx>,
30+
param_env: ty::ParamEnv<'tcx>,
31+
filter: F,
32+
) -> Self {
2433
let mut move_paths = IndexVec::new();
2534
let mut path_map = IndexVec::new();
2635
let mut init_path_map = IndexVec::new();
2736

37+
let locals = body
38+
.local_decls
39+
.iter_enumerated()
40+
.map(|(i, l)| {
41+
if l.is_deref_temp() {
42+
return None;
43+
}
44+
if filter(l.ty) {
45+
Some(new_move_path(
46+
&mut move_paths,
47+
&mut path_map,
48+
&mut init_path_map,
49+
None,
50+
Place::from(i),
51+
))
52+
} else {
53+
None
54+
}
55+
})
56+
.collect();
57+
2858
MoveDataBuilder {
2959
body,
3060
tcx,
@@ -33,23 +63,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
3363
moves: IndexVec::new(),
3464
loc_map: LocationMap::new(body),
3565
rev_lookup: MovePathLookup {
36-
locals: body
37-
.local_decls
38-
.iter_enumerated()
39-
.map(|(i, l)| {
40-
if l.is_deref_temp() {
41-
None
42-
} else {
43-
Some(Self::new_move_path(
44-
&mut move_paths,
45-
&mut path_map,
46-
&mut init_path_map,
47-
None,
48-
Place::from(i),
49-
))
50-
}
51-
})
52-
.collect(),
66+
locals,
5367
projections: Default::default(),
5468
un_derefer: Default::default(),
5569
},
@@ -59,32 +73,33 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
5973
init_loc_map: LocationMap::new(body),
6074
init_path_map,
6175
},
76+
filter,
6277
}
6378
}
79+
}
6480

65-
fn new_move_path(
66-
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
67-
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
68-
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
69-
parent: Option<MovePathIndex>,
70-
place: Place<'tcx>,
71-
) -> MovePathIndex {
72-
let move_path =
73-
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
74-
75-
if let Some(parent) = parent {
76-
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
77-
move_paths[move_path].next_sibling = next_sibling;
78-
}
81+
fn new_move_path<'tcx>(
82+
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
83+
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
84+
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
85+
parent: Option<MovePathIndex>,
86+
place: Place<'tcx>,
87+
) -> MovePathIndex {
88+
let move_path =
89+
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
90+
91+
if let Some(parent) = parent {
92+
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
93+
move_paths[move_path].next_sibling = next_sibling;
94+
}
7995

80-
let path_map_ent = path_map.push(smallvec![]);
81-
assert_eq!(path_map_ent, move_path);
96+
let path_map_ent = path_map.push(smallvec![]);
97+
assert_eq!(path_map_ent, move_path);
8298

83-
let init_path_map_ent = init_path_map.push(smallvec![]);
84-
assert_eq!(init_path_map_ent, move_path);
99+
let init_path_map_ent = init_path_map.push(smallvec![]);
100+
assert_eq!(init_path_map_ent, move_path);
85101

86-
move_path
87-
}
102+
move_path
88103
}
89104

90105
enum MovePathResult {
@@ -93,7 +108,10 @@ enum MovePathResult {
93108
Error,
94109
}
95110

96-
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
111+
impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
112+
where
113+
F: Fn(Ty<'tcx>) -> bool,
114+
{
97115
/// This creates a MovePath for a given place, returning an `MovePathError`
98116
/// if that place can't be moved from.
99117
///
@@ -211,11 +229,15 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
211229
// So it's safe to skip these.
212230
ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
213231
}
232+
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
233+
if !(self.builder.filter)(elem_ty) {
234+
return MovePathResult::Error;
235+
}
214236
if union_path.is_none() {
215237
// inlined from add_move_path because of a borrowck conflict with the iterator
216238
base =
217239
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
218-
MoveDataBuilder::new_move_path(
240+
new_move_path(
219241
&mut data.move_paths,
220242
&mut data.path_map,
221243
&mut data.init_path_map,
@@ -246,13 +268,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
246268
..
247269
} = self.builder;
248270
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
249-
MoveDataBuilder::new_move_path(
250-
move_paths,
251-
path_map,
252-
init_path_map,
253-
Some(base),
254-
mk_place(*tcx),
255-
)
271+
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
256272
})
257273
}
258274

@@ -263,7 +279,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
263279
}
264280
}
265281

266-
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
282+
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
267283
fn finalize(self) -> MoveData<'tcx> {
268284
debug!("{}", {
269285
debug!("moves for {:?}:", self.body.span);
@@ -285,8 +301,9 @@ pub(super) fn gather_moves<'tcx>(
285301
body: &Body<'tcx>,
286302
tcx: TyCtxt<'tcx>,
287303
param_env: ty::ParamEnv<'tcx>,
304+
filter: impl Fn(Ty<'tcx>) -> bool,
288305
) -> MoveData<'tcx> {
289-
let mut builder = MoveDataBuilder::new(body, tcx, param_env);
306+
let mut builder = MoveDataBuilder::new(body, tcx, param_env, filter);
290307

291308
builder.gather_args();
292309

@@ -303,7 +320,10 @@ pub(super) fn gather_moves<'tcx>(
303320
builder.finalize()
304321
}
305322

306-
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
323+
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
324+
where
325+
F: Fn(Ty<'tcx>) -> bool,
326+
{
307327
fn gather_args(&mut self) {
308328
for arg in self.body.args_iter() {
309329
if let Some(path) = self.data.rev_lookup.find_local(arg) {
@@ -331,12 +351,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
331351
}
332352
}
333353

334-
struct Gatherer<'b, 'a, 'tcx> {
335-
builder: &'b mut MoveDataBuilder<'a, 'tcx>,
354+
struct Gatherer<'b, 'a, 'tcx, F> {
355+
builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
336356
loc: Location,
337357
}
338358

339-
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
359+
impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
360+
where
361+
F: Fn(Ty<'tcx>) -> bool,
362+
{
340363
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
341364
match &stmt.kind {
342365
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {

compiler/rustc_mir_dataflow/src/move_paths/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::un_derefer::UnDerefer;
22
use rustc_data_structures::fx::FxHashMap;
33
use rustc_index::{IndexSlice, IndexVec};
44
use rustc_middle::mir::*;
5-
use rustc_middle::ty::{ParamEnv, TyCtxt};
5+
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
66
use rustc_span::Span;
77
use smallvec::SmallVec;
88

@@ -351,8 +351,9 @@ impl<'tcx> MoveData<'tcx> {
351351
body: &Body<'tcx>,
352352
tcx: TyCtxt<'tcx>,
353353
param_env: ParamEnv<'tcx>,
354+
filter: impl Fn(Ty<'tcx>) -> bool,
354355
) -> MoveData<'tcx> {
355-
builder::gather_moves(body, tcx, param_env)
356+
builder::gather_moves(body, tcx, param_env, filter)
356357
}
357358

358359
/// For the move path `mpi`, returns the root local variable (if any) that starts the path.

compiler/rustc_mir_dataflow/src/rustc_peek.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
3434
}
3535

3636
let param_env = tcx.param_env(def_id);
37-
let move_data = MoveData::gather_moves(body, tcx, param_env);
37+
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
3838
let mdpe = MoveDataParamEnv { move_data, param_env };
3939

4040
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {

compiler/rustc_mir_transform/src/elaborate_drops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
5454

5555
let def_id = body.source.def_id();
5656
let param_env = tcx.param_env_reveal_all_normalized(def_id);
57-
let move_data = MoveData::gather_moves(body, tcx, param_env);
57+
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
5858
let elaborate_patch = {
5959
let env = MoveDataParamEnv { move_data, param_env };
6060

compiler/rustc_mir_transform/src/remove_uninit_drops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub struct RemoveUninitDrops;
2424
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
2525
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
2626
let param_env = tcx.param_env(body.source.def_id());
27-
let move_data = MoveData::gather_moves(body, tcx, param_env);
27+
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
2828

2929
let mdpe = MoveDataParamEnv { move_data, param_env };
3030
let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)

0 commit comments

Comments
 (0)