Skip to content

Commit 773ce53

Browse files
committedJun 26, 2018
Auto merge of #51613 - nnethercote:ob-forest-cleanup, r=nikomatsakis
Obligation forest cleanup While looking at this code I was scratching my head about whether a node could appear in both `parent` and `dependents`. Turns out it can, but it's not useful to do so, so this PR cleans things up so it's no longer possible.
2 parents 7d2fa4a + 70d22fa commit 773ce53

File tree

1 file changed

+18
-21
lines changed
  • src/librustc_data_structures/obligation_forest

1 file changed

+18
-21
lines changed
 

‎src/librustc_data_structures/obligation_forest/mod.rs

+18-21
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ struct Node<O> {
9191
obligation: O,
9292
state: Cell<NodeState>,
9393

94-
/// Obligations that depend on this obligation for their
95-
/// completion. They must all be in a non-pending state.
96-
dependents: Vec<NodeIndex>,
9794
/// The parent of a node - the original obligation of
9895
/// which it is a subobligation. Except for error reporting,
99-
/// this is just another member of `dependents`.
96+
/// it is just like any member of `dependents`.
10097
parent: Option<NodeIndex>,
98+
99+
/// Obligations that depend on this obligation for their
100+
/// completion. They must all be in a non-pending state.
101+
dependents: Vec<NodeIndex>,
101102
}
102103

103104
/// The state of one node in some tree within the forest. This
@@ -193,15 +194,18 @@ impl<O: ForestObligation> ObligationForest<O> {
193194
Entry::Occupied(o) => {
194195
debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
195196
obligation, parent, o.get());
197+
let node = &mut self.nodes[o.get().get()];
196198
if let Some(parent) = parent {
197-
if self.nodes[o.get().get()].dependents.contains(&parent) {
198-
debug!("register_obligation_at({:?}, {:?}) - duplicate subobligation",
199-
obligation, parent);
200-
} else {
201-
self.nodes[o.get().get()].dependents.push(parent);
199+
// If the node is already in `waiting_cache`, it's already
200+
// been marked with a parent. (It's possible that parent
201+
// has been cleared by `apply_rewrites`, though.) So just
202+
// dump `parent` into `node.dependents`... unless it's
203+
// already in `node.dependents` or `node.parent`.
204+
if !node.dependents.contains(&parent) && Some(parent) != node.parent {
205+
node.dependents.push(parent);
202206
}
203207
}
204-
if let NodeState::Error = self.nodes[o.get().get()].state.get() {
208+
if let NodeState::Error = node.state.get() {
205209
Err(())
206210
} else {
207211
Ok(())
@@ -380,10 +384,7 @@ impl<O: ForestObligation> ObligationForest<O> {
380384
NodeState::Success => {
381385
node.state.set(NodeState::OnDfsStack);
382386
stack.push(index);
383-
if let Some(parent) = node.parent {
384-
self.find_cycles_from_node(stack, processor, parent.get());
385-
}
386-
for dependent in &node.dependents {
387+
for dependent in node.parent.iter().chain(node.dependents.iter()) {
387388
self.find_cycles_from_node(stack, processor, dependent.get());
388389
}
389390
stack.pop();
@@ -427,7 +428,7 @@ impl<O: ForestObligation> ObligationForest<O> {
427428
}
428429

429430
error_stack.extend(
430-
node.dependents.iter().cloned().chain(node.parent).map(|x| x.get())
431+
node.parent.iter().chain(node.dependents.iter()).map(|x| x.get())
431432
);
432433
}
433434

@@ -437,11 +438,7 @@ impl<O: ForestObligation> ObligationForest<O> {
437438

438439
#[inline]
439440
fn mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
440-
if let Some(parent) = node.parent {
441-
self.mark_as_waiting_from(&self.nodes[parent.get()]);
442-
}
443-
444-
for dependent in &node.dependents {
441+
for dependent in node.parent.iter().chain(node.dependents.iter()) {
445442
self.mark_as_waiting_from(&self.nodes[dependent.get()]);
446443
}
447444
}
@@ -588,8 +585,8 @@ impl<O> Node<O> {
588585
fn new(parent: Option<NodeIndex>, obligation: O) -> Node<O> {
589586
Node {
590587
obligation,
591-
parent,
592588
state: Cell::new(NodeState::Pending),
589+
parent,
593590
dependents: vec![],
594591
}
595592
}

0 commit comments

Comments
 (0)
Please sign in to comment.