Skip to content

Commit 30e1b1e

Browse files
committed
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
1 parent 006f547 commit 30e1b1e

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ use crate::expr_use_visitor;
3434
/// record the parent expression, which is the point where the drop actually takes place.
3535
pub struct ExprUseDelegate<'tcx> {
3636
hir: Map<'tcx>,
37-
/// Records the point at which an expression or local variable is dropped.
37+
/// Records the variables/expressions that are dropped by a given expression.
3838
///
3939
/// The key is the hir-id of the expression, and the value is a set or hir-ids for variables
4040
/// or values that are consumed by that expression.
4141
///
4242
/// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is
43-
/// not considered a drop of `x`.
43+
/// not considered a drop of `x`, although it would be a drop of `x.y`.
4444
consumed_places: HirIdMap<HirIdSet>,
4545
/// A set of hir-ids of values or variables that are borrowed at some point within the body.
4646
borrowed_places: HirIdSet,
@@ -437,29 +437,29 @@ impl DropRanges {
437437
let mut changed = false;
438438
for id in self.nodes.indices() {
439439
let old_state = self.nodes[id].drop_state.clone();
440-
if preds[id].len() != 0 {
441-
self.nodes[id].drop_state = self.nodes[preds[id][0]].drop_state.clone();
442-
for pred in &preds[id][1..] {
443-
let state = self.nodes[*pred].drop_state.clone();
444-
self.nodes[id].drop_state.intersect(&state);
445-
}
440+
let mut new_state = if id.index() == 0 {
441+
BitSet::new_empty(self.num_values())
446442
} else {
447-
self.nodes[id].drop_state = if id.index() == 0 {
448-
BitSet::new_empty(self.num_values())
449-
} else {
450-
// If we are not the start node and we have no predecessors, treat
451-
// everything as dropped because there's no way to get here anyway.
452-
BitSet::new_filled(self.num_values())
453-
};
443+
// If we are not the start node and we have no predecessors, treat
444+
// everything as dropped because there's no way to get here anyway.
445+
BitSet::new_filled(self.num_values())
454446
};
455-
for drop in &self.nodes[id].drops.clone() {
456-
self.nodes[id].drop_state.insert(*drop);
447+
448+
for pred in &preds[id] {
449+
let state = &self.nodes[*pred].drop_state;
450+
new_state.intersect(state);
451+
}
452+
453+
for drop in &self.nodes[id].drops {
454+
new_state.insert(*drop);
457455
}
458-
for reinit in &self.nodes[id].reinits.clone() {
459-
self.nodes[id].drop_state.remove(*reinit);
456+
457+
for reinit in &self.nodes[id].reinits {
458+
new_state.remove(*reinit);
460459
}
461460

462-
changed |= old_state != self.nodes[id].drop_state;
461+
changed |= old_state != new_state;
462+
self.nodes[id].drop_state = new_state;
463463
}
464464

465465
changed
@@ -476,7 +476,7 @@ impl DropRanges {
476476
let mut preds = IndexVec::from_fn_n(|_| vec![], self.nodes.len());
477477
for (id, node) in self.nodes.iter_enumerated() {
478478
if node.successors.len() == 0 && id.index() != self.nodes.len() - 1 {
479-
preds[<_>::from(id.index() + 1)].push(id);
479+
preds[id + 1].push(id);
480480
} else {
481481
for succ in &node.successors {
482482
preds[*succ].push(id);
@@ -501,7 +501,7 @@ impl<'a> dot::GraphWalk<'a> for DropRanges {
501501
.iter_enumerated()
502502
.flat_map(|(i, node)| {
503503
if node.successors.len() == 0 {
504-
vec![(i, PostOrderId::from_usize(i.index() + 1))]
504+
vec![(i, i + 1)]
505505
} else {
506506
node.successors.iter().map(move |&s| (i, s)).collect()
507507
}

src/test/ui/generator/partial-drop.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
#![feature(negative_impls, generators)]
4+
5+
struct Foo;
6+
impl !Send for Foo {}
7+
8+
struct Bar {
9+
foo: Foo,
10+
x: i32,
11+
}
12+
13+
fn main() {
14+
assert_send(|| {
15+
let guard = Bar { foo: Foo, x: 42 };
16+
drop(guard.foo);
17+
yield;
18+
})
19+
}
20+
21+
fn assert_send<T: Send>(_: T) {}

0 commit comments

Comments
 (0)