auto merge of #13713 : edwardw/rust/methodcall-span, r=alexcrichton
Specifically, the method parameter cardinality mismatch or missing method error message span now gets method itself exactly. It was the whole expression. Closes #9390 Closes #13684 Closes #13709
This commit is contained in:
commit
70647ccc6d
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
_ => {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -481,7 +481,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),
|
||||
|
@ -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))
|
||||
|
@ -798,7 +798,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())
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
_ => {
|
||||
|
@ -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(),
|
||||
|
30
src/test/compile-fail/method-call-err-msg.rs
Normal file
30
src/test/compile-fail/method-call-err-msg.rs
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user