@@ -31,7 +31,8 @@ use super::Selection;
3131use super :: SelectionResult ;
3232use super :: { VtableBuiltin , VtableImpl , VtableParam , VtableClosure ,
3333 VtableFnPointer , VtableObject , VtableDefaultImpl } ;
34- use super :: { VtableImplData , VtableObjectData , VtableBuiltinData , VtableDefaultImplData } ;
34+ use super :: { VtableImplData , VtableObjectData , VtableBuiltinData ,
35+ VtableClosureData , VtableDefaultImplData } ;
3536use super :: object_safety;
3637use super :: util;
3738
@@ -355,7 +356,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
355356 } ;
356357 assert ! ( !substs. has_escaping_regions( ) ) ;
357358
358- let closure_trait_ref = self . closure_trait_ref ( obligation, closure_def_id, substs) ;
359+ // It is OK to call the unnormalized variant here - this is only
360+ // reached for TyClosure: Fn inputs where the closure kind is
361+ // still unknown, which should only occur in typeck where the
362+ // closure type is already normalized.
363+ let closure_trait_ref = self . closure_trait_ref_unnormalized ( obligation,
364+ closure_def_id,
365+ substs) ;
366+
359367 match self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
360368 obligation. predicate . to_poly_trait_ref ( ) ,
361369 closure_trait_ref) {
@@ -2001,8 +2009,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20012009 }
20022010
20032011 ClosureCandidate ( closure_def_id, substs) => {
2004- try!( self . confirm_closure_candidate ( obligation, closure_def_id, & substs) ) ;
2005- Ok ( VtableClosure ( closure_def_id, substs) )
2012+ let vtable_closure =
2013+ try!( self . confirm_closure_candidate ( obligation, closure_def_id, & substs) ) ;
2014+ Ok ( VtableClosure ( vtable_closure) )
20062015 }
20072016
20082017 BuiltinObjectCandidate => {
@@ -2343,24 +2352,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23432352 obligation : & TraitObligation < ' tcx > ,
23442353 closure_def_id : ast:: DefId ,
23452354 substs : & Substs < ' tcx > )
2346- -> Result < ( ) , SelectionError < ' tcx > >
2355+ -> Result < VtableClosureData < ' tcx , PredicateObligation < ' tcx > > ,
2356+ SelectionError < ' tcx > >
23472357 {
23482358 debug ! ( "confirm_closure_candidate({},{},{})" ,
23492359 obligation. repr( self . tcx( ) ) ,
23502360 closure_def_id. repr( self . tcx( ) ) ,
23512361 substs. repr( self . tcx( ) ) ) ;
23522362
2353- let trait_ref = self . closure_trait_ref ( obligation,
2354- closure_def_id,
2355- substs) ;
2363+ let Normalized {
2364+ value : trait_ref,
2365+ obligations
2366+ } = self . closure_trait_ref ( obligation, closure_def_id, substs) ;
23562367
2357- debug ! ( "confirm_closure_candidate(closure_def_id={}, trait_ref={})" ,
2368+ debug ! ( "confirm_closure_candidate(closure_def_id={}, trait_ref={}, obligations={} )" ,
23582369 closure_def_id. repr( self . tcx( ) ) ,
2359- trait_ref. repr( self . tcx( ) ) ) ;
2370+ trait_ref. repr( self . tcx( ) ) ,
2371+ obligations. repr( self . tcx( ) ) ) ;
2372+
2373+ try!( self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2374+ obligation. predicate . to_poly_trait_ref ( ) ,
2375+ trait_ref) ) ;
23602376
2361- self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2362- obligation. predicate . to_poly_trait_ref ( ) ,
2363- trait_ref)
2377+ Ok ( VtableClosureData {
2378+ closure_def_id : closure_def_id,
2379+ substs : substs. clone ( ) ,
2380+ nested : obligations
2381+ } )
23642382 }
23652383
23662384 /// In the case of closure types and fn pointers,
@@ -2819,11 +2837,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28192837 }
28202838 }
28212839
2822- fn closure_trait_ref ( & self ,
2823- obligation : & TraitObligation < ' tcx > ,
2824- closure_def_id : ast:: DefId ,
2825- substs : & Substs < ' tcx > )
2826- -> ty:: PolyTraitRef < ' tcx >
2840+ fn closure_trait_ref_unnormalized ( & mut self ,
2841+ obligation : & TraitObligation < ' tcx > ,
2842+ closure_def_id : ast:: DefId ,
2843+ substs : & Substs < ' tcx > )
2844+ -> ty:: PolyTraitRef < ' tcx >
28272845 {
28282846 let closure_type = self . closure_typer . closure_type ( closure_def_id, substs) ;
28292847 let ty:: Binder ( ( trait_ref, _) ) =
@@ -2832,7 +2850,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28322850 obligation. predicate . 0 . self_ty ( ) , // (1)
28332851 & closure_type. sig ,
28342852 util:: TupleArgumentsFlag :: No ) ;
2835-
28362853 // (1) Feels icky to skip the binder here, but OTOH we know
28372854 // that the self-type is an unboxed closure type and hence is
28382855 // in fact unparameterized (or at least does not reference any
@@ -2842,6 +2859,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28422859 ty:: Binder ( trait_ref)
28432860 }
28442861
2862+ fn closure_trait_ref ( & mut self ,
2863+ obligation : & TraitObligation < ' tcx > ,
2864+ closure_def_id : ast:: DefId ,
2865+ substs : & Substs < ' tcx > )
2866+ -> Normalized < ' tcx , ty:: PolyTraitRef < ' tcx > >
2867+ {
2868+ let trait_ref = self . closure_trait_ref_unnormalized (
2869+ obligation, closure_def_id, substs) ;
2870+
2871+ // A closure signature can contain associated types which
2872+ // must be normalized.
2873+ normalize_with_depth ( self ,
2874+ obligation. cause . clone ( ) ,
2875+ obligation. recursion_depth +1 ,
2876+ & trait_ref)
2877+ }
2878+
28452879 /// Returns the obligations that are implied by instantiating an
28462880 /// impl or trait. The obligations are substituted and fully
28472881 /// normalized. This is used when confirming an impl or default
0 commit comments