Skip to content

Commit 075f2bf

Browse files
authored
Rollup merge of #75023 - euclio:argument-span, r=estebank
ensure arguments are included in count mismatch span The current diagnostic isn't very helpful if the function header spans multiple lines. Lines comprising the function signature may be elided to keep the diagnostic short, but these lines are essential to fixing the error. This is made worse when the function has a body, because the last two lines of the span are then dedicated to showing the end of the body, which is irrelevant. This PR changes the span to be a multispan made up of the header and the the arguments, ensuring they won't be elided. It also discards the function body from the span. [Old](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f92d9f81a8c9416f0f04e4e09923b6d4): ``` error[E0061]: this function takes 6 arguments but 1 argument was supplied --> src/main.rs:18:5 | 1 | / fn bar( 2 | | a: i32, 3 | | b: i32, 4 | | c: i32, ... | 14 | | println!("{}", f); 15 | | } | |_- defined here ... 18 | bar(1); | ^^^ - supplied 1 argument | | | expected 6 arguments ``` New: ``` error[E0061]: this function takes 6 arguments but 1 argument was supplied --> $DIR/not-enough-arguments.rs:28:3 | LL | bar(1); | ^^^ - supplied 1 argument | | | expected 6 arguments | note: function defined here --> $DIR/not-enough-arguments.rs:9:1 | LL | / fn bar( LL | | a: i32, | | ^^^^^^^ LL | | b: i32, | | ^^^^^^^ LL | | c: i32, | | ^^^^^^^ LL | | d: i32, | | ^^^^^^^ LL | | e: i32, | | ^^^^^^^ LL | | f: i32, | | ^^^^^^^ LL | | ) { | |_^ ```
2 parents dd7fc54 + 14b2d16 commit 075f2bf

21 files changed

+276
-125
lines changed

compiler/rustc_hir/src/hir.rs

+28
Original file line numberDiff line numberDiff line change
@@ -2742,4 +2742,32 @@ impl<'hir> Node<'hir> {
27422742
_ => None,
27432743
}
27442744
}
2745+
2746+
pub fn hir_id(&self) -> Option<HirId> {
2747+
match self {
2748+
Node::Item(Item { hir_id, .. })
2749+
| Node::ForeignItem(ForeignItem { hir_id, .. })
2750+
| Node::TraitItem(TraitItem { hir_id, .. })
2751+
| Node::ImplItem(ImplItem { hir_id, .. })
2752+
| Node::Field(StructField { hir_id, .. })
2753+
| Node::AnonConst(AnonConst { hir_id, .. })
2754+
| Node::Expr(Expr { hir_id, .. })
2755+
| Node::Stmt(Stmt { hir_id, .. })
2756+
| Node::Ty(Ty { hir_id, .. })
2757+
| Node::Binding(Pat { hir_id, .. })
2758+
| Node::Pat(Pat { hir_id, .. })
2759+
| Node::Arm(Arm { hir_id, .. })
2760+
| Node::Block(Block { hir_id, .. })
2761+
| Node::Local(Local { hir_id, .. })
2762+
| Node::MacroDef(MacroDef { hir_id, .. })
2763+
| Node::Lifetime(Lifetime { hir_id, .. })
2764+
| Node::Param(Param { hir_id, .. })
2765+
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
2766+
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
2767+
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
2768+
Node::Variant(Variant { id, .. }) => Some(*id),
2769+
Node::Ctor(variant) => variant.ctor_hir_id(),
2770+
Node::Crate(_) | Node::Visibility(_) => None,
2771+
}
2772+
}
27452773
}

compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1744,7 +1744,7 @@ impl<'a> Parser<'a> {
17441744
}
17451745
};
17461746

1747-
let span = lo.to(self.token.span);
1747+
let span = lo.until(self.token.span);
17481748

17491749
Ok(Param {
17501750
attrs: attrs.into(),

compiler/rustc_typeck/src/check/callee.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
285285
arg_exprs: &'tcx [hir::Expr<'tcx>],
286286
expected: Expectation<'tcx>,
287287
) -> Ty<'tcx> {
288-
let (fn_sig, def_span) = match *callee_ty.kind() {
289-
ty::FnDef(def_id, _) => {
290-
(callee_ty.fn_sig(self.tcx), self.tcx.hir().span_if_local(def_id))
291-
}
288+
let (fn_sig, def_id) = match *callee_ty.kind() {
289+
ty::FnDef(def_id, _) => (callee_ty.fn_sig(self.tcx), Some(def_id)),
292290
ty::FnPtr(sig) => (sig, None),
293291
ref t => {
294292
let mut unit_variant = None;
@@ -427,7 +425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
427425
arg_exprs,
428426
fn_sig.c_variadic,
429427
TupleArgumentsFlag::DontTupleArguments,
430-
def_span,
428+
def_id,
431429
);
432430

433431
fn_sig.output()

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::ty::fold::TypeFoldable;
1919
use rustc_middle::ty::{self, Ty};
2020
use rustc_session::Session;
2121
use rustc_span::symbol::{sym, Ident};
22-
use rustc_span::{self, Span};
22+
use rustc_span::{self, MultiSpan, Span};
2323
use rustc_trait_selection::traits::{self, ObligationCauseCode};
2424

2525
use std::mem::replace;
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8383
args_no_rcvr,
8484
method.sig.c_variadic,
8585
tuple_arguments,
86-
self.tcx.hir().span_if_local(method.def_id),
86+
Some(method.def_id),
8787
);
8888
method.sig.output()
8989
}
@@ -99,7 +99,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9999
args: &'tcx [hir::Expr<'tcx>],
100100
c_variadic: bool,
101101
tuple_arguments: TupleArgumentsFlag,
102-
def_span: Option<Span>,
102+
def_id: Option<DefId>,
103103
) {
104104
let tcx = self.tcx;
105105
// Grab the argument types, supplying fresh type variables
@@ -172,9 +172,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
172172
);
173173
}
174174

175-
if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
176-
err.span_label(def_s, "defined here");
175+
if let Some(def_id) = def_id {
176+
if let Some(node) = tcx.hir().get_if_local(def_id) {
177+
let mut spans: MultiSpan = node
178+
.ident()
179+
.map(|ident| ident.span)
180+
.unwrap_or_else(|| tcx.hir().span(node.hir_id().unwrap()))
181+
.into();
182+
183+
if let Some(id) = node.body_id() {
184+
let body = tcx.hir().body(id);
185+
for param in body.params {
186+
spans.push_span_label(param.span, String::new());
187+
}
188+
}
189+
190+
let def_kind = tcx.def_kind(def_id);
191+
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
192+
}
177193
}
194+
178195
if sugg_unit {
179196
let sugg_span = tcx.sess.source_map().end_point(expr.span);
180197
// remove closing `)` from the span

src/test/ui/arg-count-mismatch.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
error[E0061]: this function takes 1 argument but 0 arguments were supplied
22
--> $DIR/arg-count-mismatch.rs:5:28
33
|
4-
LL | fn f(x: isize) { }
5-
| -------------- defined here
6-
LL |
74
LL | fn main() { let i: (); i = f(); }
85
| ^-- supplied 0 arguments
96
| |
107
| expected 1 argument
8+
|
9+
note: function defined here
10+
--> $DIR/arg-count-mismatch.rs:3:4
11+
|
12+
LL | fn f(x: isize) { }
13+
| ^ --------
1114

1215
error: aborting due to previous error
1316

src/test/ui/c-variadic/variadic-ffi-1.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,30 @@ LL | fn printf(_: *const u8, ...);
77
error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
88
--> $DIR/variadic-ffi-1.rs:17:9
99
|
10-
LL | fn foo(f: isize, x: u8, ...);
11-
| ----------------------------- defined here
12-
...
1310
LL | foo();
1411
| ^^^-- supplied 0 arguments
1512
| |
1613
| expected at least 2 arguments
14+
|
15+
note: function defined here
16+
--> $DIR/variadic-ffi-1.rs:10:8
17+
|
18+
LL | fn foo(f: isize, x: u8, ...);
19+
| ^^^
1720

1821
error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
1922
--> $DIR/variadic-ffi-1.rs:18:9
2023
|
21-
LL | fn foo(f: isize, x: u8, ...);
22-
| ----------------------------- defined here
23-
...
2424
LL | foo(1);
2525
| ^^^ - supplied 1 argument
2626
| |
2727
| expected at least 2 arguments
28+
|
29+
note: function defined here
30+
--> $DIR/variadic-ffi-1.rs:10:8
31+
|
32+
LL | fn foo(f: isize, x: u8, ...);
33+
| ^^^
2834

2935
error[E0308]: mismatched types
3036
--> $DIR/variadic-ffi-1.rs:20:56

src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: C-variadic function must be declared with at least one named argument
22
--> $DIR/variadic-ffi-no-fixed-args.rs:2:12
33
|
44
LL | fn foo(...);
5-
| ^^^^
5+
| ^^^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0060.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
error[E0060]: this function takes at least 1 argument but 0 arguments were supplied
22
--> $DIR/E0060.rs:6:14
33
|
4-
LL | fn printf(_: *const u8, ...) -> u32;
5-
| ------------------------------------ defined here
6-
...
74
LL | unsafe { printf(); }
85
| ^^^^^^-- supplied 0 arguments
96
| |
107
| expected at least 1 argument
8+
|
9+
note: function defined here
10+
--> $DIR/E0060.rs:2:8
11+
|
12+
LL | fn printf(_: *const u8, ...) -> u32;
13+
| ^^^^^^
1114

1215
error: aborting due to previous error
1316

src/test/ui/error-codes/E0061.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
error[E0061]: this function takes 2 arguments but 1 argument was supplied
22
--> $DIR/E0061.rs:6:5
33
|
4-
LL | fn f(a: u16, b: &str) {}
5-
| --------------------- defined here
6-
...
74
LL | f(0);
85
| ^ - supplied 1 argument
96
| |
107
| expected 2 arguments
8+
|
9+
note: function defined here
10+
--> $DIR/E0061.rs:1:4
11+
|
12+
LL | fn f(a: u16, b: &str) {}
13+
| ^ ------ -------
1114

1215
error[E0061]: this function takes 1 argument but 0 arguments were supplied
1316
--> $DIR/E0061.rs:10:5
1417
|
15-
LL | fn f2(a: u16) {}
16-
| ------------- defined here
17-
...
1818
LL | f2();
1919
| ^^-- supplied 0 arguments
2020
| |
2121
| expected 1 argument
22+
|
23+
note: function defined here
24+
--> $DIR/E0061.rs:3:4
25+
|
26+
LL | fn f2(a: u16) {}
27+
| ^^ ------
2228

2329
error: aborting due to 2 previous errors
2430

src/test/ui/hrtb/issue-58451.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0061]: this function takes 1 argument but 0 arguments were supplied
22
--> $DIR/issue-58451.rs:12:9
33
|
4-
LL | / fn f<I>(i: I)
5-
LL | | where
6-
LL | | I: IntoIterator,
7-
LL | | I::Item: for<'a> Into<&'a ()>,
8-
| |__________________________________- defined here
9-
...
10-
LL | f(&[f()]);
11-
| ^-- supplied 0 arguments
12-
| |
13-
| expected 1 argument
4+
LL | f(&[f()]);
5+
| ^-- supplied 0 arguments
6+
| |
7+
| expected 1 argument
8+
|
9+
note: function defined here
10+
--> $DIR/issue-58451.rs:5:4
11+
|
12+
LL | fn f<I>(i: I)
13+
| ^ ----
1414

1515
error: aborting due to previous error
1616

src/test/ui/issues/issue-18819.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
error[E0061]: this function takes 2 arguments but 1 argument was supplied
22
--> $DIR/issue-18819.rs:16:5
33
|
4-
LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
5-
| ----------------------------------------------- defined here
6-
...
74
LL | print_x(X);
85
| ^^^^^^^ - supplied 1 argument
96
| |
107
| expected 2 arguments
8+
|
9+
note: function defined here
10+
--> $DIR/issue-18819.rs:11:4
11+
|
12+
LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
13+
| ^^^^^^^ ---------------------- -----------
1114

1215
error: aborting due to previous error
1316

src/test/ui/issues/issue-26094.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
44
LL | $other(None)
55
| ---- supplied 1 argument
66
...
7-
LL | fn some_function() {}
8-
| ------------------ defined here
9-
...
107
LL | some_macro!(some_function);
118
| ^^^^^^^^^^^^^ expected 0 arguments
9+
|
10+
note: function defined here
11+
--> $DIR/issue-26094.rs:7:4
12+
|
13+
LL | fn some_function() {}
14+
| ^^^^^^^^^^^^^
1215

1316
error: aborting due to previous error
1417

src/test/ui/issues/issue-4935.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
error[E0061]: this function takes 1 argument but 2 arguments were supplied
22
--> $DIR/issue-4935.rs:5:13
33
|
4-
LL | fn foo(a: usize) {}
5-
| ---------------- defined here
6-
LL |
74
LL | fn main() { foo(5, 6) }
85
| ^^^ - - supplied 2 arguments
96
| |
107
| expected 1 argument
8+
|
9+
note: function defined here
10+
--> $DIR/issue-4935.rs:3:4
11+
|
12+
LL | fn foo(a: usize) {}
13+
| ^^^ --------
1114

1215
error: aborting due to previous error
1316

0 commit comments

Comments
 (0)