@@ -198,9 +198,10 @@ enum SelectionCandidate<'tcx> {
198198 /// we found an applicable bound in the trait definition.
199199 ProjectionCandidate ,
200200
201- /// Implementation of a `Fn`-family trait by one of the
202- /// anonymous types generated for a `||` expression.
203- ClosureCandidate ( /* closure */ DefId , & ' tcx ty:: ClosureSubsts < ' tcx > ) ,
201+ /// Implementation of a `Fn`-family trait by one of the anonymous types
202+ /// generated for a `||` expression. The ty::ClosureKind informs the
203+ /// confirmation step what ClosureKind obligation to emit.
204+ ClosureCandidate ( /* closure */ DefId , & ' tcx ty:: ClosureSubsts < ' tcx > , ty:: ClosureKind ) ,
204205
205206 /// Implementation of a `Fn`-family trait by one of the anonymous
206207 /// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -321,75 +322,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
321322
322323 let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
323324 match self . candidate_from_obligation ( & stack) ? {
324- None => {
325- self . consider_unification_despite_ambiguity ( obligation) ;
326- Ok ( None )
327- }
325+ None => Ok ( None ) ,
328326 Some ( candidate) => Ok ( Some ( self . confirm_candidate ( obligation, candidate) ?) ) ,
329327 }
330328 }
331329
332- /// In the particular case of unboxed closure obligations, we can
333- /// sometimes do some amount of unification for the
334- /// argument/return types even though we can't yet fully match obligation.
335- /// The particular case we are interesting in is an obligation of the form:
336- ///
337- /// C : FnFoo<A>
338- ///
339- /// where `C` is an unboxed closure type and `FnFoo` is one of the
340- /// `Fn` traits. Because we know that users cannot write impls for closure types
341- /// themselves, the only way that `C : FnFoo` can fail to match is under two
342- /// conditions:
343- ///
344- /// 1. The closure kind for `C` is not yet known, because inference isn't complete.
345- /// 2. The closure kind for `C` *is* known, but doesn't match what is needed.
346- /// For example, `C` may be a `FnOnce` closure, but a `Fn` closure is needed.
347- ///
348- /// In either case, we always know what argument types are
349- /// expected by `C`, no matter what kind of `Fn` trait it
350- /// eventually matches. So we can go ahead and unify the argument
351- /// types, even though the end result is ambiguous.
352- ///
353- /// Note that this is safe *even if* the trait would never be
354- /// matched (case 2 above). After all, in that case, an error will
355- /// result, so it kind of doesn't matter what we do --- unifying
356- /// the argument types can only be helpful to the user, because
357- /// once they patch up the kind of closure that is expected, the
358- /// argment types won't really change.
359- fn consider_unification_despite_ambiguity ( & mut self , obligation : & TraitObligation < ' tcx > ) {
360- // Is this a `C : FnFoo(...)` trait reference for some trait binding `FnFoo`?
361- match self . tcx ( ) . lang_items . fn_trait_kind ( obligation. predicate . 0 . def_id ( ) ) {
362- Some ( _) => { }
363- None => { return ; }
364- }
365-
366- // Is the self-type a closure type? We ignore bindings here
367- // because if it is a closure type, it must be a closure type from
368- // within this current fn, and hence none of the higher-ranked
369- // lifetimes can appear inside the self-type.
370- let self_ty = self . infcx . shallow_resolve ( * obligation. self_ty ( ) . skip_binder ( ) ) ;
371- let ( closure_def_id, substs) = match self_ty. sty {
372- ty:: TyClosure ( id, ref substs) => ( id, substs) ,
373- _ => { return ; }
374- } ;
375- assert ! ( !substs. has_escaping_regions( ) ) ;
376-
377- // It is OK to call the unnormalized variant here - this is only
378- // reached for TyClosure: Fn inputs where the closure kind is
379- // still unknown, which should only occur in typeck where the
380- // closure type is already normalized.
381- let closure_trait_ref = self . closure_trait_ref_unnormalized ( obligation,
382- closure_def_id,
383- substs) ;
384-
385- match self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
386- obligation. predicate . to_poly_trait_ref ( ) ,
387- closure_trait_ref) {
388- Ok ( ( ) ) => { }
389- Err ( _) => { /* Silently ignore errors. */ }
390- }
391- }
392-
393330 ///////////////////////////////////////////////////////////////////////////
394331 // EVALUATION
395332 //
@@ -532,6 +469,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
532469 }
533470 }
534471 }
472+
473+ ty:: Predicate :: ClosureKind ( closure_def_id, kind) => {
474+ match self . infcx . closure_kind ( closure_def_id) {
475+ Some ( closure_kind) => {
476+ if closure_kind. extends ( kind) {
477+ EvaluatedToOk
478+ } else {
479+ EvaluatedToErr
480+ }
481+ }
482+ None => {
483+ EvaluatedToAmbig
484+ }
485+ }
486+ }
535487 }
536488 }
537489
@@ -1282,12 +1234,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12821234 Some ( closure_kind) => {
12831235 debug ! ( "assemble_unboxed_candidates: closure_kind = {:?}" , closure_kind) ;
12841236 if closure_kind. extends ( kind) {
1285- candidates. vec . push ( ClosureCandidate ( closure_def_id, substs) ) ;
1237+ candidates. vec . push ( ClosureCandidate ( closure_def_id, substs, kind ) ) ;
12861238 }
12871239 }
12881240 None => {
12891241 debug ! ( "assemble_unboxed_candidates: closure_kind not yet known" ) ;
1290- candidates. ambiguous = true ;
1242+ candidates. vec . push ( ClosureCandidate ( closure_def_id , substs , kind ) ) ;
12911243 }
12921244 }
12931245
@@ -2071,9 +2023,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20712023 Ok ( VtableImpl ( vtable_impl) )
20722024 }
20732025
2074- ClosureCandidate ( closure_def_id, substs) => {
2026+ ClosureCandidate ( closure_def_id, substs, kind ) => {
20752027 let vtable_closure =
2076- self . confirm_closure_candidate ( obligation, closure_def_id, substs) ?;
2028+ self . confirm_closure_candidate ( obligation, closure_def_id, substs, kind ) ?;
20772029 Ok ( VtableClosure ( vtable_closure) )
20782030 }
20792031
@@ -2430,7 +2382,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24302382 fn confirm_closure_candidate ( & mut self ,
24312383 obligation : & TraitObligation < ' tcx > ,
24322384 closure_def_id : DefId ,
2433- substs : & ty:: ClosureSubsts < ' tcx > )
2385+ substs : & ty:: ClosureSubsts < ' tcx > ,
2386+ kind : ty:: ClosureKind )
24342387 -> Result < VtableClosureData < ' tcx , PredicateObligation < ' tcx > > ,
24352388 SelectionError < ' tcx > >
24362389 {
@@ -2441,7 +2394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24412394
24422395 let Normalized {
24432396 value : trait_ref,
2444- obligations
2397+ mut obligations
24452398 } = self . closure_trait_ref ( obligation, closure_def_id, substs) ;
24462399
24472400 debug ! ( "confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})" ,
@@ -2453,6 +2406,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24532406 obligation. predicate . to_poly_trait_ref ( ) ,
24542407 trait_ref) ?;
24552408
2409+ obligations. push ( Obligation :: new (
2410+ obligation. cause . clone ( ) ,
2411+ ty:: Predicate :: ClosureKind ( closure_def_id, kind) ) ) ;
2412+
24562413 Ok ( VtableClosureData {
24572414 closure_def_id : closure_def_id,
24582415 substs : substs. clone ( ) ,
0 commit comments