Skip to content

Commit 72cf40d

Browse files
authored
Rollup merge of rust-lang#133538 - dev-ardi:69232-better-diag, r=compiler-errors
Better diagnostic for fn items in variadic functions closes rust-lang#69232
2 parents 8ca5a90 + 1e4817c commit 72cf40d

File tree

9 files changed

+75
-12
lines changed

9 files changed

+75
-12
lines changed

compiler/rustc_hir_typeck/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ hir_typeck_field_multiply_specified_in_initializer =
7979
.label = used more than once
8080
.previous_use_label = first use of `{$ident}`
8181
82+
hir_typeck_fn_item_to_variadic_function = can't pass a function item to a variadic function
83+
.suggestion = use a function pointer instead
84+
.help = a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
85+
.note = for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
86+
8287
hir_typeck_fru_expr = this expression does not end in a comma...
8388
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
8489
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression

compiler/rustc_hir_typeck/src/errors.rs

+12
Original file line numberDiff line numberDiff line change
@@ -797,3 +797,15 @@ pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
797797
#[note(hir_typeck_teach_help)]
798798
pub(crate) teach: bool,
799799
}
800+
801+
#[derive(Diagnostic)]
802+
#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)]
803+
#[help]
804+
#[note]
805+
pub(crate) struct PassFnItemToVariadicFunction {
806+
#[primary_span]
807+
pub span: Span,
808+
#[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")]
809+
pub sugg_span: Span,
810+
pub replace: String,
811+
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
472472
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
473473
}
474474
ty::FnDef(..) => {
475-
let ptr_ty = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx));
476-
let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
477-
variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
475+
let fn_ptr = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx));
476+
let fn_ptr = self.resolve_vars_if_possible(fn_ptr).to_string();
477+
478+
let fn_item_spa = arg.span;
479+
tcx.sess.dcx().emit_err(errors::PassFnItemToVariadicFunction {
480+
span: fn_item_spa,
481+
sugg_span: fn_item_spa.shrink_to_hi(),
482+
replace: fn_ptr,
483+
});
478484
}
479485
_ => {}
480486
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// https://github.com/rust-lang/rust/issues/69232
2+
3+
extern "C" {
4+
fn foo(x: usize, ...);
5+
}
6+
7+
fn test() -> u8 {
8+
127
9+
}
10+
11+
fn main() {
12+
unsafe { foo(1, test) }; //~ ERROR can't pass a function item to a variadic function
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0617]: can't pass a function item to a variadic function
2+
--> $DIR/fn-item-diagnostic-issue-69232.rs:12:21
3+
|
4+
LL | unsafe { foo(1, test) };
5+
| ^^^^
6+
|
7+
= help: a function item is zero-sized and needs to be cast 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: use a function pointer instead
10+
|
11+
LL | unsafe { foo(1, test as fn() -> u8) };
12+
| +++++++++++++
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0617`.

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ 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 a function item to a variadic function
11+
//~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
12+
////~| HELP use a function pointer instead
1213
}
1314
}

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function
1+
error[E0617]: can't pass a function item to a 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 cast 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: use a function pointer instead
10+
|
11+
LL | foo(0, bar as fn(*const u8));
12+
| ++++++++++++++++
613

714
error: aborting due to 1 previous error
815

tests/ui/error-codes/E0617.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ fn main() {
2020
//~^ ERROR can't pass `u16` to variadic function
2121
//~| HELP cast the value to `c_uint`
2222
printf(::std::ptr::null(), printf);
23-
//~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function
24-
//~| HELP cast the value to `unsafe extern "C" fn(*const i8, ...)`
23+
//~^ ERROR can't pass a function item to a variadic function
24+
//~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
25+
//~| HELP use a function pointer instead
2526
}
2627
}

tests/ui/error-codes/E0617.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@ error[E0617]: can't pass `u16` to variadic function
2828
LL | printf(::std::ptr::null(), 0u16);
2929
| ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint`
3030

31-
error[E0617]: can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function
31+
error[E0617]: can't pass a function item to a variadic function
3232
--> $DIR/E0617.rs:22:36
3333
|
3434
LL | printf(::std::ptr::null(), printf);
3535
| ^^^^^^
3636
|
37-
help: cast the value to `unsafe extern "C" fn(*const i8, ...)`
37+
= help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
38+
= note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
39+
help: use a function pointer instead
3840
|
3941
LL | printf(::std::ptr::null(), printf as unsafe extern "C" fn(*const i8, ...));
40-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42+
| +++++++++++++++++++++++++++++++++++++++
4143

4244
error: aborting due to 6 previous errors
4345

0 commit comments

Comments
 (0)