Rollup merge of #124048 - veera-sivarajan:bugfix-123773-c23-variadics, r=compiler-errors
Support C23's Variadics Without a Named Parameter Fixes #123773 This PR removes the static check that disallowed extern functions with ellipsis (varargs) as the only parameter since this is now valid in C23. This will not break any existing code as mentioned in the proposal document: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf. Also, adds a doc comment for `check_decl_cvariadic_pos()` and fixes the name of the function (`varadic` -> `variadic`).
This commit is contained in:
commit
866630d004
@ -92,9 +92,6 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block
|
||||
ast_passes_fn_param_c_var_args_not_last =
|
||||
`...` must be the last argument of a C-variadic function
|
||||
|
||||
ast_passes_fn_param_c_var_args_only =
|
||||
C-variadic function must be declared with at least one named argument
|
||||
|
||||
ast_passes_fn_param_doc_comment =
|
||||
documentation comments cannot be applied to function parameters
|
||||
.label = doc comments are not allowed here
|
||||
|
@ -364,7 +364,7 @@ fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'
|
||||
|
||||
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
self.check_decl_num_args(fn_decl);
|
||||
self.check_decl_cvaradic_pos(fn_decl);
|
||||
self.check_decl_cvariadic_pos(fn_decl);
|
||||
self.check_decl_attrs(fn_decl);
|
||||
self.check_decl_self_param(fn_decl, self_semantic);
|
||||
}
|
||||
@ -379,13 +379,11 @@ fn check_decl_num_args(&self, fn_decl: &FnDecl) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
|
||||
/// Emits an error if a function declaration has a variadic parameter in the
|
||||
/// beginning or middle of parameter list.
|
||||
/// Example: `fn foo(..., x: i32)` will emit an error.
|
||||
fn check_decl_cvariadic_pos(&self, fn_decl: &FnDecl) {
|
||||
match &*fn_decl.inputs {
|
||||
[Param { ty, span, .. }] => {
|
||||
if let TyKind::CVarArgs = ty.kind {
|
||||
self.dcx().emit_err(errors::FnParamCVarArgsOnly { span: *span });
|
||||
}
|
||||
}
|
||||
[ps @ .., _] => {
|
||||
for Param { ty, span, .. } in ps {
|
||||
if let TyKind::CVarArgs = ty.kind {
|
||||
|
@ -92,13 +92,6 @@ pub struct FnParamTooMany {
|
||||
pub max_num_args: usize,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_fn_param_c_var_args_only)]
|
||||
pub struct FnParamCVarArgsOnly {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_fn_param_c_var_args_not_last)]
|
||||
pub struct FnParamCVarArgsNotLast {
|
||||
|
@ -1,6 +1,9 @@
|
||||
//@ build-pass
|
||||
|
||||
// Supported since C23
|
||||
// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf
|
||||
extern "C" {
|
||||
fn foo(...);
|
||||
//~^ ERROR C-variadic function must be declared with at least one named argument
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +0,0 @@
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-no-fixed-args.rs:2:12
|
||||
|
|
||||
LL | fn foo(...);
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -8,14 +8,12 @@ fn f1_1(x: isize, ...) {}
|
||||
|
||||
fn f1_2(...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
|
||||
extern "C" fn f2_1(x: isize, ...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
|
||||
extern "C" fn f2_2(...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
|
||||
extern "C" fn f2_3(..., x: isize) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
@ -26,7 +24,6 @@ extern "C" fn f3_1(x: isize, ...) {}
|
||||
|
||||
extern "C" fn f3_2(...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
|
||||
extern "C" fn f3_3(..., x: isize) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
@ -47,8 +44,6 @@ extern "C" fn f3_3(..., x: isize) {}
|
||||
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||
|
||||
extern "C" {
|
||||
fn e_f1(...);
|
||||
//~^ ERROR C-variadic function must be declared with at least one named argument
|
||||
fn e_f2(..., x: isize);
|
||||
//~^ ERROR `...` must be the last argument of a C-variadic function
|
||||
}
|
||||
@ -60,7 +55,6 @@ fn i_f1(x: isize, ...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
fn i_f2(...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
fn i_f3(..., x: isize, ...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||
@ -80,10 +74,8 @@ fn t_f1(x: isize, ...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
fn t_f3(...) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
fn t_f4(...);
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR C-variadic function must be declared with at least one named argument
|
||||
fn t_f5(..., x: isize) {}
|
||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||
|
@ -4,12 +4,6 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
LL | fn f1_1(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
|
||||
|
|
||||
LL | fn f1_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
|
||||
|
|
||||
@ -17,91 +11,79 @@ LL | fn f1_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:13:30
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
|
||||
|
|
||||
LL | extern "C" fn f2_1(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
|
||||
|
|
||||
LL | extern "C" fn f2_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
|
||||
|
|
||||
LL | extern "C" fn f2_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
|
||||
|
|
||||
LL | extern "C" fn f2_3(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
|
||||
|
|
||||
LL | extern "C" fn f2_3(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:24:30
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:22:30
|
||||
|
|
||||
LL | extern "C" fn f3_1(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
|
||||
|
|
||||
LL | extern "C" fn f3_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:25:20
|
||||
|
|
||||
LL | extern "C" fn f3_2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:28:20
|
||||
|
|
||||
LL | extern "C" fn f3_3(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:28:20
|
||||
|
|
||||
LL | extern "C" fn f3_3(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: functions cannot be both `const` and C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:35:1
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:32:1
|
||||
|
|
||||
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
|
||||
| ^^^^^ `const` because of this ^^^ C-variadic because of this
|
||||
|
||||
error: functions cannot be both `const` and C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:39:1
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:36:1
|
||||
|
|
||||
LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||
| ^^^^^ `const` because of this ^^^ C-variadic because of this
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:36:36
|
||||
|
|
||||
LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:41:26
|
||||
|
|
||||
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: functions cannot be both `const` and C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:44:1
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:41:1
|
||||
|
|
||||
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||
| ^^^^^ ^^^ ^^^ C-variadic because of this
|
||||
@ -110,67 +92,55 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||
| `const` because of this
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:41:26
|
||||
|
|
||||
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||
| ^^^ ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
|
||||
|
|
||||
LL | fn e_f1(...);
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:52:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
|
||||
|
|
||||
LL | fn e_f2(..., x: isize);
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:23
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:23
|
||||
|
|
||||
LL | fn i_f1(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
||||
|
|
||||
LL | fn i_f2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:56:13
|
||||
|
|
||||
LL | fn i_f2(...) {}
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:58:13
|
||||
|
|
||||
LL | fn i_f3(..., x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:58:13
|
||||
|
|
||||
LL | fn i_f3(..., x: isize, ...) {}
|
||||
| ^^^ ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
||||
|
|
||||
LL | fn i_f4(..., x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
||||
|
|
||||
LL | fn i_f4(..., x: isize, ...) {}
|
||||
| ^^^ ^^^
|
||||
|
||||
error: functions cannot be both `const` and C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:70:5
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:64:5
|
||||
|
|
||||
LL | const fn i_f5(x: isize, ...) {}
|
||||
| ^^^^^ ^^^ C-variadic because of this
|
||||
@ -178,73 +148,61 @@ LL | const fn i_f5(x: isize, ...) {}
|
||||
| `const` because of this
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:64:29
|
||||
|
|
||||
LL | const fn i_f5(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:77:23
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:71:23
|
||||
|
|
||||
LL | fn t_f1(x: isize, ...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:79:23
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:73:23
|
||||
|
|
||||
LL | fn t_f2(x: isize, ...);
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:75:13
|
||||
|
|
||||
LL | fn t_f3(...) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
|
||||
|
|
||||
LL | fn t_f3(...) {}
|
||||
| ^^^
|
||||
|
||||
error: C-variadic function must be declared with at least one named argument
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
|
||||
|
|
||||
LL | fn t_f4(...);
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:77:13
|
||||
|
|
||||
LL | fn t_f4(...);
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
|
||||
|
|
||||
LL | fn t_f5(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
|
||||
|
|
||||
LL | fn t_f5(..., x: isize) {}
|
||||
| ^^^
|
||||
|
||||
error: `...` must be the last argument of a C-variadic function
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
|
||||
|
|
||||
LL | fn t_f6(..., x: isize);
|
||||
| ^^^
|
||||
|
||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
|
||||
|
|
||||
LL | fn t_f6(..., x: isize);
|
||||
| ^^^
|
||||
|
||||
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:35:43
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:32:43
|
||||
|
|
||||
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
|
||||
| ^^^ - value is dropped here
|
||||
@ -252,7 +210,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:36:36
|
||||
|
|
||||
LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||
| ^^^ - value is dropped here
|
||||
@ -260,13 +218,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
|
||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:64:29
|
||||
|
|
||||
LL | const fn i_f5(x: isize, ...) {}
|
||||
| ^^^ - value is dropped here
|
||||
| |
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error: aborting due to 43 previous errors
|
||||
error: aborting due to 36 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
|
Loading…
Reference in New Issue
Block a user