|
14 | 14 | use CrateCtxt;
|
15 | 15 |
|
16 | 16 | use astconv::AstConv;
|
17 |
| -use check::{self, FnCtxt}; |
| 17 | +use check::{self, FnCtxt, UnresolvedTypeAction, autoderef}; |
18 | 18 | use front::map as hir_map;
|
19 | 19 | use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
|
20 | 20 | use middle::cstore::{self, CrateStore};
|
21 | 21 | use middle::def::Def;
|
22 | 22 | use middle::def_id::DefId;
|
23 | 23 | use middle::lang_items::FnOnceTraitLangItem;
|
24 | 24 | use rustc::ty::subst::Substs;
|
| 25 | +use rustc::ty::LvaluePreference; |
25 | 26 | use rustc::traits::{Obligation, SelectionContext};
|
26 | 27 | use util::nodemap::{FnvHashSet};
|
27 | 28 |
|
@@ -50,23 +51,37 @@ fn is_fn_ty<'a, 'tcx>(ty: &Ty<'tcx>, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> bool
|
50 | 51 | if let Ok(fn_once_trait_did) =
|
51 | 52 | cx.lang_items.require(FnOnceTraitLangItem) {
|
52 | 53 | let infcx = fcx.infcx();
|
53 |
| - infcx.probe(|_| { |
54 |
| - let fn_once_substs = |
55 |
| - Substs::new_trait(vec![infcx.next_ty_var()], |
56 |
| - Vec::new(), |
57 |
| - ty); |
58 |
| - let trait_ref = |
59 |
| - ty::TraitRef::new(fn_once_trait_did, |
60 |
| - cx.mk_substs(fn_once_substs)); |
61 |
| - let poly_trait_ref = trait_ref.to_poly_trait_ref(); |
62 |
| - let obligation = Obligation::misc(span, |
63 |
| - fcx.body_id, |
64 |
| - poly_trait_ref |
65 |
| - .to_predicate()); |
66 |
| - let mut selcx = SelectionContext::new(infcx); |
67 |
| - |
68 |
| - return selcx.evaluate_obligation(&obligation) |
69 |
| - }) |
| 54 | + let (_, _, opt_is_fn) = autoderef(fcx, |
| 55 | + span, |
| 56 | + ty, |
| 57 | + || None, |
| 58 | + UnresolvedTypeAction::Ignore, |
| 59 | + LvaluePreference::NoPreference, |
| 60 | + |ty, _| { |
| 61 | + infcx.probe(|_| { |
| 62 | + let fn_once_substs = |
| 63 | + Substs::new_trait(vec![infcx.next_ty_var()], |
| 64 | + Vec::new(), |
| 65 | + ty); |
| 66 | + let trait_ref = |
| 67 | + ty::TraitRef::new(fn_once_trait_did, |
| 68 | + cx.mk_substs(fn_once_substs)); |
| 69 | + let poly_trait_ref = trait_ref.to_poly_trait_ref(); |
| 70 | + let obligation = Obligation::misc(span, |
| 71 | + fcx.body_id, |
| 72 | + poly_trait_ref |
| 73 | + .to_predicate()); |
| 74 | + let mut selcx = SelectionContext::new(infcx); |
| 75 | + |
| 76 | + if selcx.evaluate_obligation(&obligation) { |
| 77 | + Some(()) |
| 78 | + } else { |
| 79 | + None |
| 80 | + } |
| 81 | + }) |
| 82 | + }); |
| 83 | + |
| 84 | + opt_is_fn.is_some() |
70 | 85 | } else {
|
71 | 86 | false
|
72 | 87 | }
|
|
0 commit comments