Skip to content

Commit 252c647

Browse files
committed
Parametrize gather_moves by filter.
1 parent 4bedd7d commit 252c647

File tree

6 files changed

+88
-64
lines changed

6 files changed

+88
-64
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ fn do_mir_borrowck<'tcx>(
219219
let location_table_owned = LocationTable::new(body);
220220
let location_table = &location_table_owned;
221221

222-
let move_data = MoveData::gather_moves(&body, tcx, param_env);
222+
let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
223223
let promoted_move_data = promoted
224224
.iter_enumerated()
225-
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env)));
225+
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env, |_| true)));
226226

227227
let mdpe = MoveDataParamEnv { move_data, param_env };
228228

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

Lines changed: 80 additions & 57 deletions
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
///
@@ -214,11 +232,15 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
214232
| ProjectionElem::Subtype(_)
215233
| ProjectionElem::Downcast(_, _) => (),
216234
}
235+
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
236+
if !(self.builder.filter)(elem_ty) {
237+
return MovePathResult::Error;
238+
}
217239
if union_path.is_none() {
218240
// inlined from add_move_path because of a borrowck conflict with the iterator
219241
base =
220242
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
221-
MoveDataBuilder::new_move_path(
243+
new_move_path(
222244
&mut data.move_paths,
223245
&mut data.path_map,
224246
&mut data.init_path_map,
@@ -249,13 +271,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
249271
..
250272
} = self.builder;
251273
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
252-
MoveDataBuilder::new_move_path(
253-
move_paths,
254-
path_map,
255-
init_path_map,
256-
Some(base),
257-
mk_place(*tcx),
258-
)
274+
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
259275
})
260276
}
261277

@@ -266,7 +282,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
266282
}
267283
}
268284

269-
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
285+
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
270286
fn finalize(self) -> MoveData<'tcx> {
271287
debug!("{}", {
272288
debug!("moves for {:?}:", self.body.span);
@@ -288,8 +304,9 @@ pub(super) fn gather_moves<'tcx>(
288304
body: &Body<'tcx>,
289305
tcx: TyCtxt<'tcx>,
290306
param_env: ty::ParamEnv<'tcx>,
307+
filter: impl Fn(Ty<'tcx>) -> bool,
291308
) -> MoveData<'tcx> {
292-
let mut builder = MoveDataBuilder::new(body, tcx, param_env);
309+
let mut builder = MoveDataBuilder::new(body, tcx, param_env, filter);
293310

294311
builder.gather_args();
295312

@@ -306,7 +323,10 @@ pub(super) fn gather_moves<'tcx>(
306323
builder.finalize()
307324
}
308325

309-
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
326+
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
327+
where
328+
F: Fn(Ty<'tcx>) -> bool,
329+
{
310330
fn gather_args(&mut self) {
311331
for arg in self.body.args_iter() {
312332
if let Some(path) = self.data.rev_lookup.find_local(arg) {
@@ -334,12 +354,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
334354
}
335355
}
336356

337-
struct Gatherer<'b, 'a, 'tcx> {
338-
builder: &'b mut MoveDataBuilder<'a, 'tcx>,
357+
struct Gatherer<'b, 'a, 'tcx, F> {
358+
builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
339359
loc: Location,
340360
}
341361

342-
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
362+
impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
363+
where
364+
F: Fn(Ty<'tcx>) -> bool,
365+
{
343366
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
344367
match &stmt.kind {
345368
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {

compiler/rustc_mir_dataflow/src/move_paths/mod.rs

Lines changed: 3 additions & 2 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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)