@@ -499,10 +499,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
499
499
) {
500
500
Ok ( ( ) ) => ProcessResult :: Changed ( vec ! [ ] ) ,
501
501
Err ( ErrorHandled :: TooGeneric ) => {
502
- pending_obligation. stalled_on = substs
503
- . iter ( )
504
- . filter_map ( TyOrConstInferVar :: maybe_from_generic_arg)
505
- . collect ( ) ;
502
+ pending_obligation. stalled_on . clear ( ) ;
503
+ pending_obligation . stalled_on . extend (
504
+ substs . iter ( ) . filter_map ( TyOrConstInferVar :: maybe_from_generic_arg) ,
505
+ ) ;
506
506
ProcessResult :: Unchanged
507
507
}
508
508
Err ( e) => ProcessResult :: Error ( CodeSelectionError ( ConstEvalFailure ( e) ) ) ,
@@ -544,13 +544,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
544
544
) {
545
545
Ok ( val) => Ok ( Const :: from_value ( self . selcx . tcx ( ) , val, c. ty ) ) ,
546
546
Err ( ErrorHandled :: TooGeneric ) => {
547
- stalled_on. append (
548
- & mut substs
547
+ stalled_on. extend (
548
+ substs
549
549
. iter ( )
550
- . filter_map ( |arg| {
551
- TyOrConstInferVar :: maybe_from_generic_arg ( arg)
552
- } )
553
- . collect ( ) ,
550
+ . filter_map ( TyOrConstInferVar :: maybe_from_generic_arg) ,
554
551
) ;
555
552
Err ( ErrorHandled :: TooGeneric )
556
553
}
@@ -634,10 +631,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
634
631
// only reason we can fail to make progress on
635
632
// trait selection is because we don't have enough
636
633
// information about the types in the trait.
637
- * stalled_on = substs_infer_vars (
634
+ stalled_on. clear ( ) ;
635
+ stalled_on. extend ( substs_infer_vars (
638
636
self . selcx ,
639
637
trait_obligation. predicate . map_bound ( |pred| pred. trait_ref . substs ) ,
640
- ) ;
638
+ ) ) ;
641
639
642
640
debug ! (
643
641
"process_predicate: pending obligation {:?} now stalled on {:?}" ,
@@ -664,10 +662,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
664
662
match project:: poly_project_and_unify_type ( self . selcx , & project_obligation) {
665
663
Ok ( Ok ( Some ( os) ) ) => ProcessResult :: Changed ( mk_pending ( os) ) ,
666
664
Ok ( Ok ( None ) ) => {
667
- * stalled_on = substs_infer_vars (
665
+ stalled_on. clear ( ) ;
666
+ stalled_on. extend ( substs_infer_vars (
668
667
self . selcx ,
669
668
project_obligation. predicate . map_bound ( |pred| pred. projection_ty . substs ) ,
670
- ) ;
669
+ ) ) ;
671
670
ProcessResult :: Unchanged
672
671
}
673
672
// Let the caller handle the recursion
@@ -683,18 +682,24 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
683
682
fn substs_infer_vars < ' a , ' tcx > (
684
683
selcx : & mut SelectionContext < ' a , ' tcx > ,
685
684
substs : ty:: Binder < SubstsRef < ' tcx > > ,
686
- ) -> Vec < TyOrConstInferVar < ' tcx > > {
685
+ ) -> impl Iterator < Item = TyOrConstInferVar < ' tcx > > {
687
686
selcx
688
687
. infcx ( )
689
688
. resolve_vars_if_possible ( substs)
690
689
. skip_binder ( ) // ok because this check doesn't care about regions
691
690
. iter ( )
692
- // FIXME(eddyb) try using `skip_current_subtree` to skip everything that
693
- // doesn't contain inference variables, not just the outermost level.
694
691
. filter ( |arg| arg. has_infer_types_or_consts ( ) )
695
- . flat_map ( |arg| arg. walk ( ) )
692
+ . flat_map ( |arg| {
693
+ let mut walker = arg. walk ( ) ;
694
+ while let Some ( c) = walker. next ( ) {
695
+ if !c. has_infer_types_or_consts ( ) {
696
+ walker. visited . remove ( & c) ;
697
+ walker. skip_current_subtree ( ) ;
698
+ }
699
+ }
700
+ walker. visited . into_iter ( )
701
+ } )
696
702
. filter_map ( TyOrConstInferVar :: maybe_from_generic_arg)
697
- . collect ( )
698
703
}
699
704
700
705
fn to_fulfillment_error < ' tcx > (
0 commit comments