@@ -73,7 +73,10 @@ pub struct FulfillmentContext<'tcx> {
73
73
#[ derive( Clone , Debug ) ]
74
74
pub struct PendingPredicateObligation < ' tcx > {
75
75
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 > > ,
77
80
}
78
81
79
82
// `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> {
266
269
// Match arms are in order of frequency, which matters because this
267
270
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
268
271
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
+ }
271
279
}
272
280
0 => {
273
281
// 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> {
277
285
// This `for` loop was once a call to `all()`, but this lower-level
278
286
// form was a perf win. See #64545 for details.
279
287
( || {
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 ! ( ) ,
283
298
}
284
299
}
285
300
false
@@ -309,13 +324,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
309
324
310
325
debug ! ( "process_obligation: obligation = {:?} cause = {:?}" , obligation, obligation. cause) ;
311
326
312
- fn infer_ty ( ty : Ty < ' tcx > ) -> ty:: InferTy {
313
- match ty. kind {
314
- ty:: Infer ( infer) => infer,
315
- _ => panic ! ( ) ,
316
- }
317
- }
318
-
319
327
match obligation. predicate {
320
328
ty:: Predicate :: Trait ( ref data, _) => {
321
329
let trait_obligation = obligation. with ( data. clone ( ) ) ;
@@ -351,7 +359,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
351
359
// trait selection is because we don't have enough
352
360
// information about the types in the trait.
353
361
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 ( ) ) ;
355
363
356
364
debug ! (
357
365
"process_predicate: pending obligation {:?} now stalled on {:?}" ,
@@ -429,7 +437,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
429
437
Ok ( None ) => {
430
438
let tcx = self . selcx . tcx ( ) ;
431
439
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) ) ;
433
441
ProcessResult :: Unchanged
434
442
}
435
443
Ok ( Some ( os) ) => ProcessResult :: Changed ( mk_pending ( os) ) ,
@@ -467,7 +475,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
467
475
obligation. cause . span ,
468
476
) {
469
477
None => {
470
- pending_obligation. stalled_on = vec ! [ infer_ty( ty) ] ;
478
+ assert ! ( matches!( ty. kind, ty:: Infer ( _) ) ) ;
479
+ pending_obligation. stalled_on = vec ! [ ty] ;
471
480
ProcessResult :: Unchanged
472
481
}
473
482
Some ( os) => ProcessResult :: Changed ( mk_pending ( os) ) ,
@@ -482,10 +491,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
482
491
) {
483
492
None => {
484
493
// 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 ] ;
489
498
ProcessResult :: Unchanged
490
499
}
491
500
Some ( Ok ( ok) ) => ProcessResult :: Changed ( mk_pending ( ok. obligations ) ) ,
@@ -534,20 +543,19 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
534
543
}
535
544
}
536
545
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 > (
539
548
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
543
552
. 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 ( _) ) )
551
559
. collect ( )
552
560
}
553
561
0 commit comments