Skip to content

Commit 4185581

Browse files
committed
---
yaml --- r: 177023 b: refs/heads/master c: 47c2d31 h: refs/heads/master i: 177021: e067690 177019: 818eb41 177015: 335faee 177007: 56831d5 176991: 8098776 176959: 4cde66d 176895: 07e07c0 v: v3
1 parent 6490801 commit 4185581

File tree

2 files changed

+50
-40
lines changed

2 files changed

+50
-40
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 25a27977fa1cbaddd4c2275881bee358eeaeb8a1
2+
refs/heads/master: 47c2d3103874b2f07d91179fc13609904cd9639b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a45e117733b866302fa99390553d1c548508dcca
55
refs/heads/try: fde4472848b662a4d1236388c4cf15e2450237e6

trunk/src/librustc_typeck/check/closure.rs

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3434
expected.repr(fcx.tcx()));
3535

3636
let expected_sig_and_kind = expected.to_option(fcx).and_then(|ty| {
37-
deduce_closure_expectations_from_expected_type(fcx, ty)
37+
deduce_expectations_from_expected_type(fcx, ty)
3838
});
3939

4040
match opt_kind {
@@ -137,36 +137,73 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
137137
fcx.inh.closures.borrow_mut().insert(expr_def_id, closure);
138138
}
139139

140-
fn deduce_closure_expectations_from_expected_type<'a,'tcx>(
140+
fn deduce_expectations_from_expected_type<'a,'tcx>(
141141
fcx: &FnCtxt<'a,'tcx>,
142142
expected_ty: Ty<'tcx>)
143143
-> Option<(ty::FnSig<'tcx>,ty::ClosureKind)>
144144
{
145145
match expected_ty.sty {
146146
ty::ty_trait(ref object_type) => {
147-
let trait_ref =
148-
object_type.principal_trait_ref_with_self_ty(fcx.tcx(),
149-
fcx.tcx().types.err);
150-
deduce_closure_expectations_from_trait_ref(fcx, &trait_ref)
147+
let proj_bounds = object_type.projection_bounds_with_self_ty(fcx.tcx(),
148+
fcx.tcx().types.err);
149+
proj_bounds.iter()
150+
.filter_map(|pb| deduce_expectations_from_projection(fcx, pb))
151+
.next()
151152
}
152153
ty::ty_infer(ty::TyVar(vid)) => {
153-
deduce_closure_expectations_from_obligations(fcx, vid)
154+
deduce_expectations_from_obligations(fcx, vid)
154155
}
155156
_ => {
156157
None
157158
}
158159
}
159160
}
160161

161-
fn deduce_closure_expectations_from_trait_ref<'a,'tcx>(
162+
fn deduce_expectations_from_obligations<'a,'tcx>(
162163
fcx: &FnCtxt<'a,'tcx>,
163-
trait_ref: &ty::PolyTraitRef<'tcx>)
164+
expected_vid: ty::TyVid)
165+
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
166+
{
167+
let fulfillment_cx = fcx.inh.fulfillment_cx.borrow();
168+
// Here `expected_ty` is known to be a type inference variable.
169+
170+
fulfillment_cx.pending_obligations()
171+
.iter()
172+
.filter_map(|obligation| {
173+
match obligation.predicate {
174+
ty::Predicate::Projection(ref proj_predicate) => {
175+
let trait_ref = proj_predicate.to_poly_trait_ref();
176+
let self_ty = fcx.infcx().shallow_resolve(trait_ref.self_ty());
177+
match self_ty.sty {
178+
ty::ty_infer(ty::TyVar(v)) if expected_vid == v => {
179+
deduce_expectations_from_projection(fcx, proj_predicate)
180+
}
181+
_ => {
182+
None
183+
}
184+
}
185+
}
186+
_ => {
187+
None
188+
}
189+
}
190+
})
191+
.next()
192+
}
193+
194+
/// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
195+
/// everything we need to know about a closure.
196+
fn deduce_expectations_from_projection<'a,'tcx>(
197+
fcx: &FnCtxt<'a,'tcx>,
198+
projection: &ty::PolyProjectionPredicate<'tcx>)
164199
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
165200
{
166201
let tcx = fcx.tcx();
167202

168-
debug!("deduce_closure_expectations_from_object_type({})",
169-
trait_ref.repr(tcx));
203+
debug!("deduce_expectations_from_projection({})",
204+
projection.repr(tcx));
205+
206+
let trait_ref = projection.to_poly_trait_ref();
170207

171208
let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id()) {
172209
Some(k) => k,
@@ -185,7 +222,7 @@ fn deduce_closure_expectations_from_trait_ref<'a,'tcx>(
185222
};
186223
debug!("input_tys {}", input_tys.repr(tcx));
187224

188-
let ret_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 1);
225+
let ret_param_ty = projection.0.ty;
189226
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(&ret_param_ty);
190227
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
191228

@@ -199,30 +236,3 @@ fn deduce_closure_expectations_from_trait_ref<'a,'tcx>(
199236
return Some((fn_sig, kind));
200237
}
201238

202-
fn deduce_closure_expectations_from_obligations<'a,'tcx>(
203-
fcx: &FnCtxt<'a,'tcx>,
204-
expected_vid: ty::TyVid)
205-
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
206-
{
207-
// Here `expected_ty` is known to be a type inference variable.
208-
for obligation in fcx.inh.fulfillment_cx.borrow().pending_obligations().iter() {
209-
match obligation.predicate {
210-
ty::Predicate::Trait(ref trait_predicate) => {
211-
let trait_ref = trait_predicate.to_poly_trait_ref();
212-
let self_ty = fcx.infcx().shallow_resolve(trait_ref.self_ty());
213-
match self_ty.sty {
214-
ty::ty_infer(ty::TyVar(v)) if expected_vid == v => { }
215-
_ => { continue; }
216-
}
217-
218-
match deduce_closure_expectations_from_trait_ref(fcx, &trait_ref) {
219-
Some(e) => { return Some(e); }
220-
None => { }
221-
}
222-
}
223-
_ => { }
224-
}
225-
}
226-
227-
None
228-
}

0 commit comments

Comments
 (0)