From 687cee62dba6099c4d9443906b4c9ac73b705184 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Fri, 13 Jun 2014 22:56:42 +0100 Subject: [PATCH] rustc: Improve span for error about using a method as a field. libsyntax: ExprField now contains a SpannedIdent rather than Ident. [breaking-change] --- src/librustc/back/svh.rs | 2 +- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/privacy.rs | 2 +- src/librustc/middle/resolve.rs | 2 +- src/librustc/middle/save/mod.rs | 2 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 16 ++++++++-------- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/build.rs | 12 ++++++++++-- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/parser.rs | 5 +++-- src/libsyntax/print/pprust.rs | 2 +- src/test/compile-fail/method-missing-call.rs | 13 +++++++++++-- 15 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/librustc/back/svh.rs b/src/librustc/back/svh.rs index 1fce6eaf8e1b0..24111d1c7a16b 100644 --- a/src/librustc/back/svh.rs +++ b/src/librustc/back/svh.rs @@ -270,7 +270,7 @@ mod svh_visitor { ExprBlock(..) => SawExprBlock, ExprAssign(..) => SawExprAssign, ExprAssignOp(op, _, _) => SawExprAssignOp(op), - ExprField(_, id, _) => SawExprField(content(id)), + ExprField(_, id, _) => SawExprField(content(id.node)), ExprIndex(..) => SawExprIndex, ExprPath(..) => SawExprPath, ExprAddrOf(m, _) => SawExprAddrOf(m), diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index aa74614b78cd8..1535239141862 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -235,7 +235,7 @@ impl<'a> Visitor for MarkSymbolVisitor<'a> { self.lookup_and_handle_method(expr.id, expr.span); } ast::ExprField(ref lhs, ref ident, _) => { - self.handle_field_access(&**lhs, ident); + self.handle_field_access(&**lhs, &ident.node); } _ => () } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 57c10e19e661a..5357054c6f5b9 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -447,7 +447,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> { ast::ExprField(ref base, f_name, _) => { let base_cmt = if_ok!(self.cat_expr(&**base)); - Ok(self.cat_field(expr, base_cmt, f_name, expr_ty)) + Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty)) } ast::ExprIndex(ref base, _) => { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 112ecd66f4cc9..1f00fff0ee968 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -805,7 +805,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> { ast::ExprField(ref base, ident, _) => { match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty { ty::ty_struct(id, _) => { - self.check_field(expr.span, id, NamedField(ident)); + self.check_field(expr.span, id, NamedField(ident.node)); } _ => {} } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 795c292b981f2..8ee5e551b9a97 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -5279,7 +5279,7 @@ impl<'a> Resolver<'a> { // field, we need to add any trait methods we find that match // the field name so that we can do some nice error reporting // later on in typeck. - let traits = self.search_for_traits_containing_method(ident.name); + let traits = self.search_for_traits_containing_method(ident.node.name); self.trait_map.insert(expr.id, traits); } ExprMethodCall(ident, _, _) => { diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index 7e26d9c79386e..2b2f3b8fb0b5f 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -1210,7 +1210,7 @@ impl<'l> Visitor for DxrVisitor<'l> { ty::ty_struct(def_id, _) => { let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id); for f in fields.iter() { - if f.name == ident.name { + if f.name == ident.node.name { let sub_span = self.span.span_for_last_ident(ex.span); self.fmt.ref_str(recorder::VarRef, ex.span, diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 7e4bcb8f684f2..45019edc58bdf 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -419,7 +419,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, let brepr = adt::represent_type(cx, bt); let (bv, inlineable) = const_expr(cx, &**base, is_local); expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { - let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys); + let ix = ty::field_idx_strict(cx.tcx(), field.node.name, field_tys); (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable) }) } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index fa65660224685..01ba6113c0d51 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -389,7 +389,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>, trans_def(bcx, expr, bcx.def(expr.id)) } ast::ExprField(ref base, ident, _) => { - trans_rec_field(bcx, &**base, ident) + trans_rec_field(bcx, &**base, ident.node) } ast::ExprIndex(ref base, ref idx) => { trans_index(bcx, expr, &**base, &**idx) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index b24b32bc81fd3..c87b7ec76ee02 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2352,7 +2352,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, expr: &ast::Expr, lvalue_pref: LvaluePreference, base: &ast::Expr, - field: ast::Name, + field: &ast::SpannedIdent, tys: &[ast::P]) { let tcx = fcx.ccx.tcx; check_expr_with_lvalue_pref(fcx, base, lvalue_pref); @@ -2365,7 +2365,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, ty::ty_struct(base_id, ref substs) => { debug!("struct named {}", ppaux::ty_to_str(tcx, base_t)); let fields = ty::lookup_struct_fields(tcx, base_id); - lookup_field_ty(tcx, base_id, fields.as_slice(), field, &(*substs)) + lookup_field_ty(tcx, base_id, fields.as_slice(), field.node.name, &(*substs)) } _ => None } @@ -2383,7 +2383,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, match method::lookup(fcx, expr, base, - field, + field.node.name, expr_t, tps.as_slice(), DontDerefArgs, @@ -2392,14 +2392,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt, IgnoreStaticMethods) { Some(_) => { fcx.type_error_message( - expr.span, + field.span, |actual| { format!("attempted to take value of method `{}` on type \ - `{}`", token::get_name(field), actual) + `{}`", token::get_ident(field.node), actual) }, expr_t, None); - tcx.sess.span_note(expr.span, + tcx.sess.span_note(field.span, "maybe a missing `()` to call it? If not, try an anonymous function."); } @@ -2410,7 +2410,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, format!("attempted access of field `{}` on \ type `{}`, but no field with that \ name was found", - token::get_name(field), + token::get_ident(field.node), actual) }, expr_t, None); @@ -3214,7 +3214,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } } ast::ExprField(ref base, ref field, ref tys) => { - check_field(fcx, expr, lvalue_pref, &**base, field.name, tys.as_slice()); + check_field(fcx, expr, lvalue_pref, &**base, field, tys.as_slice()); } ast::ExprIndex(ref base, ref idx) => { check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 08f412cd76381..ae0fb34d73521 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -464,7 +464,7 @@ pub enum Expr_ { ExprAssign(Gc, Gc), ExprAssignOp(BinOp, Gc, Gc), - ExprField(Gc, Ident, Vec>), + ExprField(Gc, SpannedIdent, Vec>), ExprIndex(Gc, Gc), /// Expression that looks like a "name". For example, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b99ab50c32618..8d48401f9c2a4 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -13,7 +13,7 @@ use ast::{P, Ident, Generics, NodeId, Expr}; use ast; use ast_util; use attr; -use codemap::{Span, respan, Spanned, DUMMY_SP}; +use codemap::{Span, respan, Spanned, DUMMY_SP, Pos}; use ext::base::ExtCtxt; use fold::Folder; use owned_slice::OwnedSlice; @@ -560,7 +560,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn expr_field_access(&self, sp: Span, expr: Gc, ident: ast::Ident) -> Gc { - self.expr(sp, ast::ExprField(expr, ident, Vec::new())) + let field_name = token::get_ident(ident); + let field_span = Span { + lo: sp.lo - Pos::from_uint(field_name.get().len()), + hi: sp.hi, + expn_info: sp.expn_info, + }; + + let id = Spanned { node: ident, span: field_span }; + self.expr(sp, ast::ExprField(expr, id, Vec::new())) } fn expr_addr_of(&self, sp: Span, e: Gc) -> Gc { self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2e538c9579b7e..6d2b0ceed8bf7 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -876,7 +876,7 @@ pub fn noop_fold_expr(e: Gc, folder: &mut T) -> Gc { } ExprField(el, id, ref tys) => { ExprField(folder.fold_expr(el), - folder.fold_ident(id), + respan(id.span, folder.fold_ident(id.node)), tys.iter().map(|&x| folder.fold_ty(x)).collect()) } ExprIndex(el, er) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ae3b8587ee510..698cfab153c6c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1805,7 +1805,7 @@ impl<'a> Parser<'a> { ExprIndex(expr, idx) } - pub fn mk_field(&mut self, expr: Gc, ident: Ident, + pub fn mk_field(&mut self, expr: Gc, ident: ast::SpannedIdent, tys: Vec>) -> ast::Expr_ { ExprField(expr, ident, tys) } @@ -2099,7 +2099,8 @@ impl<'a> Parser<'a> { e = self.mk_expr(lo, hi, nd); } _ => { - let field = self.mk_field(e, i, tys); + let id = spanned(dot, hi, i); + let field = self.mk_field(e, id, tys); e = self.mk_expr(lo, hi, field) } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 63acdb1a6ca75..badfbe7eb1522 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1487,7 +1487,7 @@ impl<'a> State<'a> { ast::ExprField(ref expr, id, ref tys) => { try!(self.print_expr(&**expr)); try!(word(&mut self.s, ".")); - try!(self.print_ident(id)); + try!(self.print_ident(id.node)); if tys.len() > 0u { try!(word(&mut self.s, "::<")); try!(self.commasep( diff --git a/src/test/compile-fail/method-missing-call.rs b/src/test/compile-fail/method-missing-call.rs index 55a178af961ac..3cde24892af3e 100644 --- a/src/test/compile-fail/method-missing-call.rs +++ b/src/test/compile-fail/method-missing-call.rs @@ -28,7 +28,16 @@ impl Point { fn main() { let point: Point = Point::new(); - let px: int = point.get_x;//~ ERROR attempted to take value of method `get_x` on type `Point` - //~^ NOTE maybe a missing `()` to call it? If not, try an anonymous function. + let px: int = point + .get_x;//~ ERROR attempted to take value of method `get_x` on type `Point` + //~^ NOTE maybe a missing `()` to call it? If not, try an anonymous + + // Ensure the span is useful + let ys = &[1,2,3,4,5,6,7]; + let a = ys.iter() + .map(|x| x) + .filter(|&&x| x == 1) + .filter_map; //~ ERROR attempted to take value of method `filter_map` on type + //~^ NOTE maybe a missing `()` to call it? If not, try an anonymous function. }