Skip to content

Commit fe5d397

Browse files
committed
enhance diagnostic emitted for E0617 in missing cast for variadic arg
tidy fix compiler error fix compiler error round 2 tweak fndef pretty print fmt shorten the pretty-print output add a ui test specifically for linked issue 69232 Implement suggestion Co-authored-by: Esteban Kuber <[email protected]> fix compiler errors rebless tests
1 parent 8ace7ea commit fe5d397

File tree

115 files changed

+535
-364
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+535
-364
lines changed

compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{errors, structured_errors::StructuredDiagnostic};
2-
use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode};
2+
use rustc_errors::{codes::*, Applicability, DiagnosticBuilder, ErrCode};
33
use rustc_middle::ty::{Ty, TypeVisitableExt};
44
use rustc_session::Session;
55
use rustc_span::Span;
@@ -41,6 +41,20 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
4141
err.downgrade_to_delayed_bug();
4242
}
4343

44+
let msg = if self.ty.is_fn() {
45+
err.help("a function item is zero-sized and needs to be casted into a function pointer to be used in FFI")
46+
.note("for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html");
47+
"cast the value into a function pointer".to_string()
48+
} else {
49+
format!("cast the value to `{}`", self.cast_ty)
50+
};
51+
err.span_suggestion_verbose(
52+
self.span.shrink_to_hi(),
53+
msg,
54+
format!(" as {}", self.cast_ty),
55+
Applicability::MachineApplicable,
56+
);
57+
4458
err
4559
}
4660

compiler/rustc_middle/src/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
663663
p!(print_def_path(def_id, args));
664664
} else {
665665
let sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
666-
p!(print(sig), " {{", print_value_path(def_id, args), "}}");
666+
p!("{{fn item ", print_value_path(def_id, args), ": ", print(sig), "}}");
667667
}
668668
}
669669
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),

tests/ui/asm/x86_64/type-check-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn main() {
6464
let mut r = &mut 0;
6565
asm!("{}", in(reg) f);
6666
asm!("{}", inout(reg) f);
67-
//~^ ERROR cannot use value of type `fn() {main}` for inline assembly
67+
//~^ ERROR cannot use value of type `{fn item main: fn()}` for inline assembly
6868
asm!("{}", in(reg) r);
6969
asm!("{}", inout(reg) r);
7070
//~^ ERROR cannot use value of type `&mut i32` for inline assembly

tests/ui/asm/x86_64/type-check-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]);
6363
|
6464
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
6565

66-
error: cannot use value of type `fn() {main}` for inline assembly
66+
error: cannot use value of type `{fn item main: fn()}` for inline assembly
6767
--> $DIR/type-check-2.rs:66:31
6868
|
6969
LL | asm!("{}", inout(reg) f);

tests/ui/associated-types/substs-ppaux.normal.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
1010
| expected due to this
1111
|
1212
= note: expected unit type `()`
13-
found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
13+
found fn item `{fn item <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>: fn()}`
1414
help: use parentheses to call this associated function
1515
|
1616
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
@@ -28,7 +28,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
2828
| expected due to this
2929
|
3030
= note: expected unit type `()`
31-
found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
31+
found fn item `{fn item <i8 as Foo<'static, 'static>>::bar::<'static, char>: fn()}`
3232
help: use parentheses to call this associated function
3333
|
3434
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
@@ -46,7 +46,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
4646
| expected due to this
4747
|
4848
= note: expected unit type `()`
49-
found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
49+
found fn item `{fn item <i8 as Foo<'static, 'static, u8>>::baz: fn()}`
5050
help: use parentheses to call this associated function
5151
|
5252
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
@@ -64,7 +64,7 @@ LL | let x: () = foo::<'static>;
6464
| expected due to this
6565
|
6666
= note: expected unit type `()`
67-
found fn item `fn() {foo::<'static>}`
67+
found fn item `{fn item foo::<'static>: fn()}`
6868
help: use parentheses to call this function
6969
|
7070
LL | let x: () = foo::<'static>();

tests/ui/associated-types/substs-ppaux.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,35 @@ fn foo<'z>() where &'z (): Sized {
1616
let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
1717
//[verbose]~^ ERROR mismatched types
1818
//[verbose]~| expected unit type `()`
19-
//[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
19+
//[verbose]~| found fn item `{fn item <i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>: fn()}`
2020
//[normal]~^^^^ ERROR mismatched types
2121
//[normal]~| expected unit type `()`
22-
//[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
22+
//[normal]~| found fn item `{fn item <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>: fn()}`
2323

2424

2525
let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
2626
//[verbose]~^ ERROR mismatched types
2727
//[verbose]~| expected unit type `()`
28-
//[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
28+
//[verbose]~| found fn item `{fn item <i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>: fn()}`
2929
//[normal]~^^^^ ERROR mismatched types
3030
//[normal]~| expected unit type `()`
31-
//[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
31+
//[normal]~| found fn item `{fn item <i8 as Foo<'static, 'static>>::bar::<'static, char>: fn()}`
3232

3333
let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
3434
//[verbose]~^ ERROR mismatched types
3535
//[verbose]~| expected unit type `()`
36-
//[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
36+
//[verbose]~| found fn item `{fn item <i8 as Foo<ReStatic, ReStatic, u8>>::baz: fn()}`
3737
//[normal]~^^^^ ERROR mismatched types
3838
//[normal]~| expected unit type `()`
39-
//[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
39+
//[normal]~| found fn item `{fn item <i8 as Foo<'static, 'static, u8>>::baz: fn()}`
4040

4141
let x: () = foo::<'static>;
4242
//[verbose]~^ ERROR mismatched types
4343
//[verbose]~| expected unit type `()`
44-
//[verbose]~| found fn item `fn() {foo::<ReStatic>}`
44+
//[verbose]~| found fn item `{fn item foo::<ReStatic>: fn()}`
4545
//[normal]~^^^^ ERROR mismatched types
4646
//[normal]~| expected unit type `()`
47-
//[normal]~| found fn item `fn() {foo::<'static>}`
47+
//[normal]~| found fn item `{fn item foo::<'static>: fn()}`
4848

4949
<str as Foo<u8>>::bar;
5050
//[verbose]~^ ERROR the size for values of type

tests/ui/associated-types/substs-ppaux.verbose.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
1010
| expected due to this
1111
|
1212
= note: expected unit type `()`
13-
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
13+
found fn item `{fn item <i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>: fn()}`
1414
help: use parentheses to call this associated function
1515
|
1616
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
@@ -28,7 +28,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
2828
| expected due to this
2929
|
3030
= note: expected unit type `()`
31-
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
31+
found fn item `{fn item <i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>: fn()}`
3232
help: use parentheses to call this associated function
3333
|
3434
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
@@ -46,7 +46,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
4646
| expected due to this
4747
|
4848
= note: expected unit type `()`
49-
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
49+
found fn item `{fn item <i8 as Foo<ReStatic, ReStatic, u8>>::baz: fn()}`
5050
help: use parentheses to call this associated function
5151
|
5252
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
@@ -64,7 +64,7 @@ LL | let x: () = foo::<'static>;
6464
| expected due to this
6565
|
6666
= note: expected unit type `()`
67-
found fn item `fn() {foo::<ReStatic>}`
67+
found fn item `{fn item foo::<ReStatic>: fn()}`
6868
help: use parentheses to call this function
6969
|
7070
LL | let x: () = foo::<'static>();

tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrde
88
LL | | });
99
| |______^ implementation of `FnOnce` is not general enough
1010
|
11-
= note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
11+
= note: `{fn item std::future::ready::<&'0 ()>: fn(&'0 ()) -> std::future::Ready<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
1212
= note: ...but it actually implements `FnOnce<(&(),)>`
1313

1414
error: implementation of `FnOnce` is not general enough
@@ -21,7 +21,7 @@ LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrde
2121
LL | | });
2222
| |______^ implementation of `FnOnce` is not general enough
2323
|
24-
= note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
24+
= note: `{fn item std::future::ready::<&'0 ()>: fn(&'0 ()) -> std::future::Ready<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
2525
= note: ...but it actually implements `FnOnce<(&(),)>`
2626
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2727

tests/ui/binop/issue-77910-1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ fn main() {
77
// we shouldn't ice with the bound var here.
88
assert_eq!(foo, y);
99
//~^ ERROR binary operation `==` cannot be applied to type
10-
//~| ERROR `for<'a> fn(&'a i32) -> &'a i32 {foo}` doesn't implement `Debug`
10+
//~| ERROR `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}` doesn't implement `Debug`
1111
}

tests/ui/binop/issue-77910-1.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
error[E0369]: binary operation `==` cannot be applied to type `for<'a> fn(&'a i32) -> &'a i32 {foo}`
1+
error[E0369]: binary operation `==` cannot be applied to type `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}`
22
--> $DIR/issue-77910-1.rs:8:5
33
|
44
LL | assert_eq!(foo, y);
55
| ^^^^^^^^^^^^^^^^^^
66
| |
7-
| for<'a> fn(&'a i32) -> &'a i32 {foo}
7+
| {fn item foo: for<'a> fn(&'a i32) -> &'a i32}
88
| _
99
|
1010
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
1111

12-
error[E0277]: `for<'a> fn(&'a i32) -> &'a i32 {foo}` doesn't implement `Debug`
12+
error[E0277]: `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}` doesn't implement `Debug`
1313
--> $DIR/issue-77910-1.rs:8:5
1414
|
1515
LL | fn foo(s: &i32) -> &i32 {
1616
| --- consider calling this function
1717
...
1818
LL | assert_eq!(foo, y);
19-
| ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
19+
| ^^^^^^^^^^^^^^^^^^ `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
2020
|
21-
= help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
21+
= help: the trait `Debug` is not implemented for fn item `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}`
2222
= help: use parentheses to call this function: `foo(/* &i32 */)`
2323
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
2424

tests/ui/binop/issue-77910-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0369]: binary operation `==` cannot be applied to type `for<'a> fn(&'a i32) -> &'a i32 {foo}`
1+
error[E0369]: binary operation `==` cannot be applied to type `{fn item foo: for<'a> fn(&'a i32) -> &'a i32}`
22
--> $DIR/issue-77910-2.rs:7:12
33
|
44
LL | if foo == y {}
55
| --- ^^ - _
66
| |
7-
| for<'a> fn(&'a i32) -> &'a i32 {foo}
7+
| {fn item foo: for<'a> fn(&'a i32) -> &'a i32}
88
|
99
help: use parentheses to call this function
1010
|

tests/ui/c-variadic/issue-32201.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ fn bar(_: *const u8) {}
77
fn main() {
88
unsafe {
99
foo(0, bar);
10-
//~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function
11-
//~| HELP cast the value to `fn(*const u8)`
10+
//~^ ERROR can't pass `{fn item bar: fn(*const u8)}` to variadic function
11+
//~| HELP a function item is zero-sized and needs to be casted into a function pointer to be used in FFI
12+
//~| HELP cast the value into a function pointer
13+
//~| HELP cast the value to `fn(*const u8)
1214
}
1315
}

tests/ui/c-variadic/issue-32201.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function
1+
error[E0617]: can't pass `{fn item bar: fn(*const u8)}` to variadic function
22
--> $DIR/issue-32201.rs:9:16
33
|
44
LL | foo(0, bar);
5-
| ^^^ help: cast the value to `fn(*const u8)`: `bar as fn(*const u8)`
5+
| ^^^
6+
|
7+
= help: a function item is zero-sized and needs to be casted into a function pointer to be used in FFI
8+
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
9+
help: cast the value to `fn(*const u8)`
10+
|
11+
LL | foo(0, bar as fn(*const u8));
12+
| ~~~~~~~~~~~~~~~~~~~~
13+
help: cast the value into a function pointer
14+
|
15+
LL | foo(0, bar as fn(*const u8));
16+
| ++++++++++++++++
617

718
error: aborting due to 1 previous error
819

tests/ui/c-variadic/issue-69232.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extern "C" {
2+
fn foo(x: usize, ...);
3+
}
4+
5+
fn test() -> u8 {
6+
127
7+
}
8+
9+
fn main() {
10+
foo(1, test);
11+
//~^ ERROR can't pass `{fn item test: fn() -> u8}` to variadic function
12+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0617]: can't pass `{fn item test: fn() -> u8}` to variadic function
2+
--> $DIR/issue-69232.rs:10:12
3+
|
4+
LL | foo(1, test);
5+
| ^^^^
6+
|
7+
= help: a function item is zero-sized and needs to be casted into a function pointer to be used in FFI
8+
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
9+
help: cast the value to `fn() -> u8`
10+
|
11+
LL | foo(1, test as fn() -> u8);
12+
| ~~~~~~~~~~~~~~~~~~
13+
help: cast the value into a function pointer
14+
|
15+
LL | foo(1, test as fn() -> u8);
16+
| +++++++++++++
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0617`.

0 commit comments

Comments
 (0)