Skip to content

Commit 899f222

Browse files
committed
Calibrate span for method call error messages
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
1 parent b5dd3f0 commit 899f222

File tree

9 files changed

+53
-17
lines changed

9 files changed

+53
-17
lines changed

src/librustc/middle/privacy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
791791
}
792792
Some(method) => {
793793
debug!("(privacy checking) checking impl method");
794-
self.check_method(expr.span, method.origin, ident);
794+
self.check_method(expr.span, method.origin, ident.node);
795795
}
796796
}
797797
}

src/librustc/middle/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5083,7 +5083,7 @@ impl<'a> Resolver<'a> {
50835083
debug!("(recording candidate traits for expr) recording \
50845084
traits for {}",
50855085
expr.id);
5086-
let traits = self.search_for_traits_containing_method(ident.name);
5086+
let traits = self.search_for_traits_containing_method(ident.node.name);
50875087
self.trait_map.insert(expr.id, traits);
50885088
}
50895089
_ => {

src/librustc/middle/typeck/check/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
17221722
}
17231723
_ => {
17241724
fcx.tcx().sess.span_bug(
1725-
sp,
1725+
callee_expr.span,
17261726
format!("method without bare fn type"));
17271727
}
17281728
}
@@ -1936,7 +1936,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
19361936
// Checks a method call.
19371937
fn check_method_call(fcx: &FnCtxt,
19381938
expr: &ast::Expr,
1939-
method_name: ast::Ident,
1939+
method_name: ast::SpannedIdent,
19401940
args: &[@ast::Expr],
19411941
tps: &[ast::P<ast::Ty>]) {
19421942
let rcvr = args[0];
@@ -1952,7 +1952,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
19521952

19531953
let tps = tps.iter().map(|&ast_ty| fcx.to_ty(ast_ty)).collect::<Vec<_>>();
19541954
let fn_ty = match method::lookup(fcx, expr, rcvr,
1955-
method_name.name,
1955+
method_name.node.name,
19561956
expr_t, tps.as_slice(),
19571957
DontDerefArgs,
19581958
CheckTraitsAndInherentMethods,
@@ -1966,11 +1966,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
19661966
None => {
19671967
debug!("(checking method call) failing expr is {}", expr.id);
19681968

1969-
fcx.type_error_message(expr.span,
1969+
fcx.type_error_message(method_name.span,
19701970
|actual| {
1971-
format!("type `{}` does not implement any method in scope \
1972-
named `{}`",
1973-
actual, token::get_ident(method_name))
1971+
format!("type `{}` does not implement any method in scope named `{}`",
1972+
actual, token::get_ident(method_name.node))
19741973
},
19751974
expr_t,
19761975
None);
@@ -1982,7 +1981,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
19821981
};
19831982

19841983
// Call the generic checker.
1985-
let ret_ty = check_method_argument_types(fcx, expr.span,
1984+
let ret_ty = check_method_argument_types(fcx, method_name.span,
19861985
fn_ty, expr, args,
19871986
DontDerefArgs);
19881987

src/libsyntax/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ pub enum Expr_ {
480480
ExprBox(@Expr, @Expr),
481481
ExprVec(Vec<@Expr>),
482482
ExprCall(@Expr, Vec<@Expr>),
483-
ExprMethodCall(Ident, Vec<P<Ty>>, Vec<@Expr>),
483+
ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>),
484484
ExprTup(Vec<@Expr>),
485485
ExprBinary(BinOp, @Expr, @Expr),
486486
ExprUnary(UnOp, @Expr),

src/libsyntax/ext/build.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use abi;
1212
use ast::{P, Ident};
1313
use ast;
1414
use ast_util;
15-
use codemap::{Span, respan, DUMMY_SP};
15+
use codemap::{Span, respan, Spanned, DUMMY_SP};
1616
use ext::base::ExtCtxt;
1717
use ext::quote::rt::*;
1818
use fold::Folder;
@@ -548,8 +548,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
548548
expr: @ast::Expr,
549549
ident: ast::Ident,
550550
mut args: Vec<@ast::Expr> ) -> @ast::Expr {
551+
let id = Spanned { node: ident, span: span };
551552
args.unshift(expr);
552-
self.expr(span, ast::ExprMethodCall(ident, Vec::new(), args))
553+
self.expr(span, ast::ExprMethodCall(id, Vec::new(), args))
553554
}
554555
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
555556
self.expr(b.span, ast::ExprBlock(b))

src/libsyntax/fold.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
797797
}
798798
ExprMethodCall(i, ref tps, ref args) => {
799799
ExprMethodCall(
800-
folder.fold_ident(i),
800+
respan(i.span, folder.fold_ident(i.node)),
801801
tps.iter().map(|&x| folder.fold_ty(x)).collect(),
802802
args.iter().map(|&x| folder.fold_expr(x)).collect())
803803
}

src/libsyntax/parse/parser.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,11 @@ impl<'a> Parser<'a> {
16461646
ExprCall(f, args)
16471647
}
16481648

1649-
fn mk_method_call(&mut self, ident: Ident, tps: Vec<P<Ty>> , args: Vec<@Expr> ) -> ast::Expr_ {
1649+
fn mk_method_call(&mut self,
1650+
ident: ast::SpannedIdent,
1651+
tps: Vec<P<Ty>>,
1652+
args: Vec<@Expr>)
1653+
-> ast::Expr_ {
16501654
ExprMethodCall(ident, tps, args)
16511655
}
16521656

@@ -1919,6 +1923,7 @@ impl<'a> Parser<'a> {
19191923
if self.eat(&token::DOT) {
19201924
match self.token {
19211925
token::IDENT(i, _) => {
1926+
let dot = self.last_span.hi;
19221927
hi = self.span.hi;
19231928
self.bump();
19241929
let (_, tys) = if self.eat(&token::MOD_SEP) {
@@ -1940,7 +1945,8 @@ impl<'a> Parser<'a> {
19401945
hi = self.last_span.hi;
19411946

19421947
es.unshift(e);
1943-
let nd = self.mk_method_call(i, tys, es);
1948+
let id = spanned(dot, hi, i);
1949+
let nd = self.mk_method_call(id, tys, es);
19441950
e = self.mk_expr(lo, hi, nd);
19451951
}
19461952
_ => {

src/libsyntax/print/pprust.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,7 @@ impl<'a> State<'a> {
12081208
let base_args = args.slice_from(1);
12091209
try!(self.print_expr(*args.get(0)));
12101210
try!(word(&mut self.s, "."));
1211-
try!(self.print_ident(ident));
1211+
try!(self.print_ident(ident.node));
12121212
if tys.len() > 0u {
12131213
try!(word(&mut self.s, "::<"));
12141214
try!(self.commasep(Inconsistent, tys.as_slice(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that parameter cardinality or missing method error gets span exactly.
12+
13+
pub struct Foo;
14+
impl Foo {
15+
fn zero(self) -> Foo { self }
16+
fn one(self, _: int) -> Foo { self }
17+
fn two(self, _: int, _: int) -> Foo { self }
18+
}
19+
20+
fn main() {
21+
let x = Foo;
22+
x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
23+
.one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
24+
.two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
25+
26+
let y = Foo;
27+
y.zero()
28+
.take() //~ ERROR type `Foo` does not implement any method in scope named `take`
29+
.one(0);
30+
}

0 commit comments

Comments
 (0)