Skip to content

Commit 2af3445

Browse files
Rollup merge of rust-lang#99646 - compiler-errors:arg-mismatch-single-arg-label, r=estebank
Only point out a single function parameter if we have a single arg incompatibility Fixes rust-lang#99635
2 parents b76fec3 + c608918 commit 2af3445

18 files changed

+148
-61
lines changed

compiler/rustc_parse/src/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ impl<'a> Parser<'a> {
22682268
attrs: attrs.into(),
22692269
ty,
22702270
pat,
2271-
span: lo.to(this.token.span),
2271+
span: lo.to(this.prev_token.span),
22722272
id: DUMMY_NODE_ID,
22732273
is_placeholder: false,
22742274
},

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

+40-18
Original file line numberDiff line numberDiff line change
@@ -440,30 +440,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
440440
call_expr: &hir::Expr<'tcx>,
441441
) {
442442
// Next, let's construct the error
443-
let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
443+
let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
444444
hir::ExprKind::Call(
445445
hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
446446
_,
447447
) => {
448448
if let Res::Def(DefKind::Ctor(of, _), _) =
449449
self.typeck_results.borrow().qpath_res(qpath, *hir_id)
450450
{
451-
(call_span, *span, Some(of))
451+
(call_span, *span, Some(of), false)
452452
} else {
453-
(call_span, *span, None)
453+
(call_span, *span, None, false)
454454
}
455455
}
456-
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
456+
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
457457
hir::ExprKind::MethodCall(path_segment, _, span) => {
458458
let ident_span = path_segment.ident.span;
459459
let ident_span = if let Some(args) = path_segment.args {
460460
ident_span.with_hi(args.span_ext.hi())
461461
} else {
462462
ident_span
463463
};
464-
(
465-
*span, ident_span, None, // methods are never ctors
466-
)
464+
// methods are never ctors
465+
(*span, ident_span, None, true)
467466
}
468467
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
469468
};
@@ -659,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659658
Applicability::MachineApplicable,
660659
);
661660
};
662-
self.label_fn_like(&mut err, fn_def_id, callee_ty);
661+
self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method);
663662
err.emit();
664663
return;
665664
}
@@ -701,16 +700,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
701700
}
702701

703702
errors.drain_filter(|error| {
704-
let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(error)) = error else { return false };
703+
let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
705704
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
706705
let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
707706
let cause = &self.misc(provided_span);
708707
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
709-
if let Some(e) = error {
710-
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
711-
self.report_and_explain_type_error(trace, e).emit();
712-
return true;
713-
}
708+
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
709+
self.report_and_explain_type_error(trace, e).emit();
710+
return true;
714711
}
715712
false
716713
});
@@ -749,7 +746,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
749746
format!("arguments to this {} are incorrect", call_name),
750747
);
751748
// Call out where the function is defined
752-
self.label_fn_like(&mut err, fn_def_id, callee_ty);
749+
self.label_fn_like(
750+
&mut err,
751+
fn_def_id,
752+
callee_ty,
753+
Some(expected_idx.as_usize()),
754+
is_method,
755+
);
753756
err.emit();
754757
return;
755758
}
@@ -1031,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10311034
}
10321035

10331036
// Call out where the function is defined
1034-
self.label_fn_like(&mut err, fn_def_id, callee_ty);
1037+
self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
10351038

10361039
// And add a suggestion block for all of the parameters
10371040
let suggestion_text = match suggestion_text {
@@ -1781,6 +1784,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17811784
err: &mut Diagnostic,
17821785
callable_def_id: Option<DefId>,
17831786
callee_ty: Option<Ty<'tcx>>,
1787+
// A specific argument should be labeled, instead of all of them
1788+
expected_idx: Option<usize>,
1789+
is_method: bool,
17841790
) {
17851791
let Some(mut def_id) = callable_def_id else {
17861792
return;
@@ -1881,14 +1887,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18811887
.get_if_local(def_id)
18821888
.and_then(|node| node.body_id())
18831889
.into_iter()
1884-
.flat_map(|id| self.tcx.hir().body(id).params);
1890+
.flat_map(|id| self.tcx.hir().body(id).params)
1891+
.skip(if is_method { 1 } else { 0 });
18851892

1886-
for param in params {
1893+
for (_, param) in params
1894+
.into_iter()
1895+
.enumerate()
1896+
.filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
1897+
{
18871898
spans.push_span_label(param.span, "");
18881899
}
18891900

18901901
let def_kind = self.tcx.def_kind(def_id);
18911902
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
1903+
} else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
1904+
&& let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
1905+
{
1906+
let param = expected_idx
1907+
.and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
1908+
let (kind, span) = if let Some(param) = param {
1909+
("closure parameter", param.span)
1910+
} else {
1911+
("closure", self.tcx.def_span(def_id))
1912+
};
1913+
err.span_note(span, &format!("{} defined here", kind));
18921914
} else {
18931915
let def_kind = self.tcx.def_kind(def_id);
18941916
err.span_note(

src/test/ui/argument-suggestions/invalid_arguments.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ note: function defined here
2424
--> $DIR/invalid_arguments.rs:6:4
2525
|
2626
LL | fn two_arg_same(_a: i32, _b: i32) {}
27-
| ^^^^^^^^^^^^ ------- -------
27+
| ^^^^^^^^^^^^ -------
2828

2929
error[E0308]: mismatched types
3030
--> $DIR/invalid_arguments.rs:17:16
@@ -38,7 +38,7 @@ note: function defined here
3838
--> $DIR/invalid_arguments.rs:6:4
3939
|
4040
LL | fn two_arg_same(_a: i32, _b: i32) {}
41-
| ^^^^^^^^^^^^ ------- -------
41+
| ^^^^^^^^^^^^ -------
4242

4343
error[E0308]: arguments to this function are incorrect
4444
--> $DIR/invalid_arguments.rs:18:3
@@ -66,7 +66,7 @@ note: function defined here
6666
--> $DIR/invalid_arguments.rs:7:4
6767
|
6868
LL | fn two_arg_diff(_a: i32, _b: f32) {}
69-
| ^^^^^^^^^^^^ ------- -------
69+
| ^^^^^^^^^^^^ -------
7070

7171
error[E0308]: mismatched types
7272
--> $DIR/invalid_arguments.rs:20:16
@@ -80,7 +80,7 @@ note: function defined here
8080
--> $DIR/invalid_arguments.rs:7:4
8181
|
8282
LL | fn two_arg_diff(_a: i32, _b: f32) {}
83-
| ^^^^^^^^^^^^ ------- -------
83+
| ^^^^^^^^^^^^ -------
8484

8585
error[E0308]: arguments to this function are incorrect
8686
--> $DIR/invalid_arguments.rs:21:3
@@ -108,7 +108,7 @@ note: function defined here
108108
--> $DIR/invalid_arguments.rs:8:4
109109
|
110110
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
111-
| ^^^^^^^^^^^^^^ ------- ------- --------
111+
| ^^^^^^^^^^^^^^ -------
112112

113113
error[E0308]: mismatched types
114114
--> $DIR/invalid_arguments.rs:25:21
@@ -122,7 +122,7 @@ note: function defined here
122122
--> $DIR/invalid_arguments.rs:8:4
123123
|
124124
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
125-
| ^^^^^^^^^^^^^^ ------- ------- --------
125+
| ^^^^^^^^^^^^^^ -------
126126

127127
error[E0308]: mismatched types
128128
--> $DIR/invalid_arguments.rs:26:26
@@ -136,7 +136,7 @@ note: function defined here
136136
--> $DIR/invalid_arguments.rs:8:4
137137
|
138138
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
139-
| ^^^^^^^^^^^^^^ ------- ------- --------
139+
| ^^^^^^^^^^^^^^ --------
140140

141141
error[E0308]: arguments to this function are incorrect
142142
--> $DIR/invalid_arguments.rs:28:3
@@ -207,7 +207,7 @@ note: function defined here
207207
--> $DIR/invalid_arguments.rs:9:4
208208
|
209209
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
210-
| ^^^^^^^^^^^^^^^^ ------- ------- --------
210+
| ^^^^^^^^^^^^^^^^ -------
211211

212212
error[E0308]: mismatched types
213213
--> $DIR/invalid_arguments.rs:35:23
@@ -221,7 +221,7 @@ note: function defined here
221221
--> $DIR/invalid_arguments.rs:9:4
222222
|
223223
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
224-
| ^^^^^^^^^^^^^^^^ ------- ------- --------
224+
| ^^^^^^^^^^^^^^^^ -------
225225

226226
error[E0308]: mismatched types
227227
--> $DIR/invalid_arguments.rs:36:26
@@ -235,7 +235,7 @@ note: function defined here
235235
--> $DIR/invalid_arguments.rs:9:4
236236
|
237237
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
238-
| ^^^^^^^^^^^^^^^^ ------- ------- --------
238+
| ^^^^^^^^^^^^^^^^ --------
239239

240240
error[E0308]: arguments to this function are incorrect
241241
--> $DIR/invalid_arguments.rs:38:3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
struct Qux;
2+
3+
impl Qux {
4+
fn foo(
5+
&self,
6+
a: i32,
7+
b: i32,
8+
c: i32,
9+
d: i32,
10+
e: i32,
11+
f: i32,
12+
g: i32,
13+
h: i32,
14+
i: i32,
15+
j: i32,
16+
k: i32,
17+
l: i32,
18+
) {
19+
}
20+
}
21+
22+
fn what(
23+
qux: &Qux,
24+
a: i32,
25+
b: i32,
26+
c: i32,
27+
d: i32,
28+
e: i32,
29+
f: &i32,
30+
g: i32,
31+
h: i32,
32+
i: i32,
33+
j: i32,
34+
k: i32,
35+
l: i32,
36+
) {
37+
qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
38+
//~^ ERROR mismatched types
39+
}
40+
41+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/too-long.rs:37:28
3+
|
4+
LL | qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
5+
| --- ^ expected `i32`, found `&i32`
6+
| |
7+
| arguments to this function are incorrect
8+
|
9+
note: associated function defined here
10+
--> $DIR/too-long.rs:4:8
11+
|
12+
LL | fn foo(
13+
| ^^^
14+
...
15+
LL | f: i32,
16+
| ------
17+
help: consider dereferencing the borrow
18+
|
19+
LL | qux.foo(a, b, c, d, e, *f, g, h, i, j, k, l);
20+
| +
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ note: function defined here
1010
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
1111
|
1212
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
13-
| ^^^^ ---- ---------------
13+
| ^^^^ ---------------
1414

1515
error[E0308]: mismatched types
1616
--> $DIR/associated-type-projection-from-supertrait.rs:28:23
@@ -24,7 +24,7 @@ note: function defined here
2424
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
2525
|
2626
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
27-
| ^^^^ ---- ---------------
27+
| ^^^^ ---------------
2828

2929
error[E0308]: mismatched types
3030
--> $DIR/associated-type-projection-from-supertrait.rs:32:28
@@ -38,7 +38,7 @@ note: associated function defined here
3838
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
3939
|
4040
LL | fn chip_paint(&self, c: Self::Color) { }
41-
| ^^^^^^^^^^ ----- --------------
41+
| ^^^^^^^^^^ --------------
4242

4343
error[E0308]: mismatched types
4444
--> $DIR/associated-type-projection-from-supertrait.rs:33:28
@@ -52,7 +52,7 @@ note: associated function defined here
5252
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
5353
|
5454
LL | fn chip_paint(&self, c: Self::Color) { }
55-
| ^^^^^^^^^^ ----- --------------
55+
| ^^^^^^^^^^ --------------
5656

5757
error: aborting due to 4 previous errors
5858

src/test/ui/associated-types/associated-types-path-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ note: function defined here
1010
--> $DIR/associated-types-path-2.rs:13:8
1111
|
1212
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
13-
| ^^ ---- -------
13+
| ^^ -------
1414
help: change the type of the numeric literal from `i32` to `u32`
1515
|
1616
LL | f1(2i32, 4u32);

src/test/ui/async-await/generator-desc.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ note: function defined here
4242
--> $DIR/generator-desc.rs:8:4
4343
|
4444
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
45-
| ^^^ ----- -----
45+
| ^^^ -----
4646

4747
error[E0308]: mismatched types
4848
--> $DIR/generator-desc.rs:14:26
@@ -67,7 +67,7 @@ note: function defined here
6767
--> $DIR/generator-desc.rs:8:4
6868
|
6969
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
70-
| ^^^ ----- -----
70+
| ^^^ -----
7171

7272
error: aborting due to 3 previous errors
7373

src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: function defined here
1212
--> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
1313
|
1414
LL | fn test<T>(_a: T, _b: T) {}
15-
| ^^^^ ----- -----
15+
| ^^^^ -----
1616

1717
error: aborting due to previous error
1818

0 commit comments

Comments
 (0)