|
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,40 @@ 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(true) |
| 78 | + } else { |
| 79 | + None |
| 80 | + } |
| 81 | + }) |
| 82 | + }); |
| 83 | + |
| 84 | + match opt_is_fn { |
| 85 | + Some(result) => result, |
| 86 | + None => false, |
| 87 | + } |
70 | 88 | } else { |
71 | 89 | false |
72 | 90 | } |
|
0 commit comments