@@ -91,13 +91,14 @@ struct Node<O> {
91
91
obligation : O ,
92
92
state : Cell < NodeState > ,
93
93
94
- /// Obligations that depend on this obligation for their
95
- /// completion. They must all be in a non-pending state.
96
- dependents : Vec < NodeIndex > ,
97
94
/// The parent of a node - the original obligation of
98
95
/// 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`.
100
97
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 > ,
101
102
}
102
103
103
104
/// The state of one node in some tree within the forest. This
@@ -193,15 +194,18 @@ impl<O: ForestObligation> ObligationForest<O> {
193
194
Entry :: Occupied ( o) => {
194
195
debug ! ( "register_obligation_at({:?}, {:?}) - duplicate of {:?}!" ,
195
196
obligation, parent, o. get( ) ) ;
197
+ let node = & mut self . nodes [ o. get ( ) . get ( ) ] ;
196
198
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) ;
202
206
}
203
207
}
204
- if let NodeState :: Error = self . nodes [ o . get ( ) . get ( ) ] . state . get ( ) {
208
+ if let NodeState :: Error = node . state . get ( ) {
205
209
Err ( ( ) )
206
210
} else {
207
211
Ok ( ( ) )
@@ -380,10 +384,7 @@ impl<O: ForestObligation> ObligationForest<O> {
380
384
NodeState :: Success => {
381
385
node. state . set ( NodeState :: OnDfsStack ) ;
382
386
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 ( ) ) {
387
388
self . find_cycles_from_node ( stack, processor, dependent. get ( ) ) ;
388
389
}
389
390
stack. pop ( ) ;
@@ -427,7 +428,7 @@ impl<O: ForestObligation> ObligationForest<O> {
427
428
}
428
429
429
430
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 ( ) )
431
432
) ;
432
433
}
433
434
@@ -437,11 +438,7 @@ impl<O: ForestObligation> ObligationForest<O> {
437
438
438
439
#[ inline]
439
440
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 ( ) ) {
445
442
self . mark_as_waiting_from ( & self . nodes [ dependent. get ( ) ] ) ;
446
443
}
447
444
}
@@ -588,8 +585,8 @@ impl<O> Node<O> {
588
585
fn new ( parent : Option < NodeIndex > , obligation : O ) -> Node < O > {
589
586
Node {
590
587
obligation,
591
- parent,
592
588
state : Cell :: new ( NodeState :: Pending ) ,
589
+ parent,
593
590
dependents : vec ! [ ] ,
594
591
}
595
592
}
0 commit comments