10
10
11
11
use dep_graph:: DepGraph ;
12
12
use middle:: infer:: InferCtxt ;
13
- use middle:: ty:: { self , Ty , TypeFoldable } ;
13
+ use middle:: ty:: { self , Ty , TypeFoldable , ToPolyTraitRef } ;
14
14
use rustc_data_structures:: obligation_forest:: { Backtrace , ObligationForest , Error } ;
15
15
use std:: iter;
16
16
use syntax:: ast;
@@ -417,6 +417,21 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
417
417
}
418
418
}
419
419
420
+
421
+ /// Return the set of type variables contained in a trait ref
422
+ fn trait_ref_type_vars < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
423
+ t : ty:: PolyTraitRef < ' tcx > ) -> Vec < Ty < ' tcx > >
424
+ {
425
+ t. skip_binder ( ) // ok b/c this check doesn't care about regions
426
+ . input_types ( )
427
+ . iter ( )
428
+ . map ( |t| selcx. infcx ( ) . resolve_type_vars_if_possible ( t) )
429
+ . filter ( |t| t. has_infer_types ( ) )
430
+ . flat_map ( |t| t. walk ( ) )
431
+ . filter ( |t| match t. sty { ty:: TyInfer ( _) => true , _ => false } )
432
+ . collect ( )
433
+ }
434
+
420
435
/// Processes a predicate obligation and returns either:
421
436
/// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true
422
437
/// - `Ok(None)` if we don't have enough info to be sure
@@ -433,7 +448,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
433
448
// doing more work yet
434
449
if !pending_obligation. stalled_on . is_empty ( ) {
435
450
if pending_obligation. stalled_on . iter ( ) . all ( |& ty| {
436
- let resolved_ty = selcx. infcx ( ) . resolve_type_vars_if_possible ( & ty) ;
451
+ let resolved_ty = selcx. infcx ( ) . shallow_resolve ( & ty) ;
437
452
resolved_ty == ty // nothing changed here
438
453
} ) {
439
454
debug ! ( "process_predicate: pending obligation {:?} still stalled on {:?}" ,
@@ -493,14 +508,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
493
508
// of its type, and those types are resolved at
494
509
// the same time.
495
510
pending_obligation. stalled_on =
496
- data. skip_binder ( ) // ok b/c this check doesn't care about regions
497
- . input_types ( )
498
- . iter ( )
499
- . map ( |t| selcx. infcx ( ) . resolve_type_vars_if_possible ( t) )
500
- . filter ( |t| t. has_infer_types ( ) )
501
- . flat_map ( |t| t. walk ( ) )
502
- . filter ( |t| match t. sty { ty:: TyInfer ( _) => true , _ => false } )
503
- . collect ( ) ;
511
+ trait_ref_type_vars ( selcx, data. to_poly_trait_ref ( ) ) ;
504
512
505
513
debug ! ( "process_predicate: pending obligation {:?} now stalled on {:?}" ,
506
514
selcx. infcx( ) . resolve_type_vars_if_possible( obligation) ,
@@ -568,6 +576,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
568
576
ty:: Predicate :: Projection ( ref data) => {
569
577
let project_obligation = obligation. with ( data. clone ( ) ) ;
570
578
match project:: poly_project_and_unify_type ( selcx, & project_obligation) {
579
+ Ok ( None ) => {
580
+ pending_obligation. stalled_on =
581
+ trait_ref_type_vars ( selcx, data. to_poly_trait_ref ( ) ) ;
582
+ Ok ( None )
583
+ }
571
584
Ok ( v) => Ok ( v) ,
572
585
Err ( e) => Err ( CodeProjectionError ( e) )
573
586
}
@@ -582,8 +595,14 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
582
595
}
583
596
584
597
ty:: Predicate :: WellFormed ( ty) => {
585
- Ok ( ty:: wf:: obligations ( selcx. infcx ( ) , obligation. cause . body_id ,
586
- ty, obligation. cause . span ) )
598
+ match ty:: wf:: obligations ( selcx. infcx ( ) , obligation. cause . body_id ,
599
+ ty, obligation. cause . span ) {
600
+ None => {
601
+ pending_obligation. stalled_on = vec ! [ ty] ;
602
+ Ok ( None )
603
+ }
604
+ s => Ok ( s)
605
+ }
587
606
}
588
607
}
589
608
}
0 commit comments