about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/privacy.rs2
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/typeck/check/mod.rs15
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ext/build.rs5
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/parse/parser.rs10
-rw-r--r--src/libsyntax/print/pprust.rs2
-rw-r--r--src/test/compile-fail/method-call-err-msg.rs30
9 files changed, 53 insertions, 17 deletions
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index eeccd1ca334..17666f33494 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -791,7 +791,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
                     }
                     Some(method) => {
                         debug!("(privacy checking) checking impl method");
-                        self.check_method(expr.span, method.origin, ident);
+                        self.check_method(expr.span, method.origin, ident.node);
                     }
                 }
             }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index ab345ecb243..d429ead39d6 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -5083,7 +5083,7 @@ impl<'a> Resolver<'a> {
                 debug!("(recording candidate traits for expr) recording \
                         traits for {}",
                        expr.id);
-                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);
             }
             _ => {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 9a261689b37..ce35d1ab1de 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1722,7 +1722,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                 }
                 _ => {
                     fcx.tcx().sess.span_bug(
-                        sp,
+                        callee_expr.span,
                         format!("method without bare fn type"));
                 }
             }
@@ -1936,7 +1936,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
     // Checks a method call.
     fn check_method_call(fcx: &FnCtxt,
                          expr: &ast::Expr,
-                         method_name: ast::Ident,
+                         method_name: ast::SpannedIdent,
                          args: &[@ast::Expr],
                          tps: &[ast::P<ast::Ty>]) {
         let rcvr = args[0];
@@ -1952,7 +1952,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
 
         let tps = tps.iter().map(|&ast_ty| fcx.to_ty(ast_ty)).collect::<Vec<_>>();
         let fn_ty = match method::lookup(fcx, expr, rcvr,
-                                         method_name.name,
+                                         method_name.node.name,
                                          expr_t, tps.as_slice(),
                                          DontDerefArgs,
                                          CheckTraitsAndInherentMethods,
@@ -1966,11 +1966,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             None => {
                 debug!("(checking method call) failing expr is {}", expr.id);
 
-                fcx.type_error_message(expr.span,
+                fcx.type_error_message(method_name.span,
                   |actual| {
-                      format!("type `{}` does not implement any method in scope \
-                            named `{}`",
-                           actual, token::get_ident(method_name))
+                      format!("type `{}` does not implement any method in scope named `{}`",
+                              actual, token::get_ident(method_name.node))
                   },
                   expr_t,
                   None);
@@ -1982,7 +1981,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         };
 
         // Call the generic checker.
-        let ret_ty = check_method_argument_types(fcx, expr.span,
+        let ret_ty = check_method_argument_types(fcx, method_name.span,
                                                  fn_ty, expr, args,
                                                  DontDerefArgs);
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 116411c9e05..12a57cacc3a 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -480,7 +480,7 @@ pub enum Expr_ {
     ExprBox(@Expr, @Expr),
     ExprVec(Vec<@Expr>),
     ExprCall(@Expr, Vec<@Expr>),
-    ExprMethodCall(Ident, Vec<P<Ty>>, Vec<@Expr>),
+    ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>),
     ExprTup(Vec<@Expr>),
     ExprBinary(BinOp, @Expr, @Expr),
     ExprUnary(UnOp, @Expr),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index e1174ea6cc4..d5465303394 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -12,7 +12,7 @@ use abi;
 use ast::{P, Ident};
 use ast;
 use ast_util;
-use codemap::{Span, respan, DUMMY_SP};
+use codemap::{Span, respan, Spanned, DUMMY_SP};
 use ext::base::ExtCtxt;
 use ext::quote::rt::*;
 use fold::Folder;
@@ -548,8 +548,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                         expr: @ast::Expr,
                         ident: ast::Ident,
                         mut args: Vec<@ast::Expr> ) -> @ast::Expr {
+        let id = Spanned { node: ident, span: span };
         args.unshift(expr);
-        self.expr(span, ast::ExprMethodCall(ident, Vec::new(), args))
+        self.expr(span, ast::ExprMethodCall(id, Vec::new(), args))
     }
     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
         self.expr(b.span, ast::ExprBlock(b))
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 04b289b9fca..d50e425b9a7 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -797,7 +797,7 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
         }
         ExprMethodCall(i, ref tps, ref args) => {
             ExprMethodCall(
-                folder.fold_ident(i),
+                respan(i.span, folder.fold_ident(i.node)),
                 tps.iter().map(|&x| folder.fold_ty(x)).collect(),
                 args.iter().map(|&x| folder.fold_expr(x)).collect())
         }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8808312bed7..8f011ffab5f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1646,7 +1646,11 @@ impl<'a> Parser<'a> {
         ExprCall(f, args)
     }
 
-    fn mk_method_call(&mut self, ident: Ident, tps: Vec<P<Ty>> , args: Vec<@Expr> ) -> ast::Expr_ {
+    fn mk_method_call(&mut self,
+                      ident: ast::SpannedIdent,
+                      tps: Vec<P<Ty>>,
+                      args: Vec<@Expr>)
+                      -> ast::Expr_ {
         ExprMethodCall(ident, tps, args)
     }
 
@@ -1919,6 +1923,7 @@ impl<'a> Parser<'a> {
             if self.eat(&token::DOT) {
                 match self.token {
                   token::IDENT(i, _) => {
+                    let dot = self.last_span.hi;
                     hi = self.span.hi;
                     self.bump();
                     let (_, tys) = if self.eat(&token::MOD_SEP) {
@@ -1940,7 +1945,8 @@ impl<'a> Parser<'a> {
                             hi = self.last_span.hi;
 
                             es.unshift(e);
-                            let nd = self.mk_method_call(i, tys, es);
+                            let id = spanned(dot, hi, i);
+                            let nd = self.mk_method_call(id, tys, es);
                             e = self.mk_expr(lo, hi, nd);
                         }
                         _ => {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f768bf22ce0..2f5f1f07fc5 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1208,7 +1208,7 @@ impl<'a> State<'a> {
                 let base_args = args.slice_from(1);
                 try!(self.print_expr(*args.get(0)));
                 try!(word(&mut self.s, "."));
-                try!(self.print_ident(ident));
+                try!(self.print_ident(ident.node));
                 if tys.len() > 0u {
                     try!(word(&mut self.s, "::<"));
                     try!(self.commasep(Inconsistent, tys.as_slice(),
diff --git a/src/test/compile-fail/method-call-err-msg.rs b/src/test/compile-fail/method-call-err-msg.rs
new file mode 100644
index 00000000000..3610a0e2e9d
--- /dev/null
+++ b/src/test/compile-fail/method-call-err-msg.rs
@@ -0,0 +1,30 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that parameter cardinality or missing method error gets span exactly.
+
+pub struct Foo;
+impl Foo {
+    fn zero(self) -> Foo { self }
+    fn one(self, _: int) -> Foo { self }
+    fn two(self, _: int, _: int) -> Foo { self }
+}
+
+fn main() {
+    let x = Foo;
+    x.zero(0)   //~ ERROR this function takes 0 parameters but 1 parameter was supplied
+     .one()     //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+     .two(0);   //~ ERROR this function takes 2 parameters but 1 parameter was supplied
+
+    let y = Foo;
+    y.zero()
+     .take()    //~ ERROR type `Foo` does not implement any method in scope named `take`
+     .one(0);
+}