@@ -151,7 +151,9 @@ pub struct ObligationForest<O: ForestObligation> {
151151 /// A cache of predicates that have been successfully completed.
152152 done_cache : FxHashSet < O :: Predicate > ,
153153
154- /// An cache of the nodes in `nodes`, indexed by predicate.
154+ /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately,
155+ /// its contents are not guaranteed to match those of `nodes`. See the
156+ /// comments in `process_obligation` for details.
155157 waiting_cache : FxHashMap < O :: Predicate , NodeIndex > ,
156158
157159 scratch : Option < Vec < usize > > ,
@@ -394,6 +396,11 @@ impl<O: ForestObligation> ObligationForest<O> {
394396
395397 debug ! ( "process_obligations: node {} == {:?}" , i, node) ;
396398
399+ // `processor.process_obligation` can modify the predicate within
400+ // `node.obligation`, and that predicate is the key used for
401+ // `self.waiting_cache`. This means that `self.waiting_cache` can
402+ // get out of sync with `nodes`. It's not very common, but it does
403+ // happen, and code in `compress` has to allow for it.
397404 let result = match node. state . get ( ) {
398405 NodeState :: Pending => processor. process_obligation ( & mut node. obligation ) ,
399406 _ => continue
@@ -621,7 +628,10 @@ impl<O: ForestObligation> ObligationForest<O> {
621628 }
622629 }
623630 NodeState :: Done => {
624- // Avoid cloning the key (predicate) in case it exists in the waiting cache
631+ // This lookup can fail because the contents of
632+ // `self.waiting_cache` is not guaranteed to match those of
633+ // `self.nodes`. See the comment in `process_obligation`
634+ // for more details.
625635 if let Some ( ( predicate, _) ) = self . waiting_cache
626636 . remove_entry ( node. obligation . as_predicate ( ) )
627637 {
@@ -703,6 +713,8 @@ impl<O: ForestObligation> ObligationForest<O> {
703713 }
704714 }
705715
716+ // This updating of `self.waiting_cache` is necessary because the
717+ // removal of nodes within `compress` can fail. See above.
706718 let mut kill_list = vec ! [ ] ;
707719 for ( predicate, index) in & mut self . waiting_cache {
708720 let new_i = node_rewrites[ index. index ( ) ] ;
0 commit comments