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;
@@ -378,6 +378,20 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
378
378
}
379
379
}
380
380
381
+ /// Return the set of type variables contained in a trait ref
382
+ fn trait_ref_type_vars < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
383
+ t : ty:: PolyTraitRef < ' tcx > ) -> Vec < Ty < ' tcx > >
384
+ {
385
+ t. skip_binder ( ) // ok b/c this check doesn't care about regions
386
+ . input_types ( )
387
+ . iter ( )
388
+ . map ( |t| selcx. infcx ( ) . resolve_type_vars_if_possible ( t) )
389
+ . filter ( |t| t. has_infer_types ( ) )
390
+ . flat_map ( |t| t. walk ( ) )
391
+ . filter ( |t| match t. sty { ty:: TyInfer ( _) => true , _ => false } )
392
+ . collect ( )
393
+ }
394
+
381
395
/// Processes a predicate obligation and returns either:
382
396
/// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true
383
397
/// - `Ok(None)` if we don't have enough info to be sure
@@ -394,7 +408,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
394
408
// doing more work yet
395
409
if !pending_obligation. stalled_on . is_empty ( ) {
396
410
if pending_obligation. stalled_on . iter ( ) . all ( |& ty| {
397
- let resolved_ty = selcx. infcx ( ) . resolve_type_vars_if_possible ( & ty) ;
411
+ let resolved_ty = selcx. infcx ( ) . shallow_resolve ( & ty) ;
398
412
resolved_ty == ty // nothing changed here
399
413
} ) {
400
414
debug ! ( "process_predicate: pending obligation {:?} still stalled on {:?}" ,
@@ -441,14 +455,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
441
455
// of its type, and those types are resolved at
442
456
// the same time.
443
457
pending_obligation. stalled_on =
444
- data. skip_binder ( ) // ok b/c this check doesn't care about regions
445
- . input_types ( )
446
- . iter ( )
447
- . map ( |t| selcx. infcx ( ) . resolve_type_vars_if_possible ( t) )
448
- . filter ( |t| t. has_infer_types ( ) )
449
- . flat_map ( |t| t. walk ( ) )
450
- . filter ( |t| match t. sty { ty:: TyInfer ( _) => true , _ => false } )
451
- . collect ( ) ;
458
+ trait_ref_type_vars ( selcx, data. to_poly_trait_ref ( ) ) ;
452
459
453
460
debug ! ( "process_predicate: pending obligation {:?} now stalled on {:?}" ,
454
461
selcx. infcx( ) . resolve_type_vars_if_possible( obligation) ,
@@ -514,6 +521,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
514
521
ty:: Predicate :: Projection ( ref data) => {
515
522
let project_obligation = obligation. with ( data. clone ( ) ) ;
516
523
match project:: poly_project_and_unify_type ( selcx, & project_obligation) {
524
+ Ok ( None ) => {
525
+ pending_obligation. stalled_on =
526
+ trait_ref_type_vars ( selcx, data. to_poly_trait_ref ( ) ) ;
527
+ Ok ( None )
528
+ }
517
529
Ok ( v) => Ok ( v) ,
518
530
Err ( e) => Err ( CodeProjectionError ( e) )
519
531
}
@@ -528,8 +540,14 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
528
540
}
529
541
530
542
ty:: Predicate :: WellFormed ( ty) => {
531
- Ok ( ty:: wf:: obligations ( selcx. infcx ( ) , obligation. cause . body_id ,
532
- ty, obligation. cause . span ) )
543
+ match ty:: wf:: obligations ( selcx. infcx ( ) , obligation. cause . body_id ,
544
+ ty, obligation. cause . span ) {
545
+ None => {
546
+ pending_obligation. stalled_on = vec ! [ ty] ;
547
+ Ok ( None )
548
+ }
549
+ s => Ok ( s)
550
+ }
533
551
}
534
552
}
535
553
}
0 commit comments