@@ -499,10 +499,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
499499 ) {
500500 Ok ( ( ) ) => ProcessResult :: Changed ( vec ! [ ] ) ,
501501 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+ ) ;
506506 ProcessResult :: Unchanged
507507 }
508508 Err ( e) => ProcessResult :: Error ( CodeSelectionError ( ConstEvalFailure ( e) ) ) ,
@@ -544,13 +544,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
544544 ) {
545545 Ok ( val) => Ok ( Const :: from_value ( self . selcx . tcx ( ) , val, c. ty ) ) ,
546546 Err ( ErrorHandled :: TooGeneric ) => {
547- stalled_on. append (
548- & mut substs
547+ stalled_on. extend (
548+ substs
549549 . iter ( )
550- . filter_map ( |arg| {
551- TyOrConstInferVar :: maybe_from_generic_arg ( arg)
552- } )
553- . collect ( ) ,
550+ . filter_map ( TyOrConstInferVar :: maybe_from_generic_arg) ,
554551 ) ;
555552 Err ( ErrorHandled :: TooGeneric )
556553 }
@@ -634,10 +631,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
634631 // only reason we can fail to make progress on
635632 // trait selection is because we don't have enough
636633 // information about the types in the trait.
637- * stalled_on = substs_infer_vars (
634+ stalled_on. clear ( ) ;
635+ stalled_on. extend ( substs_infer_vars (
638636 self . selcx ,
639637 trait_obligation. predicate . map_bound ( |pred| pred. trait_ref . substs ) ,
640- ) ;
638+ ) ) ;
641639
642640 debug ! (
643641 "process_predicate: pending obligation {:?} now stalled on {:?}" ,
@@ -664,10 +662,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
664662 match project:: poly_project_and_unify_type ( self . selcx , & project_obligation) {
665663 Ok ( Ok ( Some ( os) ) ) => ProcessResult :: Changed ( mk_pending ( os) ) ,
666664 Ok ( Ok ( None ) ) => {
667- * stalled_on = substs_infer_vars (
665+ stalled_on. clear ( ) ;
666+ stalled_on. extend ( substs_infer_vars (
668667 self . selcx ,
669668 project_obligation. predicate . map_bound ( |pred| pred. projection_ty . substs ) ,
670- ) ;
669+ ) ) ;
671670 ProcessResult :: Unchanged
672671 }
673672 // Let the caller handle the recursion
@@ -683,18 +682,24 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
683682fn substs_infer_vars < ' a , ' tcx > (
684683 selcx : & mut SelectionContext < ' a , ' tcx > ,
685684 substs : ty:: Binder < SubstsRef < ' tcx > > ,
686- ) -> Vec < TyOrConstInferVar < ' tcx > > {
685+ ) -> impl Iterator < Item = TyOrConstInferVar < ' tcx > > {
687686 selcx
688687 . infcx ( )
689688 . resolve_vars_if_possible ( substs)
690689 . skip_binder ( ) // ok because this check doesn't care about regions
691690 . iter ( )
692- // FIXME(eddyb) try using `skip_current_subtree` to skip everything that
693- // doesn't contain inference variables, not just the outermost level.
694691 . 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+ } )
696702 . filter_map ( TyOrConstInferVar :: maybe_from_generic_arg)
697- . collect ( )
698703}
699704
700705fn to_fulfillment_error < ' tcx > (
0 commit comments