@@ -15,9 +15,9 @@ pub use self::FulfillmentErrorCode::*;
1515pub use self :: Vtable :: * ;
1616pub use self :: ObligationCauseCode :: * ;
1717
18- use middle:: mem_categorization:: Typer ;
1918use middle:: subst;
20- use middle:: ty:: { self , Ty } ;
19+ use middle:: ty:: { self , HasProjectionTypes , Ty } ;
20+ use middle:: ty_fold:: TypeFoldable ;
2121use middle:: infer:: { self , InferCtxt } ;
2222use std:: slice:: Iter ;
2323use std:: rc:: Rc ;
@@ -432,25 +432,44 @@ pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx
432432 debug ! ( "normalize_param_env(param_env={})" ,
433433 param_env. repr( tcx) ) ;
434434
435- let predicates: Vec < ty:: Predicate < ' tcx > > = {
436- let infcx = infer:: new_infer_ctxt ( tcx) ;
437- let mut selcx = & mut SelectionContext :: new ( & infcx, param_env) ;
438- let mut fulfill_cx = FulfillmentContext :: new ( ) ;
439- let Normalized { value : predicates, obligations } =
440- project:: normalize ( selcx, cause, & param_env. caller_bounds ) ;
441- for obligation in obligations {
442- fulfill_cx. register_predicate_obligation ( selcx. infcx ( ) , obligation) ;
443- }
444- try!( fulfill_cx. select_all_or_error ( selcx. infcx ( ) , param_env) ) ;
445- predicates. iter ( ) . map ( |p| infcx. resolve_type_vars_if_possible ( p) ) . collect ( )
446- } ;
435+ let infcx = infer:: new_infer_ctxt ( tcx) ;
436+ let predicates = try!( fully_normalize ( & infcx, param_env, cause, & param_env. caller_bounds ) ) ;
447437
448438 debug ! ( "normalize_param_env: predicates={}" ,
449439 predicates. repr( tcx) ) ;
450440
451441 Ok ( param_env. with_caller_bounds ( predicates) )
452442}
453443
444+ pub fn fully_normalize < ' a , ' tcx , T > ( infcx : & InferCtxt < ' a , ' tcx > ,
445+ closure_typer : & ty:: ClosureTyper < ' tcx > ,
446+ cause : ObligationCause < ' tcx > ,
447+ value : & T )
448+ -> Result < T , Vec < FulfillmentError < ' tcx > > >
449+ where T : TypeFoldable < ' tcx > + HasProjectionTypes + Clone + Repr < ' tcx >
450+ {
451+ let tcx = closure_typer. tcx ( ) ;
452+
453+ debug ! ( "normalize_param_env(value={})" ,
454+ value. repr( tcx) ) ;
455+
456+ let mut selcx = & mut SelectionContext :: new ( infcx, closure_typer) ;
457+ let mut fulfill_cx = FulfillmentContext :: new ( ) ;
458+ let Normalized { value : normalized_value, obligations } =
459+ project:: normalize ( selcx, cause, value) ;
460+ debug ! ( "normalize_param_env: normalized_value={} obligations={}" ,
461+ normalized_value. repr( tcx) ,
462+ obligations. repr( tcx) ) ;
463+ for obligation in obligations {
464+ fulfill_cx. register_predicate_obligation ( selcx. infcx ( ) , obligation) ;
465+ }
466+ try!( fulfill_cx. select_all_or_error ( infcx, closure_typer) ) ;
467+ let resolved_value = infcx. resolve_type_vars_if_possible ( & normalized_value) ;
468+ debug ! ( "normalize_param_env: resolved_value={}" ,
469+ resolved_value. repr( tcx) ) ;
470+ Ok ( resolved_value)
471+ }
472+
454473impl < ' tcx , O > Obligation < ' tcx , O > {
455474 pub fn new ( cause : ObligationCause < ' tcx > ,
456475 trait_ref : O )
0 commit comments