@@ -73,7 +73,10 @@ pub struct FulfillmentContext<'tcx> {
7373#[ derive( Clone , Debug ) ]
7474pub struct PendingPredicateObligation < ' tcx > {
7575 pub obligation : PredicateObligation < ' tcx > ,
76- pub stalled_on : Vec < ty:: InferTy > ,
76+ // FIXME(eddyb) look into whether this could be a `SmallVec`.
77+ // Judging by the comment in `process_obligation`, the 1-element
78+ // case is common so this could be a `SmallVec<[_; 1]>`.
79+ pub stalled_on : Vec < Ty < ' tcx > > ,
7780}
7881
7982// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -266,8 +269,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
266269 // Match arms are in order of frequency, which matters because this
267270 // code is so hot. 1 and 0 dominate; 2+ is fairly rare.
268271 1 => {
269- let infer = pending_obligation. stalled_on [ 0 ] ;
270- ShallowResolver :: new ( self . selcx . infcx ( ) ) . shallow_resolve_changed ( infer)
272+ let unresolved = pending_obligation. stalled_on [ 0 ] ;
273+ match unresolved. kind {
274+ ty:: Infer ( infer) => {
275+ ShallowResolver :: new ( self . selcx . infcx ( ) ) . shallow_resolve_changed ( infer)
276+ }
277+ _ => unreachable ! ( ) ,
278+ }
271279 }
272280 0 => {
273281 // In this case we haven't changed, but wish to make a change.
@@ -277,9 +285,16 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
277285 // This `for` loop was once a call to `all()`, but this lower-level
278286 // form was a perf win. See #64545 for details.
279287 ( || {
280- for & infer in & pending_obligation. stalled_on {
281- if ShallowResolver :: new ( self . selcx . infcx ( ) ) . shallow_resolve_changed ( infer) {
282- return true ;
288+ for & unresolved in & pending_obligation. stalled_on {
289+ match unresolved. kind {
290+ ty:: Infer ( infer) => {
291+ if ShallowResolver :: new ( self . selcx . infcx ( ) )
292+ . shallow_resolve_changed ( infer)
293+ {
294+ return true ;
295+ }
296+ }
297+ _ => unreachable ! ( ) ,
283298 }
284299 }
285300 false
@@ -309,13 +324,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
309324
310325 debug ! ( "process_obligation: obligation = {:?} cause = {:?}" , obligation, obligation. cause) ;
311326
312- fn infer_ty ( ty : Ty < ' tcx > ) -> ty:: InferTy {
313- match ty. kind {
314- ty:: Infer ( infer) => infer,
315- _ => panic ! ( ) ,
316- }
317- }
318-
319327 match obligation. predicate {
320328 ty:: Predicate :: Trait ( ref data, _) => {
321329 let trait_obligation = obligation. with ( data. clone ( ) ) ;
@@ -351,7 +359,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
351359 // trait selection is because we don't have enough
352360 // information about the types in the trait.
353361 pending_obligation. stalled_on =
354- trait_ref_type_vars ( self . selcx , data. to_poly_trait_ref ( ) ) ;
362+ trait_ref_infer_vars ( self . selcx , data. to_poly_trait_ref ( ) ) ;
355363
356364 debug ! (
357365 "process_predicate: pending obligation {:?} now stalled on {:?}" ,
@@ -429,7 +437,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
429437 Ok ( None ) => {
430438 let tcx = self . selcx . tcx ( ) ;
431439 pending_obligation. stalled_on =
432- trait_ref_type_vars ( self . selcx , data. to_poly_trait_ref ( tcx) ) ;
440+ trait_ref_infer_vars ( self . selcx , data. to_poly_trait_ref ( tcx) ) ;
433441 ProcessResult :: Unchanged
434442 }
435443 Ok ( Some ( os) ) => ProcessResult :: Changed ( mk_pending ( os) ) ,
@@ -467,7 +475,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
467475 obligation. cause . span ,
468476 ) {
469477 None => {
470- pending_obligation. stalled_on = vec ! [ infer_ty( ty) ] ;
478+ assert ! ( matches!( ty. kind, ty:: Infer ( _) ) ) ;
479+ pending_obligation. stalled_on = vec ! [ ty] ;
471480 ProcessResult :: Unchanged
472481 }
473482 Some ( os) => ProcessResult :: Changed ( mk_pending ( os) ) ,
@@ -482,10 +491,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
482491 ) {
483492 None => {
484493 // None means that both are unresolved.
485- pending_obligation . stalled_on = vec ! [
486- infer_ty ( subtype. skip_binder( ) . a ) ,
487- infer_ty ( subtype . skip_binder ( ) . b ) ,
488- ] ;
494+ assert ! ( matches! ( subtype . skip_binder ( ) . a . kind , ty :: Infer ( _ ) ) ) ;
495+ assert ! ( matches! ( subtype. skip_binder( ) . b . kind , ty :: Infer ( _ ) ) ) ;
496+ pending_obligation . stalled_on =
497+ vec ! [ subtype . skip_binder ( ) . a , subtype . skip_binder ( ) . b ] ;
489498 ProcessResult :: Unchanged
490499 }
491500 Some ( Ok ( ok) ) => ProcessResult :: Changed ( mk_pending ( ok. obligations ) ) ,
@@ -534,20 +543,19 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
534543 }
535544}
536545
537- /// Returns the set of type variables contained in a trait ref
538- fn trait_ref_type_vars < ' a , ' tcx > (
546+ /// Returns the set of inference variables contained in a trait ref.
547+ fn trait_ref_infer_vars < ' a , ' tcx > (
539548 selcx : & mut SelectionContext < ' a , ' tcx > ,
540- t : ty:: PolyTraitRef < ' tcx > ,
541- ) -> Vec < ty :: InferTy > {
542- t . skip_binder ( ) // ok b/c this check doesn't care about regions
549+ ty : ty:: PolyTraitRef < ' tcx > ,
550+ ) -> Vec < Ty < ' tcx > > {
551+ ty . skip_binder ( ) // ok b/c this check doesn't care about regions
543552 . input_types ( )
544- . map ( |t| selcx. infcx ( ) . resolve_vars_if_possible ( & t) )
545- . filter ( |t| t. has_infer_types ( ) )
546- . flat_map ( |t| t. walk ( ) )
547- . filter_map ( |t| match t. kind {
548- ty:: Infer ( infer) => Some ( infer) ,
549- _ => None ,
550- } )
553+ . map ( |ty| selcx. infcx ( ) . resolve_vars_if_possible ( & ty) )
554+ // FIXME(eddyb) try using `maybe_walk` to skip *all* subtrees that
555+ // don't contain inference variables, not just the outermost level.
556+ . filter ( |ty| ty. has_infer_types ( ) )
557+ . flat_map ( |ty| ty. walk ( ) )
558+ . filter ( |ty| matches ! ( ty. kind, ty:: Infer ( _) ) )
551559 . collect ( )
552560}
553561
0 commit comments