1
Fork 0

Address code review comments

1. Add test case for partial drops
2. Simplify code in `propagate_to_fixpoint` and remove most clones
3. Clean up PostOrderIndex creation
This commit is contained in:
Eric Holk 2021-12-13 10:47:28 -08:00
parent 006f547162
commit 30e1b1e92e
2 changed files with 44 additions and 23 deletions

View file

@ -34,13 +34,13 @@ use crate::expr_use_visitor;
/// record the parent expression, which is the point where the drop actually takes place. /// record the parent expression, which is the point where the drop actually takes place.
pub struct ExprUseDelegate<'tcx> { pub struct ExprUseDelegate<'tcx> {
hir: Map<'tcx>, hir: Map<'tcx>,
/// Records the point at which an expression or local variable is dropped. /// Records the variables/expressions that are dropped by a given expression.
/// ///
/// The key is the hir-id of the expression, and the value is a set or hir-ids for variables /// The key is the hir-id of the expression, and the value is a set or hir-ids for variables
/// or values that are consumed by that expression. /// or values that are consumed by that expression.
/// ///
/// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is /// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is
/// not considered a drop of `x`. /// not considered a drop of `x`, although it would be a drop of `x.y`.
consumed_places: HirIdMap<HirIdSet>, consumed_places: HirIdMap<HirIdSet>,
/// A set of hir-ids of values or variables that are borrowed at some point within the body. /// A set of hir-ids of values or variables that are borrowed at some point within the body.
borrowed_places: HirIdSet, borrowed_places: HirIdSet,
@ -437,29 +437,29 @@ impl DropRanges {
let mut changed = false; let mut changed = false;
for id in self.nodes.indices() { for id in self.nodes.indices() {
let old_state = self.nodes[id].drop_state.clone(); let old_state = self.nodes[id].drop_state.clone();
if preds[id].len() != 0 { let mut new_state = if id.index() == 0 {
self.nodes[id].drop_state = self.nodes[preds[id][0]].drop_state.clone();
for pred in &preds[id][1..] {
let state = self.nodes[*pred].drop_state.clone();
self.nodes[id].drop_state.intersect(&state);
}
} else {
self.nodes[id].drop_state = if id.index() == 0 {
BitSet::new_empty(self.num_values()) BitSet::new_empty(self.num_values())
} else { } else {
// If we are not the start node and we have no predecessors, treat // If we are not the start node and we have no predecessors, treat
// everything as dropped because there's no way to get here anyway. // everything as dropped because there's no way to get here anyway.
BitSet::new_filled(self.num_values()) BitSet::new_filled(self.num_values())
}; };
};
for drop in &self.nodes[id].drops.clone() { for pred in &preds[id] {
self.nodes[id].drop_state.insert(*drop); let state = &self.nodes[*pred].drop_state;
} new_state.intersect(state);
for reinit in &self.nodes[id].reinits.clone() {
self.nodes[id].drop_state.remove(*reinit);
} }
changed |= old_state != self.nodes[id].drop_state; for drop in &self.nodes[id].drops {
new_state.insert(*drop);
}
for reinit in &self.nodes[id].reinits {
new_state.remove(*reinit);
}
changed |= old_state != new_state;
self.nodes[id].drop_state = new_state;
} }
changed changed
@ -476,7 +476,7 @@ impl DropRanges {
let mut preds = IndexVec::from_fn_n(|_| vec![], self.nodes.len()); let mut preds = IndexVec::from_fn_n(|_| vec![], self.nodes.len());
for (id, node) in self.nodes.iter_enumerated() { for (id, node) in self.nodes.iter_enumerated() {
if node.successors.len() == 0 && id.index() != self.nodes.len() - 1 { if node.successors.len() == 0 && id.index() != self.nodes.len() - 1 {
preds[<_>::from(id.index() + 1)].push(id); preds[id + 1].push(id);
} else { } else {
for succ in &node.successors { for succ in &node.successors {
preds[*succ].push(id); preds[*succ].push(id);
@ -501,7 +501,7 @@ impl<'a> dot::GraphWalk<'a> for DropRanges {
.iter_enumerated() .iter_enumerated()
.flat_map(|(i, node)| { .flat_map(|(i, node)| {
if node.successors.len() == 0 { if node.successors.len() == 0 {
vec![(i, PostOrderId::from_usize(i.index() + 1))] vec![(i, i + 1)]
} else { } else {
node.successors.iter().map(move |&s| (i, s)).collect() node.successors.iter().map(move |&s| (i, s)).collect()
} }

View file

@ -0,0 +1,21 @@
// check-pass
#![feature(negative_impls, generators)]
struct Foo;
impl !Send for Foo {}
struct Bar {
foo: Foo,
x: i32,
}
fn main() {
assert_send(|| {
let guard = Bar { foo: Foo, x: 42 };
drop(guard.foo);
yield;
})
}
fn assert_send<T: Send>(_: T) {}