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:
Jubilee 2024-05-26 15:28:26 -07:00 committed by GitHub
commit 866630d004
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 45 additions and 112 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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() {}

View File

@ -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

View File

@ -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

View File

@ -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`.