From 3f8a70b613d9e41dc6db11f1d267025bb26bf73d Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Sun, 14 Jun 2015 02:49:00 -0400 Subject: [PATCH] Fixed note message to display expression in recommendations --- src/librustc_typeck/check/method/suggest.rs | 19 +++++++++++++--- src/test/compile-fail/issue-18343.rs | 24 +++++++++++++++------ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index be34c7057210..276794087176 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -59,22 +59,35 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, None); // If the item has the name of a field, give a help note - if let (&ty::TyStruct(did, substs), Some(_)) = (&rcvr_ty.sty, rcvr_expr) { + if let (&ty::TyStruct(did, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) { let fields = ty::lookup_struct_fields(cx, did); if let Some(field) = fields.iter().find(|f| f.name == item_name) { + let expr_string = match cx.sess.codemap().span_to_snippet(expr.span) { + Ok(expr_string) => expr_string, + _ => "s".into() // default to generic placeholder for expression + }; + // TODO Fix when closure note is displayed + // below commented code from eddyb on irc + // let substs = subst::Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()], Vec::new(), field_ty); + // let trait_ref = ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs)); + // let poly_trait_ref = trait_ref.to_poly_trait_ref(); + // let obligation = traits::Obligation::misc(span, fcx.body_id, poly_trait_ref.as_predicate()); + // let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx); + // if selcx.evaluate_obligation(&obligation) { /* suggest */ } + match ty::lookup_field_type(cx, did, field.id, substs).sty { ty::TyClosure(_, _) | ty::TyBareFn(_,_) => { cx.sess.span_note(span, &format!("use `({0}.{1})(...)` if you meant to call the \ function stored in the `{1}` field", - ty::item_path_str(cx, did), item_name)); + expr_string, item_name)); }, _ => { cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?", - ty::item_path_str(cx, did), item_name)); + expr_string, item_name)); }, }; } diff --git a/src/test/compile-fail/issue-18343.rs b/src/test/compile-fail/issue-18343.rs index 3572e5084c15..802b21d211cb 100644 --- a/src/test/compile-fail/issue-18343.rs +++ b/src/test/compile-fail/issue-18343.rs @@ -13,18 +13,30 @@ struct Obj where F: FnMut() -> u32 { nfn: usize, } +struct S where F: FnMut() -> u32 { + v: Obj, +} + fn func() -> u32 { 0 } fn main() { - let o = Obj { closure: || 42 }; + let o = Obj { closure: || 42, nfn: 42 }; o.closure(); //~ ERROR no method named `closure` found - //~^ NOTE use `(s.closure)(...)` if you meant to call the function stored in the `closure` field - let x = o.nfn(); //~ ERROR no method named `closure` found - //~^ NOTE did you mean `o.nfn`? + //~^ NOTE use `(o.closure)(...)` if you meant to call the function stored in the `closure` field - let b = Obj { closure: func }; + // TODO move these to a new test for #2392 + let x = o.nfn(); //~ ERROR no method named `nfn` found + //~^ NOTE did you mean to write `o.nfn`? + + let b = Obj { closure: func, nfn: 5 }; b.closure(); //~ ERROR no method named `closure` found - //~^ NOTE use `(s.closure)(...)` if you meant to call the function stored in the `closure` field + //~^ NOTE use `(b.closure)(...)` if you meant to call the function stored in the `closure` field + + let s = S { v: b }; + s.v.closure();//~ ERROR no method named `closure` found + //~^ NOTE use `(s.v.closure)(...)` if you meant to call the function stored in the `closure` field + s.v.nfn();//~ ERROR no method named `nfn` found + //~^ NOTE did you mean to write `s.v.nfn`? }