@@ -31,7 +31,8 @@ use super::Selection;
31
31
use super :: SelectionResult ;
32
32
use super :: { VtableBuiltin , VtableImpl , VtableParam , VtableClosure ,
33
33
VtableFnPointer , VtableObject , VtableDefaultImpl } ;
34
- use super :: { VtableImplData , VtableObjectData , VtableBuiltinData , VtableDefaultImplData } ;
34
+ use super :: { VtableImplData , VtableObjectData , VtableBuiltinData ,
35
+ VtableClosureData , VtableDefaultImplData } ;
35
36
use super :: object_safety;
36
37
use super :: util;
37
38
@@ -355,7 +356,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
355
356
} ;
356
357
assert ! ( !substs. has_escaping_regions( ) ) ;
357
358
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
+
359
367
match self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
360
368
obligation. predicate . to_poly_trait_ref ( ) ,
361
369
closure_trait_ref) {
@@ -2001,8 +2009,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2001
2009
}
2002
2010
2003
2011
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) )
2006
2015
}
2007
2016
2008
2017
BuiltinObjectCandidate => {
@@ -2343,24 +2352,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2343
2352
obligation : & TraitObligation < ' tcx > ,
2344
2353
closure_def_id : ast:: DefId ,
2345
2354
substs : & Substs < ' tcx > )
2346
- -> Result < ( ) , SelectionError < ' tcx > >
2355
+ -> Result < VtableClosureData < ' tcx , PredicateObligation < ' tcx > > ,
2356
+ SelectionError < ' tcx > >
2347
2357
{
2348
2358
debug ! ( "confirm_closure_candidate({},{},{})" ,
2349
2359
obligation. repr( self . tcx( ) ) ,
2350
2360
closure_def_id. repr( self . tcx( ) ) ,
2351
2361
substs. repr( self . tcx( ) ) ) ;
2352
2362
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) ;
2356
2367
2357
- debug ! ( "confirm_closure_candidate(closure_def_id={}, trait_ref={})" ,
2368
+ debug ! ( "confirm_closure_candidate(closure_def_id={}, trait_ref={}, obligations={} )" ,
2358
2369
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) ) ;
2360
2376
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
+ } )
2364
2382
}
2365
2383
2366
2384
/// In the case of closure types and fn pointers,
@@ -2819,11 +2837,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2819
2837
}
2820
2838
}
2821
2839
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 >
2827
2845
{
2828
2846
let closure_type = self . closure_typer . closure_type ( closure_def_id, substs) ;
2829
2847
let ty:: Binder ( ( trait_ref, _) ) =
@@ -2832,7 +2850,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2832
2850
obligation. predicate . 0 . self_ty ( ) , // (1)
2833
2851
& closure_type. sig ,
2834
2852
util:: TupleArgumentsFlag :: No ) ;
2835
-
2836
2853
// (1) Feels icky to skip the binder here, but OTOH we know
2837
2854
// that the self-type is an unboxed closure type and hence is
2838
2855
// in fact unparameterized (or at least does not reference any
@@ -2842,6 +2859,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2842
2859
ty:: Binder ( trait_ref)
2843
2860
}
2844
2861
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
+
2845
2879
/// Returns the obligations that are implied by instantiating an
2846
2880
/// impl or trait. The obligations are substituted and fully
2847
2881
/// normalized. This is used when confirming an impl or default
0 commit comments