Skip to content

Commit 20121fa

Browse files
Point out a single arg if we have a single arg incompatibility
1 parent 569788e commit 20121fa

16 files changed

+130
-58
lines changed

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

Lines changed: 26 additions & 19 deletions
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,7 @@ 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(&mut err, fn_def_id, callee_ty, Some(expected_idx.as_usize()), is_method);
753750
err.emit();
754751
return;
755752
}
@@ -1031,7 +1028,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10311028
}
10321029

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

10361033
// And add a suggestion block for all of the parameters
10371034
let suggestion_text = match suggestion_text {
@@ -1781,6 +1778,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17811778
err: &mut Diagnostic,
17821779
callable_def_id: Option<DefId>,
17831780
callee_ty: Option<Ty<'tcx>>,
1781+
// A specific argument should be labeled, instead of all of them
1782+
expected_idx: Option<usize>,
1783+
is_method: bool,
17841784
) {
17851785
let Some(mut def_id) = callable_def_id else {
17861786
return;
@@ -1881,10 +1881,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18811881
.get_if_local(def_id)
18821882
.and_then(|node| node.body_id())
18831883
.into_iter()
1884-
.flat_map(|id| self.tcx.hir().body(id).params);
1884+
.flat_map(|id| self.tcx.hir().body(id).params)
1885+
.skip(if is_method { 1 } else { 0 });
18851886

1886-
for param in params {
1887-
spans.push_span_label(param.span, "");
1887+
for (idx, param) in params.into_iter().enumerate() {
1888+
if let Some(expected_idx) = expected_idx {
1889+
if idx == expected_idx {
1890+
spans.push_span_label(param.span, "");
1891+
}
1892+
} else {
1893+
spans.push_span_label(param.span, "");
1894+
}
18881895
}
18891896

18901897
let def_kind = self.tcx.def_kind(def_id);

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

Lines changed: 10 additions & 10 deletions
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
Lines changed: 41 additions & 0 deletions
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() {}
Lines changed: 24 additions & 0 deletions
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 1 deletion
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

src/test/ui/coercion/coerce-to-bang.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: function defined here
1212
--> $DIR/coerce-to-bang.rs:3:4
1313
|
1414
LL | fn foo(x: usize, y: !, z: usize) { }
15-
| ^^^ -------- ---- --------
15+
| ^^^ ----
1616

1717
error[E0308]: mismatched types
1818
--> $DIR/coerce-to-bang.rs:18:13
@@ -28,7 +28,7 @@ note: function defined here
2828
--> $DIR/coerce-to-bang.rs:3:4
2929
|
3030
LL | fn foo(x: usize, y: !, z: usize) { }
31-
| ^^^ -------- ---- --------
31+
| ^^^ ----
3232

3333
error[E0308]: mismatched types
3434
--> $DIR/coerce-to-bang.rs:26:12
@@ -44,7 +44,7 @@ note: function defined here
4444
--> $DIR/coerce-to-bang.rs:3:4
4545
|
4646
LL | fn foo(x: usize, y: !, z: usize) { }
47-
| ^^^ -------- ---- --------
47+
| ^^^ ----
4848

4949
error[E0308]: mismatched types
5050
--> $DIR/coerce-to-bang.rs:36:12
@@ -60,7 +60,7 @@ note: function defined here
6060
--> $DIR/coerce-to-bang.rs:3:4
6161
|
6262
LL | fn foo(x: usize, y: !, z: usize) { }
63-
| ^^^ -------- ---- --------
63+
| ^^^ ----
6464

6565
error[E0308]: mismatched types
6666
--> $DIR/coerce-to-bang.rs:45:12
@@ -76,7 +76,7 @@ note: function defined here
7676
--> $DIR/coerce-to-bang.rs:3:4
7777
|
7878
LL | fn foo(x: usize, y: !, z: usize) { }
79-
| ^^^ -------- ---- --------
79+
| ^^^ ----
8080

8181
error[E0308]: mismatched types
8282
--> $DIR/coerce-to-bang.rs:50:21

0 commit comments

Comments
 (0)