Rollup merge of #133538 - dev-ardi:69232-better-diag, r=compiler-errors
Better diagnostic for fn items in variadic functions closes #69232
This commit is contained in:
commit
72cf40d9ed
9 changed files with 75 additions and 12 deletions
|
@ -79,6 +79,11 @@ hir_typeck_field_multiply_specified_in_initializer =
|
|||
.label = used more than once
|
||||
.previous_use_label = first use of `{$ident}`
|
||||
|
||||
hir_typeck_fn_item_to_variadic_function = can't pass a function item to a variadic function
|
||||
.suggestion = use a function pointer instead
|
||||
.help = a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
.note = for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
|
||||
|
||||
hir_typeck_fru_expr = this expression does not end in a comma...
|
||||
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
|
||||
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
|
||||
|
|
|
@ -797,3 +797,15 @@ pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
|
|||
#[note(hir_typeck_teach_help)]
|
||||
pub(crate) teach: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)]
|
||||
#[help]
|
||||
#[note]
|
||||
pub(crate) struct PassFnItemToVariadicFunction {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")]
|
||||
pub sugg_span: Span,
|
||||
pub replace: String,
|
||||
}
|
||||
|
|
|
@ -472,9 +472,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
|
||||
}
|
||||
ty::FnDef(..) => {
|
||||
let ptr_ty = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx));
|
||||
let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
|
||||
variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
|
||||
let fn_ptr = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx));
|
||||
let fn_ptr = self.resolve_vars_if_possible(fn_ptr).to_string();
|
||||
|
||||
let fn_item_spa = arg.span;
|
||||
tcx.sess.dcx().emit_err(errors::PassFnItemToVariadicFunction {
|
||||
span: fn_item_spa,
|
||||
sugg_span: fn_item_spa.shrink_to_hi(),
|
||||
replace: fn_ptr,
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
13
tests/ui/c-variadic/fn-item-diagnostic-issue-69232.rs
Normal file
13
tests/ui/c-variadic/fn-item-diagnostic-issue-69232.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// https://github.com/rust-lang/rust/issues/69232
|
||||
|
||||
extern "C" {
|
||||
fn foo(x: usize, ...);
|
||||
}
|
||||
|
||||
fn test() -> u8 {
|
||||
127
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { foo(1, test) }; //~ ERROR can't pass a function item to a variadic function
|
||||
}
|
16
tests/ui/c-variadic/fn-item-diagnostic-issue-69232.stderr
Normal file
16
tests/ui/c-variadic/fn-item-diagnostic-issue-69232.stderr
Normal file
|
@ -0,0 +1,16 @@
|
|||
error[E0617]: can't pass a function item to a variadic function
|
||||
--> $DIR/fn-item-diagnostic-issue-69232.rs:12:21
|
||||
|
|
||||
LL | unsafe { foo(1, test) };
|
||||
| ^^^^
|
||||
|
|
||||
= help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
|
||||
help: use a function pointer instead
|
||||
|
|
||||
LL | unsafe { foo(1, test as fn() -> u8) };
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0617`.
|
|
@ -7,7 +7,8 @@ fn bar(_: *const u8) {}
|
|||
fn main() {
|
||||
unsafe {
|
||||
foo(0, bar);
|
||||
//~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function
|
||||
//~| HELP cast the value to `fn(*const u8)`
|
||||
//~^ ERROR can't pass a function item to a variadic function
|
||||
//~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
////~| HELP use a function pointer instead
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function
|
||||
error[E0617]: can't pass a function item to a variadic function
|
||||
--> $DIR/issue-32201.rs:9:16
|
||||
|
|
||||
LL | foo(0, bar);
|
||||
| ^^^ help: cast the value to `fn(*const u8)`: `bar as fn(*const u8)`
|
||||
| ^^^
|
||||
|
|
||||
= help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
|
||||
help: use a function pointer instead
|
||||
|
|
||||
LL | foo(0, bar as fn(*const u8));
|
||||
| ++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ fn main() {
|
|||
//~^ ERROR can't pass `u16` to variadic function
|
||||
//~| HELP cast the value to `c_uint`
|
||||
printf(::std::ptr::null(), printf);
|
||||
//~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function
|
||||
//~| HELP cast the value to `unsafe extern "C" fn(*const i8, ...)`
|
||||
//~^ ERROR can't pass a function item to a variadic function
|
||||
//~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
//~| HELP use a function pointer instead
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,16 +28,18 @@ error[E0617]: can't pass `u16` to variadic function
|
|||
LL | printf(::std::ptr::null(), 0u16);
|
||||
| ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint`
|
||||
|
||||
error[E0617]: can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function
|
||||
error[E0617]: can't pass a function item to a variadic function
|
||||
--> $DIR/E0617.rs:22:36
|
||||
|
|
||||
LL | printf(::std::ptr::null(), printf);
|
||||
| ^^^^^^
|
||||
|
|
||||
help: cast the value to `unsafe extern "C" fn(*const i8, ...)`
|
||||
= help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
|
||||
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
|
||||
help: use a function pointer instead
|
||||
|
|
||||
LL | printf(::std::ptr::null(), printf as unsafe extern "C" fn(*const i8, ...));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| +++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue