Skip to content

Commit 866630d

Browse files
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`).
2 parents bdbbb6c + f005b45 commit 866630d

7 files changed

+44
-111
lines changed

compiler/rustc_ast_passes/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,6 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block
9292
ast_passes_fn_param_c_var_args_not_last =
9393
`...` must be the last argument of a C-variadic function
9494
95-
ast_passes_fn_param_c_var_args_only =
96-
C-variadic function must be declared with at least one named argument
97-
9895
ast_passes_fn_param_doc_comment =
9996
documentation comments cannot be applied to function parameters
10097
.label = doc comments are not allowed here

compiler/rustc_ast_passes/src/ast_validation.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ impl<'a> AstValidator<'a> {
364364

365365
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
366366
self.check_decl_num_args(fn_decl);
367-
self.check_decl_cvaradic_pos(fn_decl);
367+
self.check_decl_cvariadic_pos(fn_decl);
368368
self.check_decl_attrs(fn_decl);
369369
self.check_decl_self_param(fn_decl, self_semantic);
370370
}
@@ -379,13 +379,11 @@ impl<'a> AstValidator<'a> {
379379
}
380380
}
381381

382-
fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
382+
/// Emits an error if a function declaration has a variadic parameter in the
383+
/// beginning or middle of parameter list.
384+
/// Example: `fn foo(..., x: i32)` will emit an error.
385+
fn check_decl_cvariadic_pos(&self, fn_decl: &FnDecl) {
383386
match &*fn_decl.inputs {
384-
[Param { ty, span, .. }] => {
385-
if let TyKind::CVarArgs = ty.kind {
386-
self.dcx().emit_err(errors::FnParamCVarArgsOnly { span: *span });
387-
}
388-
}
389387
[ps @ .., _] => {
390388
for Param { ty, span, .. } in ps {
391389
if let TyKind::CVarArgs = ty.kind {

compiler/rustc_ast_passes/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ pub struct FnParamTooMany {
9292
pub max_num_args: usize,
9393
}
9494

95-
#[derive(Diagnostic)]
96-
#[diag(ast_passes_fn_param_c_var_args_only)]
97-
pub struct FnParamCVarArgsOnly {
98-
#[primary_span]
99-
pub span: Span,
100-
}
101-
10295
#[derive(Diagnostic)]
10396
#[diag(ast_passes_fn_param_c_var_args_not_last)]
10497
pub struct FnParamCVarArgsNotLast {
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
//@ build-pass
2+
3+
// Supported since C23
4+
// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf
15
extern "C" {
26
fn foo(...);
3-
//~^ ERROR C-variadic function must be declared with at least one named argument
47
}
58

69
fn main() {}

tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr

-8
This file was deleted.

tests/ui/parser/variadic-ffi-semantic-restrictions.rs

-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ fn f1_1(x: isize, ...) {}
88

99
fn f1_2(...) {}
1010
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
11-
//~| ERROR C-variadic function must be declared with at least one named argument
1211

1312
extern "C" fn f2_1(x: isize, ...) {}
1413
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
1514

1615
extern "C" fn f2_2(...) {}
1716
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
18-
//~| ERROR C-variadic function must be declared with at least one named argument
1917

2018
extern "C" fn f2_3(..., x: isize) {}
2119
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
@@ -26,7 +24,6 @@ extern "C" fn f3_1(x: isize, ...) {}
2624

2725
extern "C" fn f3_2(...) {}
2826
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
29-
//~| ERROR C-variadic function must be declared with at least one named argument
3027

3128
extern "C" fn f3_3(..., x: isize) {}
3229
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
@@ -47,8 +44,6 @@ const extern "C" fn f4_3(..., x: isize, ...) {}
4744
//~| ERROR `...` must be the last argument of a C-variadic function
4845

4946
extern "C" {
50-
fn e_f1(...);
51-
//~^ ERROR C-variadic function must be declared with at least one named argument
5247
fn e_f2(..., x: isize);
5348
//~^ ERROR `...` must be the last argument of a C-variadic function
5449
}
@@ -60,7 +55,6 @@ impl X {
6055
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
6156
fn i_f2(...) {}
6257
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
63-
//~| ERROR C-variadic function must be declared with at least one named argument
6458
fn i_f3(..., x: isize, ...) {}
6559
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
6660
//~| ERROR `...` must be the last argument of a C-variadic function
@@ -80,10 +74,8 @@ trait T {
8074
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
8175
fn t_f3(...) {}
8276
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
83-
//~| ERROR C-variadic function must be declared with at least one named argument
8477
fn t_f4(...);
8578
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
86-
//~| ERROR C-variadic function must be declared with at least one named argument
8779
fn t_f5(..., x: isize) {}
8880
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
8981
//~| ERROR `...` must be the last argument of a C-variadic function

0 commit comments

Comments
 (0)