@@ -194,13 +194,12 @@ enum SelectionCandidate<'tcx> {
194
194
ProjectionCandidate,
195
195
196
196
/// Implementation of a `Fn`-family trait by one of the anonymous types
197
- /// generated for a `||` expression. The ty::ClosureKind informs the
198
- /// confirmation step what ClosureKind obligation to emit.
199
- ClosureCandidate(/* closure */ DefId, ty::ClosureSubsts<'tcx>, ty::ClosureKind),
197
+ /// generated for a `||` expression.
198
+ ClosureCandidate,
200
199
201
200
/// Implementation of a `Generator` trait by one of the anonymous types
202
201
/// generated for a generator.
203
- GeneratorCandidate(/* function / closure */ DefId, ty::ClosureSubsts<'tcx>) ,
202
+ GeneratorCandidate,
204
203
205
204
/// Implementation of a `Fn`-family trait by one of the anonymous
206
205
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -229,20 +228,12 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
229
228
ObjectCandidate => ObjectCandidate,
230
229
BuiltinObjectCandidate => BuiltinObjectCandidate,
231
230
BuiltinUnsizeCandidate => BuiltinUnsizeCandidate,
231
+ ClosureCandidate => ClosureCandidate,
232
+ GeneratorCandidate => GeneratorCandidate,
232
233
233
234
ParamCandidate(ref trait_ref) => {
234
235
return tcx.lift(trait_ref).map(ParamCandidate);
235
236
}
236
- GeneratorCandidate(def_id, ref substs) => {
237
- return tcx.lift(substs).map(|substs| {
238
- GeneratorCandidate(def_id, substs)
239
- });
240
- }
241
- ClosureCandidate(def_id, ref substs, kind) => {
242
- return tcx.lift(substs).map(|substs| {
243
- ClosureCandidate(def_id, substs, kind)
244
- });
245
- }
246
237
})
247
238
}
248
239
}
@@ -1518,23 +1509,22 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1518
1509
// touch bound regions, they just capture the in-scope
1519
1510
// type/region parameters
1520
1511
let self_ty = *obligation.self_ty().skip_binder();
1521
- let (closure_def_id, substs) = match self_ty.sty {
1522
- ty::TyGenerator(id, substs, _) => (id, substs),
1512
+ match self_ty.sty {
1513
+ ty::TyGenerator(..) => {
1514
+ debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
1515
+ self_ty,
1516
+ obligation);
1517
+
1518
+ candidates.vec.push(GeneratorCandidate);
1519
+ Ok(())
1520
+ }
1523
1521
ty::TyInfer(ty::TyVar(_)) => {
1524
1522
debug!("assemble_generator_candidates: ambiguous self-type");
1525
1523
candidates.ambiguous = true;
1526
1524
return Ok(());
1527
1525
}
1528
1526
_ => { return Ok(()); }
1529
- };
1530
-
1531
- debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
1532
- self_ty,
1533
- obligation);
1534
-
1535
- candidates.vec.push(GeneratorCandidate(closure_def_id, substs));
1536
-
1537
- Ok(())
1527
+ }
1538
1528
}
1539
1529
1540
1530
/// Check for the artificial impl that the compiler will create for an obligation like `X :
@@ -1556,36 +1546,31 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1556
1546
// ok to skip binder because the substs on closure types never
1557
1547
// touch bound regions, they just capture the in-scope
1558
1548
// type/region parameters
1559
- let self_ty = *obligation.self_ty().skip_binder();
1560
- let (closure_def_id, substs) = match self_ty.sty {
1561
- ty::TyClosure(id, substs) => (id, substs),
1549
+ match obligation.self_ty().skip_binder().sty {
1550
+ ty::TyClosure(closure_def_id, _) => {
1551
+ debug!("assemble_unboxed_candidates: kind={:?} obligation={:?}",
1552
+ kind, obligation);
1553
+ match self.infcx.closure_kind(closure_def_id) {
1554
+ Some(closure_kind) => {
1555
+ debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
1556
+ if closure_kind.extends(kind) {
1557
+ candidates.vec.push(ClosureCandidate);
1558
+ }
1559
+ }
1560
+ None => {
1561
+ debug!("assemble_unboxed_candidates: closure_kind not yet known");
1562
+ candidates.vec.push(ClosureCandidate);
1563
+ }
1564
+ };
1565
+ Ok(())
1566
+ }
1562
1567
ty::TyInfer(ty::TyVar(_)) => {
1563
1568
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
1564
1569
candidates.ambiguous = true;
1565
1570
return Ok(());
1566
1571
}
1567
1572
_ => { return Ok(()); }
1568
- };
1569
-
1570
- debug!("assemble_unboxed_candidates: self_ty={:?} kind={:?} obligation={:?}",
1571
- self_ty,
1572
- kind,
1573
- obligation);
1574
-
1575
- match self.infcx.closure_kind(closure_def_id) {
1576
- Some(closure_kind) => {
1577
- debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
1578
- if closure_kind.extends(kind) {
1579
- candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
1580
- }
1581
- }
1582
- None => {
1583
- debug!("assemble_unboxed_candidates: closure_kind not yet known");
1584
- candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
1585
- }
1586
1573
}
1587
-
1588
- Ok(())
1589
1574
}
1590
1575
1591
1576
/// Implement one of the `Fn()` family for a fn pointer.
@@ -1902,8 +1887,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1902
1887
when there are other valid candidates");
1903
1888
}
1904
1889
ImplCandidate(..) |
1905
- ClosureCandidate(..) |
1906
- GeneratorCandidate(..) |
1890
+ ClosureCandidate |
1891
+ GeneratorCandidate |
1907
1892
FnPointerCandidate |
1908
1893
BuiltinObjectCandidate |
1909
1894
BuiltinUnsizeCandidate |
@@ -2245,15 +2230,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2245
2230
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
2246
2231
}
2247
2232
2248
- ClosureCandidate(closure_def_id, substs, kind) => {
2249
- let vtable_closure =
2250
- self.confirm_closure_candidate(obligation, closure_def_id, substs, kind)?;
2233
+ ClosureCandidate => {
2234
+ let vtable_closure = self.confirm_closure_candidate(obligation)?;
2251
2235
Ok(VtableClosure(vtable_closure))
2252
2236
}
2253
2237
2254
- GeneratorCandidate(closure_def_id, substs) => {
2255
- let vtable_generator =
2256
- self.confirm_generator_candidate(obligation, closure_def_id, substs)?;
2238
+ GeneratorCandidate => {
2239
+ let vtable_generator = self.confirm_generator_candidate(obligation)?;
2257
2240
Ok(VtableGenerator(vtable_generator))
2258
2241
}
2259
2242
@@ -2590,21 +2573,34 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2590
2573
}
2591
2574
2592
2575
fn confirm_generator_candidate(&mut self,
2593
- obligation: &TraitObligation<'tcx>,
2594
- closure_def_id: DefId,
2595
- substs: ty::ClosureSubsts<'tcx>)
2596
- -> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
2576
+ obligation: &TraitObligation<'tcx>)
2577
+ -> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
2597
2578
SelectionError<'tcx>>
2598
2579
{
2580
+ // ok to skip binder because the substs on generator types never
2581
+ // touch bound regions, they just capture the in-scope
2582
+ // type/region parameters
2583
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
2584
+ let (closure_def_id, substs) = match self_ty.sty {
2585
+ ty::TyGenerator(id, substs, _) => (id, substs),
2586
+ _ => bug!("closure candidate for non-closure {:?}", obligation)
2587
+ };
2588
+
2599
2589
debug!("confirm_generator_candidate({:?},{:?},{:?})",
2600
2590
obligation,
2601
2591
closure_def_id,
2602
2592
substs);
2603
2593
2594
+ let trait_ref =
2595
+ self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
2604
2596
let Normalized {
2605
2597
value: trait_ref,
2606
2598
obligations
2607
- } = self.generator_trait_ref(obligation, closure_def_id, substs);
2599
+ } = normalize_with_depth(self,
2600
+ obligation.param_env,
2601
+ obligation.cause.clone(),
2602
+ obligation.recursion_depth+1,
2603
+ &trait_ref);
2608
2604
2609
2605
debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
2610
2606
closure_def_id,
@@ -2624,22 +2620,36 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2624
2620
}
2625
2621
2626
2622
fn confirm_closure_candidate(&mut self,
2627
- obligation: &TraitObligation<'tcx>,
2628
- closure_def_id: DefId,
2629
- substs: ty::ClosureSubsts<'tcx>,
2630
- kind: ty::ClosureKind)
2623
+ obligation: &TraitObligation<'tcx>)
2631
2624
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
2632
2625
SelectionError<'tcx>>
2633
2626
{
2634
- debug!("confirm_closure_candidate({:?},{:?},{:?})",
2635
- obligation,
2636
- closure_def_id,
2637
- substs);
2627
+ debug!("confirm_closure_candidate({:?})", obligation);
2628
+
2629
+ let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) {
2630
+ Some(k) => k,
2631
+ None => bug!("closure candidate for non-fn trait {:?}", obligation)
2632
+ };
2633
+
2634
+ // ok to skip binder because the substs on closure types never
2635
+ // touch bound regions, they just capture the in-scope
2636
+ // type/region parameters
2637
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
2638
+ let (closure_def_id, substs) = match self_ty.sty {
2639
+ ty::TyClosure(id, substs) => (id, substs),
2640
+ _ => bug!("closure candidate for non-closure {:?}", obligation)
2641
+ };
2638
2642
2643
+ let trait_ref =
2644
+ self.closure_trait_ref_unnormalized(obligation, closure_def_id, substs);
2639
2645
let Normalized {
2640
2646
value: trait_ref,
2641
2647
mut obligations
2642
- } = self.closure_trait_ref(obligation, closure_def_id, substs);
2648
+ } = normalize_with_depth(self,
2649
+ obligation.param_env,
2650
+ obligation.cause.clone(),
2651
+ obligation.recursion_depth+1,
2652
+ &trait_ref);
2643
2653
2644
2654
debug!("confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
2645
2655
closure_def_id,
@@ -3106,24 +3116,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3106
3116
ty::Binder(trait_ref)
3107
3117
}
3108
3118
3109
- fn closure_trait_ref(&mut self,
3110
- obligation: &TraitObligation<'tcx>,
3111
- closure_def_id: DefId,
3112
- substs: ty::ClosureSubsts<'tcx>)
3113
- -> Normalized<'tcx, ty::PolyTraitRef<'tcx>>
3114
- {
3115
- let trait_ref = self.closure_trait_ref_unnormalized(
3116
- obligation, closure_def_id, substs);
3117
-
3118
- // A closure signature can contain associated types which
3119
- // must be normalized.
3120
- normalize_with_depth(self,
3121
- obligation.param_env,
3122
- obligation.cause.clone(),
3123
- obligation.recursion_depth+1,
3124
- &trait_ref)
3125
- }
3126
-
3127
3119
fn generator_trait_ref_unnormalized(&mut self,
3128
3120
obligation: &TraitObligation<'tcx>,
3129
3121
closure_def_id: DefId,
@@ -3145,24 +3137,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3145
3137
ty::Binder(trait_ref)
3146
3138
}
3147
3139
3148
- fn generator_trait_ref(&mut self,
3149
- obligation: &TraitObligation<'tcx>,
3150
- closure_def_id: DefId,
3151
- substs: ty::ClosureSubsts<'tcx>)
3152
- -> Normalized<'tcx, ty::PolyTraitRef<'tcx>>
3153
- {
3154
- let trait_ref = self.generator_trait_ref_unnormalized(
3155
- obligation, closure_def_id, substs);
3156
-
3157
- // A generator signature can contain associated types which
3158
- // must be normalized.
3159
- normalize_with_depth(self,
3160
- obligation.param_env,
3161
- obligation.cause.clone(),
3162
- obligation.recursion_depth+1,
3163
- &trait_ref)
3164
- }
3165
-
3166
3140
/// Returns the obligations that are implied by instantiating an
3167
3141
/// impl or trait. The obligations are substituted and fully
3168
3142
/// normalized. This is used when confirming an impl or default
0 commit comments