@@ -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