1010
1111use dep_graph:: DepGraph ;
1212use middle:: infer:: InferCtxt ;
13- use middle:: ty:: { self , Ty , TypeFoldable } ;
13+ use middle:: ty:: { self , Ty , TypeFoldable , ToPolyTraitRef } ;
1414use rustc_data_structures:: obligation_forest:: { Backtrace , ObligationForest , Error } ;
1515use std:: iter;
1616use syntax:: ast;
@@ -417,6 +417,21 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
417417 }
418418}
419419
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+
420435/// Processes a predicate obligation and returns either:
421436/// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true
422437/// - `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>,
433448 // doing more work yet
434449 if !pending_obligation. stalled_on . is_empty ( ) {
435450 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) ;
437452 resolved_ty == ty // nothing changed here
438453 } ) {
439454 debug ! ( "process_predicate: pending obligation {:?} still stalled on {:?}" ,
@@ -493,14 +508,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
493508 // of its type, and those types are resolved at
494509 // the same time.
495510 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 ( ) ) ;
504512
505513 debug ! ( "process_predicate: pending obligation {:?} now stalled on {:?}" ,
506514 selcx. infcx( ) . resolve_type_vars_if_possible( obligation) ,
@@ -568,6 +576,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
568576 ty:: Predicate :: Projection ( ref data) => {
569577 let project_obligation = obligation. with ( data. clone ( ) ) ;
570578 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+ }
571584 Ok ( v) => Ok ( v) ,
572585 Err ( e) => Err ( CodeProjectionError ( e) )
573586 }
@@ -582,8 +595,14 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
582595 }
583596
584597 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+ }
587606 }
588607 }
589608}
0 commit comments