@@ -27,13 +27,13 @@ use middle::region::CodeExtent;
2727use ty:: subst;
2828use ty:: subst:: Substs ;
2929use ty:: subst:: Subst ;
30- use traits:: { self , ProjectionMode } ;
3130use ty:: adjustment;
3231use ty:: { TyVid , IntVid , FloatVid } ;
3332use ty:: { self , Ty , TyCtxt } ;
3433use ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
3534use ty:: fold:: { TypeFolder , TypeFoldable } ;
3635use ty:: relate:: { Relate , RelateResult , TypeRelation } ;
36+ use traits:: { self , PredicateObligations , ProjectionMode } ;
3737use rustc_data_structures:: unify:: { self , UnificationTable } ;
3838use std:: cell:: { RefCell , Ref } ;
3939use std:: fmt;
@@ -63,6 +63,12 @@ pub mod sub;
6363pub mod type_variable;
6464pub mod unify_key;
6565
66+ pub struct InferOk < ' tcx , T > {
67+ pub value : T ,
68+ pub obligations : PredicateObligations < ' tcx > ,
69+ }
70+ pub type InferResult < ' tcx , T > = Result < InferOk < ' tcx , T > , TypeError < ' tcx > > ;
71+
6672pub type Bound < T > = Option < T > ;
6773pub type UnitResult < ' tcx > = RelateResult < ' tcx , ( ) > ; // "unify result"
6874pub type FixupResult < T > = Result < T , FixupError > ; // "fixup result"
@@ -391,16 +397,15 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
391397 origin : TypeOrigin ,
392398 a : Ty < ' tcx > ,
393399 b : Ty < ' tcx > )
394- -> UnitResult < ' tcx >
400+ -> InferResult < ' tcx , ( ) >
395401{
396402 debug ! ( "mk_subty({:?} <: {:?})" , a, b) ;
397403 cx. sub_types ( a_is_expected, origin, a, b)
398404}
399405
400- pub fn can_mk_subty < ' a , ' tcx > ( cx : & InferCtxt < ' a , ' tcx > ,
401- a : Ty < ' tcx > ,
402- b : Ty < ' tcx > )
403- -> UnitResult < ' tcx > {
406+ pub fn can_mk_subty < ' a , ' tcx > ( cx : & InferCtxt < ' a , ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > )
407+ -> UnitResult < ' tcx >
408+ {
404409 debug ! ( "can_mk_subty({:?} <: {:?})" , a, b) ;
405410 cx. probe ( |_| {
406411 let trace = TypeTrace {
@@ -412,7 +417,7 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
412417}
413418
414419pub fn can_mk_eqty < ' a , ' tcx > ( cx : & InferCtxt < ' a , ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > )
415- -> UnitResult < ' tcx >
420+ -> UnitResult < ' tcx >
416421{
417422 cx. can_equate ( & a, & b)
418423}
@@ -432,7 +437,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
432437 origin : TypeOrigin ,
433438 a : Ty < ' tcx > ,
434439 b : Ty < ' tcx > )
435- -> UnitResult < ' tcx >
440+ -> InferResult < ' tcx , ( ) >
436441{
437442 debug ! ( "mk_eqty({:?} <: {:?})" , a, b) ;
438443 cx. eq_types ( a_is_expected, origin, a, b)
@@ -443,7 +448,7 @@ pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
443448 origin : TypeOrigin ,
444449 a : ty:: TraitRef < ' tcx > ,
445450 b : ty:: TraitRef < ' tcx > )
446- -> UnitResult < ' tcx >
451+ -> InferResult < ' tcx , ( ) >
447452{
448453 debug ! ( "mk_eq_trait_refs({:?} = {:?})" , a, b) ;
449454 cx. eq_trait_refs ( a_is_expected, origin, a, b)
@@ -454,7 +459,7 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
454459 origin : TypeOrigin ,
455460 a : ty:: PolyTraitRef < ' tcx > ,
456461 b : ty:: PolyTraitRef < ' tcx > )
457- -> UnitResult < ' tcx >
462+ -> InferResult < ' tcx , ( ) >
458463{
459464 debug ! ( "mk_sub_poly_trait_refs({:?} <: {:?})" , a, b) ;
460465 cx. sub_poly_trait_refs ( a_is_expected, origin, a, b)
@@ -465,7 +470,7 @@ pub fn mk_eq_impl_headers<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
465470 origin : TypeOrigin ,
466471 a : & ty:: ImplHeader < ' tcx > ,
467472 b : & ty:: ImplHeader < ' tcx > )
468- -> UnitResult < ' tcx >
473+ -> InferResult < ' tcx , ( ) >
469474{
470475 debug ! ( "mk_eq_impl_header({:?} = {:?})" , a, b) ;
471476 match ( a. trait_ref , b. trait_ref ) {
@@ -574,6 +579,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
574579 Ok ( infcx. tcx . erase_regions ( & result) )
575580}
576581
582+ impl < ' tcx , T > InferOk < ' tcx , T > {
583+ fn unit ( self ) -> InferOk < ' tcx , ( ) > {
584+ InferOk { value : ( ) , obligations : self . obligations }
585+ }
586+ }
587+
577588impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
578589 pub fn projection_mode ( & self ) -> ProjectionMode {
579590 self . projection_mode
@@ -661,39 +672,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
661672 }
662673
663674 fn combine_fields ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > )
664- -> CombineFields < ' a , ' tcx > {
665- CombineFields { infcx : self ,
666- a_is_expected : a_is_expected,
667- trace : trace,
668- cause : None }
675+ -> CombineFields < ' a , ' tcx >
676+ {
677+ CombineFields {
678+ infcx : self ,
679+ a_is_expected : a_is_expected,
680+ trace : trace,
681+ cause : None ,
682+ obligations : PredicateObligations :: new ( ) ,
683+ }
669684 }
670685
671686 pub fn equate < T > ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > , a : & T , b : & T )
672- -> RelateResult < ' tcx , T >
687+ -> InferResult < ' tcx , T >
673688 where T : Relate < ' a , ' tcx >
674689 {
675- self . combine_fields ( a_is_expected, trace) . equate ( ) . relate ( a, b)
690+ let mut equate = self . combine_fields ( a_is_expected, trace) . equate ( ) ;
691+ let result = equate. relate ( a, b) ;
692+ result. map ( |t| InferOk { value : t, obligations : equate. obligations ( ) } )
676693 }
677694
678695 pub fn sub < T > ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > , a : & T , b : & T )
679- -> RelateResult < ' tcx , T >
696+ -> InferResult < ' tcx , T >
680697 where T : Relate < ' a , ' tcx >
681698 {
682- self . combine_fields ( a_is_expected, trace) . sub ( ) . relate ( a, b)
699+ let mut sub = self . combine_fields ( a_is_expected, trace) . sub ( ) ;
700+ let result = sub. relate ( a, b) ;
701+ result. map ( |t| InferOk { value : t, obligations : sub. obligations ( ) } )
683702 }
684703
685704 pub fn lub < T > ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > , a : & T , b : & T )
686- -> RelateResult < ' tcx , T >
705+ -> InferResult < ' tcx , T >
687706 where T : Relate < ' a , ' tcx >
688707 {
689- self . combine_fields ( a_is_expected, trace) . lub ( ) . relate ( a, b)
708+ let mut lub = self . combine_fields ( a_is_expected, trace) . lub ( ) ;
709+ let result = lub. relate ( a, b) ;
710+ result. map ( |t| InferOk { value : t, obligations : lub. obligations ( ) } )
690711 }
691712
692713 pub fn glb < T > ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > , a : & T , b : & T )
693- -> RelateResult < ' tcx , T >
714+ -> InferResult < ' tcx , T >
694715 where T : Relate < ' a , ' tcx >
695716 {
696- self . combine_fields ( a_is_expected, trace) . glb ( ) . relate ( a, b)
717+ let mut glb = self . combine_fields ( a_is_expected, trace) . glb ( ) ;
718+ let result = glb. relate ( a, b) ;
719+ result. map ( |t| InferOk { value : t, obligations : glb. obligations ( ) } )
697720 }
698721
699722 fn start_snapshot ( & self ) -> CombinedSnapshot {
@@ -829,12 +852,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
829852 origin : TypeOrigin ,
830853 a : Ty < ' tcx > ,
831854 b : Ty < ' tcx > )
832- -> UnitResult < ' tcx >
855+ -> InferResult < ' tcx , ( ) >
833856 {
834857 debug ! ( "sub_types({:?} <: {:?})" , a, b) ;
835858 self . commit_if_ok ( |_| {
836859 let trace = TypeTrace :: types ( origin, a_is_expected, a, b) ;
837- self . sub ( a_is_expected, trace, & a, & b) . map ( |_| ( ) )
860+ self . sub ( a_is_expected, trace, & a, & b) . map ( |ok| ok . unit ( ) )
838861 } )
839862 }
840863
@@ -843,11 +866,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
843866 origin : TypeOrigin ,
844867 a : Ty < ' tcx > ,
845868 b : Ty < ' tcx > )
846- -> UnitResult < ' tcx >
869+ -> InferResult < ' tcx , ( ) >
847870 {
848871 self . commit_if_ok ( |_| {
849872 let trace = TypeTrace :: types ( origin, a_is_expected, a, b) ;
850- self . equate ( a_is_expected, trace, & a, & b) . map ( |_| ( ) )
873+ self . equate ( a_is_expected, trace, & a, & b) . map ( |ok| ok . unit ( ) )
851874 } )
852875 }
853876
@@ -856,7 +879,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
856879 origin : TypeOrigin ,
857880 a : ty:: TraitRef < ' tcx > ,
858881 b : ty:: TraitRef < ' tcx > )
859- -> UnitResult < ' tcx >
882+ -> InferResult < ' tcx , ( ) >
860883 {
861884 debug ! ( "eq_trait_refs({:?} <: {:?})" ,
862885 a,
@@ -866,7 +889,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
866889 origin : origin,
867890 values : TraitRefs ( expected_found ( a_is_expected, a. clone ( ) , b. clone ( ) ) )
868891 } ;
869- self . equate ( a_is_expected, trace, & a, & b) . map ( |_| ( ) )
892+ self . equate ( a_is_expected, trace, & a, & b) . map ( |ok| ok . unit ( ) )
870893 } )
871894 }
872895
@@ -875,7 +898,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
875898 origin : TypeOrigin ,
876899 a : ty:: PolyTraitRef < ' tcx > ,
877900 b : ty:: PolyTraitRef < ' tcx > )
878- -> UnitResult < ' tcx >
901+ -> InferResult < ' tcx , ( ) >
879902 {
880903 debug ! ( "sub_poly_trait_refs({:?} <: {:?})" ,
881904 a,
@@ -885,7 +908,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
885908 origin : origin,
886909 values : PolyTraitRefs ( expected_found ( a_is_expected, a. clone ( ) , b. clone ( ) ) )
887910 } ;
888- self . sub ( a_is_expected, trace, & a, & b) . map ( |_| ( ) )
911+ self . sub ( a_is_expected, trace, & a, & b) . map ( |ok| ok . unit ( ) )
889912 } )
890913 }
891914
@@ -928,20 +951,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
928951 pub fn equality_predicate ( & self ,
929952 span : Span ,
930953 predicate : & ty:: PolyEquatePredicate < ' tcx > )
931- -> UnitResult < ' tcx > {
954+ -> InferResult < ' tcx , ( ) >
955+ {
932956 self . commit_if_ok ( |snapshot| {
933957 let ( ty:: EquatePredicate ( a, b) , skol_map) =
934958 self . skolemize_late_bound_regions ( predicate, snapshot) ;
935959 let origin = TypeOrigin :: EquatePredicate ( span) ;
936- let ( ) = mk_eqty ( self , false , origin, a, b) ?;
937- self . leak_check ( & skol_map, snapshot)
960+ let eqty_ok = mk_eqty ( self , false , origin, a, b) ?;
961+ self . leak_check ( & skol_map, snapshot) . map ( |_| eqty_ok . unit ( ) )
938962 } )
939963 }
940964
941965 pub fn region_outlives_predicate ( & self ,
942966 span : Span ,
943967 predicate : & ty:: PolyRegionOutlivesPredicate )
944- -> UnitResult < ' tcx > {
968+ -> UnitResult < ' tcx >
969+ {
945970 self . commit_if_ok ( |snapshot| {
946971 let ( ty:: OutlivesPredicate ( r_a, r_b) , skol_map) =
947972 self . skolemize_late_bound_regions ( predicate, snapshot) ;
0 commit comments