diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b6bb9d67a318..2abb53e55f64 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -73,33 +73,42 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // snippet }; - // Determine if the field can be used as a function in some way - let fn_once_trait_did = match cx.lang_items.require(FnOnceTraitLangItem) { - Ok(trait_did) => trait_did, - Err(err) => cx.sess.fatal(&err[..]) - }; + fn span_stored_function() { + cx.sess.span_note(span, &format!("use `({0}.{1})(...)` if you meant to call \ + the function stored in the `{1}` field", + expr_string, item_name)); + } - let field_ty = ty::lookup_field_type(cx, did, field.id, substs); - let field_ty_substs = Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()], - Vec::new(), - field_ty); - let trait_ref = ty::TraitRef::new(fn_once_trait_did, - cx.mk_substs(field_ty_substs)); - let poly_trait_ref = trait_ref.to_poly_trait_ref(); - let obligation = Obligation::misc(span, - fcx.body_id, - poly_trait_ref.as_predicate()); - let mut selcx = SelectionContext::new(fcx.infcx(), fcx); - - if selcx.evaluate_obligation(&obligation) { - cx.sess.span_note(span, - &format!("use `({0}.{1})(...)` if you meant to call the \ - function stored in the `{1}` field", - expr_string, item_name)); - } else { + fn span_did_you_mean() { cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?", expr_string, item_name)); } + + // Determine if the field can be used as a function in some way + let field_ty = ty::lookup_field_type(cx, did, field.id, substs); + if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) { + let fn_once_substs = Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()], + Vec::new(), + field_ty); + let trait_ref = ty::TraitRef::new(fn_once_trait_did, + cx.mk_substs(fn_once_substs)); + let poly_trait_ref = trait_ref.to_poly_trait_ref(); + let obligation = Obligation::misc(span, + fcx.body_id, + poly_trait_ref.as_predicate()); + let mut selcx = SelectionContext::new(fcx.infcx(), fcx); + + if selcx.evaluate_obligation(&obligation) { + span_stored_function(); + } else { + span_did_you_mean(); + } + } else { + match field_ty.sty { + ty::TyClosure(_,_) | ty::TyFnPtr(_,_) => span_stored_function(), + _ => span_did_you_mean(), + } + } } }