@@ -407,20 +407,21 @@ where
407
407
// If we have run this goal before, and it was stalled, check that any of the goal's
408
408
// args have changed. Otherwise, we don't need to re-run the goal because it'll remain
409
409
// stalled, since it'll canonicalize the same way and evaluation is pure.
410
- if let Some ( stalled_on) = stalled_on
411
- && !stalled_on. stalled_vars . iter ( ) . any ( |value| self . delegate . is_changed_arg ( * value) )
412
- && !self
413
- . delegate
414
- . opaque_types_storage_num_entries ( )
415
- . needs_reevaluation ( stalled_on. num_opaques )
410
+ if let Some ( GoalStalledOn { num_opaques, ref stalled_vars, ref sub_roots, stalled_cause } ) =
411
+ stalled_on
412
+ && !stalled_vars. iter ( ) . any ( |value| self . delegate . is_changed_arg ( * value) )
413
+ && !sub_roots
414
+ . iter ( )
415
+ . any ( |& vid| self . delegate . sub_unification_table_root_var ( vid) != vid)
416
+ && !self . delegate . opaque_types_storage_num_entries ( ) . needs_reevaluation ( num_opaques)
416
417
{
417
418
return Ok ( (
418
419
NestedNormalizationGoals :: empty ( ) ,
419
420
GoalEvaluation {
420
421
goal,
421
- certainty : Certainty :: Maybe ( stalled_on . stalled_cause ) ,
422
+ certainty : Certainty :: Maybe ( stalled_cause) ,
422
423
has_changed : HasChanged :: No ,
423
- stalled_on : Some ( stalled_on ) ,
424
+ stalled_on,
424
425
} ,
425
426
) ) ;
426
427
}
@@ -476,16 +477,6 @@ where
476
477
HasChanged :: No => {
477
478
let mut stalled_vars = orig_values;
478
479
479
- // Remove the canonicalized universal vars, since we only care about stalled existentials.
480
- stalled_vars. retain ( |arg| match arg. kind ( ) {
481
- ty:: GenericArgKind :: Type ( ty) => matches ! ( ty. kind( ) , ty:: Infer ( _) ) ,
482
- ty:: GenericArgKind :: Const ( ct) => {
483
- matches ! ( ct. kind( ) , ty:: ConstKind :: Infer ( _) )
484
- }
485
- // Lifetimes can never stall goals.
486
- ty:: GenericArgKind :: Lifetime ( _) => false ,
487
- } ) ;
488
-
489
480
// Remove the unconstrained RHS arg, which is expected to have changed.
490
481
if let Some ( normalizes_to) = goal. predicate . as_normalizes_to ( ) {
491
482
let normalizes_to = normalizes_to. skip_binder ( ) ;
@@ -497,6 +488,27 @@ where
497
488
stalled_vars. swap_remove ( idx) ;
498
489
}
499
490
491
+ // Remove the canonicalized universal vars, since we only care about stalled existentials.
492
+ let mut sub_roots = Vec :: new ( ) ;
493
+ stalled_vars. retain ( |arg| match arg. kind ( ) {
494
+ // Lifetimes can never stall goals.
495
+ ty:: GenericArgKind :: Lifetime ( _) => false ,
496
+ ty:: GenericArgKind :: Type ( ty) => match ty. kind ( ) {
497
+ ty:: Infer ( ty:: TyVar ( vid) ) => {
498
+ sub_roots. push ( self . delegate . sub_unification_table_root_var ( vid) ) ;
499
+ true
500
+ }
501
+ ty:: Infer ( _) => true ,
502
+ ty:: Param ( _) | ty:: Placeholder ( _) => false ,
503
+ _ => unreachable ! ( "unexpected orig_value: {ty:?}" ) ,
504
+ } ,
505
+ ty:: GenericArgKind :: Const ( ct) => match ct. kind ( ) {
506
+ ty:: ConstKind :: Infer ( _) => true ,
507
+ ty:: ConstKind :: Param ( _) | ty:: ConstKind :: Placeholder ( _) => false ,
508
+ _ => unreachable ! ( "unexpected orig_value: {ct:?}" ) ,
509
+ } ,
510
+ } ) ;
511
+
500
512
Some ( GoalStalledOn {
501
513
num_opaques : canonical_goal
502
514
. canonical
@@ -505,6 +517,7 @@ where
505
517
. opaque_types
506
518
. len ( ) ,
507
519
stalled_vars,
520
+ sub_roots,
508
521
stalled_cause,
509
522
} )
510
523
}
0 commit comments