@@ -198,9 +198,10 @@ enum SelectionCandidate<'tcx> {
198
198
/// we found an applicable bound in the trait definition.
199
199
ProjectionCandidate ,
200
200
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 ) ,
204
205
205
206
/// Implementation of a `Fn`-family trait by one of the anonymous
206
207
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -321,75 +322,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
321
322
322
323
let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
323
324
match self . candidate_from_obligation ( & stack) ? {
324
- None => {
325
- self . consider_unification_despite_ambiguity ( obligation) ;
326
- Ok ( None )
327
- }
325
+ None => Ok ( None ) ,
328
326
Some ( candidate) => Ok ( Some ( self . confirm_candidate ( obligation, candidate) ?) ) ,
329
327
}
330
328
}
331
329
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
-
393
330
///////////////////////////////////////////////////////////////////////////
394
331
// EVALUATION
395
332
//
@@ -532,6 +469,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
532
469
}
533
470
}
534
471
}
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
+ }
535
487
}
536
488
}
537
489
@@ -1282,12 +1234,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1282
1234
Some ( closure_kind) => {
1283
1235
debug ! ( "assemble_unboxed_candidates: closure_kind = {:?}" , closure_kind) ;
1284
1236
if closure_kind. extends ( kind) {
1285
- candidates. vec . push ( ClosureCandidate ( closure_def_id, substs) ) ;
1237
+ candidates. vec . push ( ClosureCandidate ( closure_def_id, substs, kind ) ) ;
1286
1238
}
1287
1239
}
1288
1240
None => {
1289
1241
debug ! ( "assemble_unboxed_candidates: closure_kind not yet known" ) ;
1290
- candidates. ambiguous = true ;
1242
+ candidates. vec . push ( ClosureCandidate ( closure_def_id , substs , kind ) ) ;
1291
1243
}
1292
1244
}
1293
1245
@@ -2071,9 +2023,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2071
2023
Ok ( VtableImpl ( vtable_impl) )
2072
2024
}
2073
2025
2074
- ClosureCandidate ( closure_def_id, substs) => {
2026
+ ClosureCandidate ( closure_def_id, substs, kind ) => {
2075
2027
let vtable_closure =
2076
- self . confirm_closure_candidate ( obligation, closure_def_id, substs) ?;
2028
+ self . confirm_closure_candidate ( obligation, closure_def_id, substs, kind ) ?;
2077
2029
Ok ( VtableClosure ( vtable_closure) )
2078
2030
}
2079
2031
@@ -2430,7 +2382,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2430
2382
fn confirm_closure_candidate ( & mut self ,
2431
2383
obligation : & TraitObligation < ' tcx > ,
2432
2384
closure_def_id : DefId ,
2433
- substs : & ty:: ClosureSubsts < ' tcx > )
2385
+ substs : & ty:: ClosureSubsts < ' tcx > ,
2386
+ kind : ty:: ClosureKind )
2434
2387
-> Result < VtableClosureData < ' tcx , PredicateObligation < ' tcx > > ,
2435
2388
SelectionError < ' tcx > >
2436
2389
{
@@ -2441,7 +2394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2441
2394
2442
2395
let Normalized {
2443
2396
value : trait_ref,
2444
- obligations
2397
+ mut obligations
2445
2398
} = self . closure_trait_ref ( obligation, closure_def_id, substs) ;
2446
2399
2447
2400
debug ! ( "confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})" ,
@@ -2453,6 +2406,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2453
2406
obligation. predicate . to_poly_trait_ref ( ) ,
2454
2407
trait_ref) ?;
2455
2408
2409
+ obligations. push ( Obligation :: new (
2410
+ obligation. cause . clone ( ) ,
2411
+ ty:: Predicate :: ClosureKind ( closure_def_id, kind) ) ) ;
2412
+
2456
2413
Ok ( VtableClosureData {
2457
2414
closure_def_id : closure_def_id,
2458
2415
substs : substs. clone ( ) ,
0 commit comments