Skip to content

Commit b3e76aa

Browse files
Rollup merge of #100479 - compiler-errors:argument-type-error-improvements, r=lcnr
Argument type error improvements Motivated by this interesting code snippet: ```rust #[derive(Copy, Clone)] struct Wrapper<T>(T); fn foo(_: fn(i32), _: Wrapper<i32>) {} fn f(_: u32) {} fn main() { let w = Wrapper::<isize>(1isize); foo(f, w); } ``` Which currently errors like: ``` error[E0308]: arguments to this function are incorrect --> src/main.rs:10:5 | 10 | foo(f, w); | ^^^ - - expected `i32`, found `isize` | | | expected `i32`, found `u32` | = note: expected fn pointer `fn(i32)` found fn item `fn(u32) {f}` = note: expected struct `Wrapper<i32>` found struct `Wrapper<isize>` note: function defined here --> src/main.rs:4:4 | 4 | fn foo(_: fn(i32), _: Wrapper<i32>) {} | ^^^ ---------- --------------- ``` Specifically, that double `expected .. found ..` which is very difficult to correlate to the types in the arguments. Also, the fact that "expected `i32`, found `isize`" and the other argument mismatch label don't even really explain what's going on here. After this PR: ``` error[E0308]: arguments to this function are incorrect --> $DIR/two-mismatch-notes.rs:10:5 | LL | foo(f, w); | ^^^ | note: expected fn pointer, found fn item --> $DIR/two-mismatch-notes.rs:10:9 | LL | foo(f, w); | ^ = note: expected fn pointer `fn(i32)` found fn item `fn(u32) {f}` note: expected struct `Wrapper`, found a different struct `Wrapper` --> $DIR/two-mismatch-notes.rs:10:12 | LL | foo(f, w); | ^ = note: expected struct `Wrapper<i32>` found struct `Wrapper<isize>` note: function defined here --> $DIR/two-mismatch-notes.rs:4:4 | LL | fn foo(_: fn(i32), _: Wrapper<i32>) {} | ^^^ ---------- --------------- error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. ``` Yeah, it's a bit verbose, but much clearer IMO. --- Open to discussions about how this could be further improved. Motivated by `@jyn514's` [tweet](https://mobile.twitter.com/joshuayn514/status/1558042020601634816) here.
2 parents 809fc86 + aa1a07f commit b3e76aa

File tree

9 files changed

+76
-20
lines changed

9 files changed

+76
-20
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14241424
/// E0271, like `src/test/ui/issues/issue-39970.stderr`.
14251425
#[tracing::instrument(
14261426
level = "debug",
1427-
skip(self, diag, secondary_span, swap_secondary_and_primary, force_label)
1427+
skip(self, diag, secondary_span, swap_secondary_and_primary, prefer_label)
14281428
)]
14291429
pub fn note_type_err(
14301430
&self,
@@ -1434,7 +1434,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14341434
mut values: Option<ValuePairs<'tcx>>,
14351435
terr: &TypeError<'tcx>,
14361436
swap_secondary_and_primary: bool,
1437-
force_label: bool,
1437+
prefer_label: bool,
14381438
) {
14391439
let span = cause.span();
14401440

@@ -1612,7 +1612,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16121612
TypeError::ObjectUnsafeCoercion(_) => {}
16131613
_ => {
16141614
let mut label_or_note = |span: Span, msg: &str| {
1615-
if force_label || &[span] == diag.span.primary_spans() {
1615+
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
16161616
diag.span_label(span, msg);
16171617
} else {
16181618
diag.span_note(span, msg);

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
544544
let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
545545
let can_coerce = self.can_coerce(arg_ty, coerced_ty);
546546
if !can_coerce {
547-
return Compatibility::Incompatible(None);
547+
return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
548+
ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
549+
)));
548550
}
549551

550552
// Using probe here, since we don't want this subtyping to affect inference.

src/test/ui/argument-suggestions/issue-96638.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied
22
--> $DIR/issue-96638.rs:8:5
33
|
44
LL | f(&x, "");
5-
| ^ -- an argument of type `usize` is missing
5+
| ^ -- -- expected `usize`, found `&str`
6+
| |
7+
| an argument of type `usize` is missing
68
|
79
note: function defined here
810
--> $DIR/issue-96638.rs:1:4

src/test/ui/argument-suggestions/issue-97484.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied
22
--> $DIR/issue-97484.rs:12:5
33
|
44
LL | foo(&&A, B, C, D, E, F, G);
5-
| ^^^ - - - argument of type `F` unexpected
6-
| | |
5+
| ^^^ - - - - argument of type `F` unexpected
6+
| | | |
7+
| | | expected `&E`, found struct `E`
78
| | argument of type `C` unexpected
89
| argument of type `B` unexpected
910
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[derive(Copy, Clone)]
2+
struct Wrapper<T>(T);
3+
4+
fn foo(_: fn(i32), _: Wrapper<i32>) {}
5+
6+
fn f(_: u32) {}
7+
8+
fn main() {
9+
let w = Wrapper::<isize>(1isize);
10+
foo(f, w); //~ ERROR arguments to this function are incorrect
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0308]: arguments to this function are incorrect
2+
--> $DIR/two-mismatch-notes.rs:10:5
3+
|
4+
LL | foo(f, w);
5+
| ^^^
6+
|
7+
note: expected `i32`, found `u32`
8+
--> $DIR/two-mismatch-notes.rs:10:9
9+
|
10+
LL | foo(f, w);
11+
| ^
12+
= note: expected fn pointer `fn(i32)`
13+
found fn item `fn(u32) {f}`
14+
note: expected `i32`, found `isize`
15+
--> $DIR/two-mismatch-notes.rs:10:12
16+
|
17+
LL | foo(f, w);
18+
| ^
19+
= note: expected struct `Wrapper<i32>`
20+
found struct `Wrapper<isize>`
21+
note: function defined here
22+
--> $DIR/two-mismatch-notes.rs:4:4
23+
|
24+
LL | fn foo(_: fn(i32), _: Wrapper<i32>) {}
25+
| ^^^ ---------- ---------------
26+
27+
error: aborting due to previous error
28+
29+
For more information about this error, try `rustc --explain E0308`.

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied
22
--> $DIR/issue-18819.rs:16:5
33
|
44
LL | print_x(X);
5-
| ^^^^^^^---
6-
| ||
7-
| |expected reference, found struct `X`
8-
| an argument of type `&str` is missing
5+
| ^^^^^^^--- an argument of type `&str` is missing
96
|
7+
note: expected reference, found struct `X`
8+
--> $DIR/issue-18819.rs:16:13
9+
|
10+
LL | print_x(X);
11+
| ^
1012
= note: expected reference `&dyn Foo<Item = bool>`
1113
found struct `X`
1214
note: function defined here

src/test/ui/suggestions/args-instead-of-tuple-errors.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
22
--> $DIR/args-instead-of-tuple-errors.rs:6:34
33
|
44
LL | let _: Option<(i32, bool)> = Some(1, 2);
5-
| ^^^^ - - argument of type `{integer}` unexpected
6-
| |
7-
| expected tuple, found integer
5+
| ^^^^ - argument of type `{integer}` unexpected
86
|
7+
note: expected tuple, found integer
8+
--> $DIR/args-instead-of-tuple-errors.rs:6:39
9+
|
10+
LL | let _: Option<(i32, bool)> = Some(1, 2);
11+
| ^
912
= note: expected tuple `(i32, bool)`
1013
found type `{integer}`
1114
note: tuple variant defined here
@@ -22,10 +25,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
2225
--> $DIR/args-instead-of-tuple-errors.rs:8:5
2326
|
2427
LL | int_bool(1, 2);
25-
| ^^^^^^^^ - - argument of type `{integer}` unexpected
26-
| |
27-
| expected tuple, found integer
28+
| ^^^^^^^^ - argument of type `{integer}` unexpected
2829
|
30+
note: expected tuple, found integer
31+
--> $DIR/args-instead-of-tuple-errors.rs:8:14
32+
|
33+
LL | int_bool(1, 2);
34+
| ^
2935
= note: expected tuple `(i32, bool)`
3036
found type `{integer}`
3137
note: function defined here

src/test/ui/tuple/wrong_argument_ice-3.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
22
--> $DIR/wrong_argument_ice-3.rs:9:16
33
|
44
LL | groups.push(new_group, vec![process]);
5-
| ^^^^ --------- ------------- argument of type `Vec<&Process>` unexpected
6-
| |
7-
| expected tuple, found struct `Vec`
5+
| ^^^^ ------------- argument of type `Vec<&Process>` unexpected
86
|
7+
note: expected tuple, found struct `Vec`
8+
--> $DIR/wrong_argument_ice-3.rs:9:21
9+
|
10+
LL | groups.push(new_group, vec![process]);
11+
| ^^^^^^^^^
912
= note: expected tuple `(Vec<String>, Vec<Process>)`
1013
found struct `Vec<String>`
1114
note: associated function defined here

0 commit comments

Comments
 (0)