Skip to content

Commit 71e619f

Browse files
committed
Refactoring: avoid tcx explicitly through drop_flag_effects API.
Instead, it currently takes closures to compute the desired value(s). I hope to replace the set of closures with two dedicated traits to provide the methods has_uniform_drop_state and needs_drop, but in a more self-documenting fashion. In other words, this is exchanging passing around a trio of lifetimes (which Rust currently cannot factor into any kind of abstract group) for passing around one or more type parameters (which might, in principle, be combined into a single type parameter, if one sets up the traits the right way...)
1 parent 48d891e commit 71e619f

File tree

3 files changed

+214
-159
lines changed

3 files changed

+214
-159
lines changed

src/librustc_mir/dataflow/drop_flag_effects.rs

Lines changed: 87 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc::mir::{self, Mir, Location};
11+
use rustc::mir::{self, Mir, Location, Place};
1212
use rustc::ty::{self, TyCtxt};
1313
use util::elaborate_drops::DropFlagState;
1414

15-
use super::{MoveDataParamEnv};
1615
use super::indexes::MovePathIndex;
1716
use super::move_paths::{MoveData, LookupResult, InitKind};
1817

@@ -25,7 +24,7 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
2524
let mut next_child = move_data.move_paths[path].first_child;
2625
while let Some(child_index) = next_child {
2726
match move_data.move_paths[child_index].place {
28-
mir::Place::Projection(ref proj) => {
27+
Place::Projection(ref proj) => {
2928
if cond(proj) {
3029
return Some(child_index)
3130
}
@@ -56,9 +55,11 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
5655
/// is no need to maintain separate drop flags to track such state.
5756
///
5857
/// FIXME: we have to do something for moving slice patterns.
59-
fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
60-
mir: &Mir<'tcx>,
61-
place: &mir::Place<'tcx>) -> bool {
58+
pub(crate) fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(
59+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
60+
mir: &Mir<'tcx>,
61+
place: &Place<'tcx>) -> bool
62+
{
6263
let ty = place.ty(mir, tcx).to_ty(tcx);
6364
match ty.sty {
6465
ty::TyArray(..) => {
@@ -82,154 +83,160 @@ fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx,
8283
}
8384
}
8485

85-
pub(crate) fn on_lookup_result_bits<'a, 'gcx, 'tcx, F>(
86-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
87-
mir: &Mir<'tcx>,
88-
move_data: &MoveData<'tcx>,
89-
lookup_result: LookupResult,
90-
each_child: F)
91-
where F: FnMut(MovePathIndex)
86+
pub(crate) fn place_needs_drop<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
87+
mir: &Mir<'tcx>,
88+
param_env: ty::ParamEnv<'gcx>,
89+
place: &Place<'tcx>)
90+
-> bool
91+
{
92+
let ty = place.ty(mir, tcx).to_ty(tcx);
93+
// debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty);
94+
95+
let gcx = tcx.global_tcx();
96+
let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
97+
erased_ty.needs_drop(gcx, param_env)
98+
}
99+
100+
pub(crate) fn on_lookup_result_bits<'tcx, F, U>(move_data: &MoveData<'tcx>,
101+
lookup_result: LookupResult,
102+
has_uniform_drop_state: U,
103+
each_child: F)
104+
where F: FnMut(MovePathIndex), U: Fn(&Place<'tcx>) -> bool
92105
{
93106
match lookup_result {
94107
LookupResult::Parent(..) => {
95108
// access to untracked value - do not touch children
96109
}
97110
LookupResult::Exact(e) => {
98-
on_all_children_bits(tcx, mir, move_data, e, each_child)
111+
on_all_children_bits(move_data, e, has_uniform_drop_state, each_child)
99112
}
100113
}
101114
}
102115

103-
pub(crate) fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
104-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
105-
mir: &Mir<'tcx>,
106-
move_data: &MoveData<'tcx>,
107-
move_path_index: MovePathIndex,
108-
mut each_child: F)
109-
where F: FnMut(MovePathIndex)
116+
pub(crate) fn on_all_children_bits<'tcx, F, U>(move_data: &MoveData<'tcx>,
117+
move_path_index: MovePathIndex,
118+
has_uniform_drop_state: U,
119+
mut each_child: F)
120+
where F: FnMut(MovePathIndex), U: Fn(&Place<'tcx>) -> bool
110121
{
111-
fn is_terminal_path<'a, 'gcx, 'tcx>(
112-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
113-
mir: &Mir<'tcx>,
114-
move_data: &MoveData<'tcx>,
115-
path: MovePathIndex) -> bool
122+
fn is_terminal_path<'tcx, U>(move_data: &MoveData<'tcx>,
123+
path: MovePathIndex,
124+
has_uniform_drop_state: U) -> bool
125+
where U: Fn(&Place<'tcx>) -> bool
116126
{
117-
place_contents_drop_state_cannot_differ(
118-
tcx, mir, &move_data.move_paths[path].place)
127+
// lvalue_contents_drop_state_cannot_differ
128+
has_uniform_drop_state(&move_data.move_paths[path].place)
119129
}
120130

121-
fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
122-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
123-
mir: &Mir<'tcx>,
124-
move_data: &MoveData<'tcx>,
125-
move_path_index: MovePathIndex,
126-
each_child: &mut F)
127-
where F: FnMut(MovePathIndex)
131+
fn on_all_children_bits<'tcx, F, U>(move_data: &MoveData<'tcx>,
132+
move_path_index: MovePathIndex,
133+
has_uniform_drop_state: &U,
134+
each_child: &mut F)
135+
where F: FnMut(MovePathIndex), U: Fn(&Place<'tcx>) -> bool
128136
{
129137
each_child(move_path_index);
130138

131-
if is_terminal_path(tcx, mir, move_data, move_path_index) {
139+
if is_terminal_path(move_data, move_path_index, has_uniform_drop_state) {
132140
return
133141
}
134142

135143
let mut next_child_index = move_data.move_paths[move_path_index].first_child;
136144
while let Some(child_index) = next_child_index {
137-
on_all_children_bits(tcx, mir, move_data, child_index, each_child);
145+
on_all_children_bits(move_data, child_index, has_uniform_drop_state, each_child);
138146
next_child_index = move_data.move_paths[child_index].next_sibling;
139147
}
140148
}
141-
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
149+
on_all_children_bits(move_data, move_path_index, &has_uniform_drop_state, &mut each_child);
142150
}
143151

144-
pub(crate) fn on_all_drop_children_bits<'a, 'gcx, 'tcx, F>(
145-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
146-
mir: &Mir<'tcx>,
147-
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
148-
path: MovePathIndex,
149-
mut each_child: F)
150-
where F: FnMut(MovePathIndex)
152+
pub(crate) fn on_all_drop_children_bits<'tcx, F, U, N>(move_data: &MoveData<'tcx>,
153+
path: MovePathIndex,
154+
has_uniform_drop_state: U,
155+
needs_drop: N,
156+
mut each_child: F)
157+
where F: FnMut(MovePathIndex),
158+
U: Fn(&Place<'tcx>) -> bool,
159+
N: Fn(&Place<'tcx>) -> bool,
151160
{
152-
on_all_children_bits(tcx, mir, &ctxt.move_data, path, |child| {
153-
let place = &ctxt.move_data.move_paths[path].place;
154-
let ty = place.ty(mir, tcx).to_ty(tcx);
155-
debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty);
156-
157-
let gcx = tcx.global_tcx();
158-
let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
159-
if erased_ty.needs_drop(gcx, ctxt.param_env) {
161+
on_all_children_bits(move_data, path, has_uniform_drop_state, |child| {
162+
let place = &move_data.move_paths[path].place;
163+
// let ty = place.ty(mir, tcx).to_ty(tcx);
164+
// debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty);
165+
166+
// let gcx = tcx.global_tcx();
167+
// let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
168+
// if erased_ty.needs_drop(gcx, ctxt.param_env) {
169+
if needs_drop(place) {
160170
each_child(child);
161171
} else {
162172
debug!("on_all_drop_children_bits - skipping")
163173
}
164174
})
165175
}
166176

167-
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
168-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
169-
mir: &Mir<'tcx>,
170-
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
171-
mut callback: F)
172-
where F: FnMut(MovePathIndex, DropFlagState)
177+
pub(crate) fn drop_flag_effects_for_function_entry<'tcx, F, U>(
178+
mir: &Mir<'tcx>,
179+
move_data: &MoveData<'tcx>,
180+
has_uniform_drop_state: U,
181+
mut callback: F)
182+
where F: FnMut(MovePathIndex, DropFlagState), U: Fn(&Place<'tcx>) -> bool
173183
{
174-
let move_data = &ctxt.move_data;
175184
for arg in mir.args_iter() {
176-
let place = mir::Place::Local(arg);
185+
let place = Place::Local(arg);
177186
let lookup_result = move_data.rev_lookup.find(&place);
178-
on_lookup_result_bits(tcx, mir, move_data,
187+
on_lookup_result_bits(move_data,
179188
lookup_result,
189+
&has_uniform_drop_state,
180190
|mpi| callback(mpi, DropFlagState::Present));
181191
}
182192
}
183193

184-
pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
185-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
186-
mir: &Mir<'tcx>,
187-
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
188-
loc: Location,
189-
mut callback: F)
190-
where F: FnMut(MovePathIndex, DropFlagState)
194+
pub(crate) fn drop_flag_effects_for_location<'tcx, F, U>(move_data: &MoveData<'tcx>,
195+
loc: Location,
196+
has_uniform_drop_state: U,
197+
mut callback: F)
198+
where F: FnMut(MovePathIndex, DropFlagState), U: Fn(&Place<'tcx>) -> bool
191199
{
192-
let move_data = &ctxt.move_data;
193200
debug!("drop_flag_effects_for_location({:?})", loc);
194201

195202
// first, move out of the RHS
196203
for mi in &move_data.loc_map[loc] {
197204
let path = mi.move_path_index(move_data);
198205
debug!("moving out of path {:?}", move_data.move_paths[path]);
199206

200-
on_all_children_bits(tcx, mir, move_data,
207+
on_all_children_bits(move_data,
201208
path,
209+
&has_uniform_drop_state,
202210
|mpi| callback(mpi, DropFlagState::Absent))
203211
}
204212

205213
debug!("drop_flag_effects: assignment for location({:?})", loc);
206214

207215
for_location_inits(
208-
tcx,
209-
mir,
210216
move_data,
211217
loc,
218+
has_uniform_drop_state,
212219
|mpi| callback(mpi, DropFlagState::Present)
213220
);
214221
}
215222

216-
pub(crate) fn for_location_inits<'a, 'gcx, 'tcx, F>(
217-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
218-
mir: &Mir<'tcx>,
223+
pub(crate) fn for_location_inits<'tcx, F, U>(
219224
move_data: &MoveData<'tcx>,
220225
loc: Location,
226+
has_uniform_drop_state: U,
221227
mut callback: F)
222-
where F: FnMut(MovePathIndex)
228+
where F: FnMut(MovePathIndex), U: Fn(&Place<'tcx>) -> bool
223229
{
224230
for ii in &move_data.init_loc_map[loc] {
225231
let init = move_data.inits[*ii];
226232
match init.kind {
227233
InitKind::Deep => {
228234
let path = init.path;
229235

230-
on_all_children_bits(tcx, mir, move_data,
231-
path,
232-
&mut callback)
236+
on_all_children_bits(move_data,
237+
path,
238+
&has_uniform_drop_state,
239+
&mut callback)
233240
},
234241
InitKind::Shallow => {
235242
let mpi = init.path;

0 commit comments

Comments
 (0)