From 2b9fce8c8cf4373ee9da938ad5eeb97e85ca2739 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 6 Sep 2025 17:23:34 +0200 Subject: [PATCH] c-variadic: reject non-extern functions --- compiler/rustc_ast_passes/messages.ftl | 2 ++ .../rustc_ast_passes/src/ast_validation.rs | 3 ++- compiler/rustc_ast_passes/src/errors.rs | 7 +++++++ tests/ui/c-variadic/issue-86053-1.rs | 2 +- tests/ui/c-variadic/issue-86053-1.stderr | 2 +- .../issue-83499-input-output-iteration-ice.rs | 5 ++--- ...ue-83499-input-output-iteration-ice.stderr | 20 +++++++------------ .../variadic-ffi-semantic-restrictions.rs | 4 ++-- .../variadic-ffi-semantic-restrictions.stderr | 4 ++-- 9 files changed, 26 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 6eb4e4bc4527..958797a60894 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -68,6 +68,8 @@ ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list +ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions + ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic .const = `const` because of this .variadic = C-variadic because of this diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 79947b514b10..bbba235a6d16 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -714,7 +714,8 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::BadCVariadic { span: variadic_param.span }); } Extern::None => { - self.dcx().emit_err(errors::BadCVariadic { span: variadic_param.span }); + let err = errors::CVariadicNoExtern { span: variadic_param.span }; + self.dcx().emit_err(err); } }, FnCtxt::Assoc(_) => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index a085e09fe948..6b57e5ef3761 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -325,6 +325,13 @@ pub(crate) struct CVariadicAssociatedFunction { pub span: Span, } +#[derive(Diagnostic)] +#[diag(ast_passes_c_variadic_no_extern)] +pub(crate) struct CVariadicNoExtern { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_bad_c_variadic)] pub(crate) struct BadCVariadic { diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index 537d0263adf7..58dfee55cf88 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -13,6 +13,6 @@ fn ordering4 < 'a , 'b > ( a : , self , self , self , //~| ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function //~| ERROR `...` must be the last argument of a C-variadic function - //~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention + //~| ERROR `...` is not supported for non-extern functions //~| ERROR cannot find type `F` in this scope } diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index b58016b5a816..eb08370b4f80 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -46,7 +46,7 @@ error: `...` must be the last argument of a C-variadic function LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ -error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +error: `...` is not supported for non-extern functions --> $DIR/issue-86053-1.rs:11:36 | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs index 9277994d9b30..dc0d14bf9d6b 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -4,7 +4,6 @@ fn main() {} -fn foo(_: Bar, ...) -> impl {} -//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -//~| ERROR cannot find type `Bar` in this scope +unsafe extern "C" fn foo(_: Bar, ...) -> impl {} +//~^ ERROR cannot find type `Bar` in this scope //~| ERROR at least one trait must be specified diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr index 4a1aa49eb6e6..31a393e7367a 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,21 +1,15 @@ -error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 - | -LL | fn foo(_: Bar, ...) -> impl {} - | ^^^ - error: at least one trait must be specified - --> $DIR/issue-83499-input-output-iteration-ice.rs:7:24 + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:42 | -LL | fn foo(_: Bar, ...) -> impl {} - | ^^^^ +LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {} + | ^^^^ error[E0412]: cannot find type `Bar` in this scope - --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11 + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:29 | -LL | fn foo(_: Bar, ...) -> impl {} - | ^^^ not found in this scope +LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {} + | ^^^ not found in this scope -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index e76bdc21fa04..fe5421ab2c0a 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -4,10 +4,10 @@ fn main() {} fn f1_1(x: isize, ...) {} -//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +//~^ ERROR `...` is not supported for non-extern functions fn f1_2(...) {} -//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +//~^ ERROR `...` is not supported for non-extern functions extern "C" fn f2_1(x: isize, ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 1317f63a88ad..0abe15264053 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,10 +1,10 @@ -error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 | LL | fn f1_1(x: isize, ...) {} | ^^^ -error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | LL | fn f1_2(...) {}