Skip to content

Allow "C-unwind" fn to have C variadics #126843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim
.label = {ast_passes_auto_super_lifetime}
.suggestion = remove the super traits or lifetime bounds

ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic
ast_passes_bad_c_variadic = only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

ast_passes_bare_fn_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
.suggestion = remove safe from this item
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ impl<'a> AstValidator<'a> {
(Some(FnCtxt::Foreign), _) => return,
(Some(FnCtxt::Free), Some(header)) => match header.ext {
Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _)
| Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _)
| Extern::Implicit(_)
if matches!(header.safety, Safety::Unsafe(_)) =>
{
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ symbols! {
Break,
C,
CStr,
C_dash_unwind: "C-unwind",
CallOnceFuture,
CallRefFuture,
Capture,
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/abi/variadic-ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 {
rust_valist_interesting_average(n, ap.as_va_list())
}

pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, mut ap: ...) -> f64 {
rust_valist_interesting_average(n, ap.as_va_list())
}

pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {
let mut ap2 = ap.clone();
assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30);
Expand Down Expand Up @@ -72,6 +76,10 @@ pub fn main() {
assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30);
}

unsafe {
assert_eq!(c_unwind_can_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30);
}

unsafe {
test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/c-variadic/issue-86053-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/mir/issue-83499-input-output-iteration-ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
fn main() {}

fn foo(_: Bar, ...) -> impl {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR cannot find type `Bar` in this scope
//~| ERROR at least one trait must be specified
2 changes: 1 addition & 1 deletion tests/ui/mir/issue-83499-input-output-iteration-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/issue-83499-input-output-iteration-ice.rs:7:16
|
LL | fn foo(_: Bar, ...) -> impl {}
Expand Down
42 changes: 21 additions & 21 deletions tests/ui/parser/variadic-ffi-semantic-restrictions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
fn main() {}

fn f1_1(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

fn f1_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

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

extern "C" fn f2_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

extern "C" fn f2_3(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function

extern "C" fn f3_1(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

extern "C" fn f3_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg

extern "C" fn f3_3(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function

const unsafe extern "C" fn f4_1(x: isize, ...) {}
Expand All @@ -35,12 +35,12 @@ const unsafe extern "C" fn f4_1(x: isize, ...) {}

const extern "C" fn f4_2(x: isize, ...) {}
//~^ ERROR functions cannot be both `const` and C-variadic
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time

const extern "C" fn f4_3(..., x: isize, ...) {}
//~^ ERROR functions cannot be both `const` and C-variadic
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function

extern "C" {
Expand All @@ -52,34 +52,34 @@ struct X;

impl X {
fn i_f1(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn i_f2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn i_f3(..., x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function
fn i_f4(..., x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function
const fn i_f5(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR functions cannot be both `const` and C-variadic
//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
}

trait T {
fn t_f1(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn t_f2(x: isize, ...);
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn t_f3(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn t_f4(...);
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
fn t_f5(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function
fn t_f6(..., x: isize);
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
//~| ERROR `...` must be the last argument of a C-variadic function
}
42 changes: 21 additions & 21 deletions tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:6:19
|
LL | fn f1_1(x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
|
LL | fn f1_2(...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
|
LL | extern "C" fn f2_1(x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
|
LL | extern "C" fn f2_2(...) {}
Expand All @@ -28,19 +28,19 @@ error: `...` must be the last argument of a C-variadic function
LL | extern "C" fn f2_3(..., x: isize) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $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
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:22:30
|
LL | extern "C" fn f3_1(x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:25:20
|
LL | extern "C" fn f3_2(...) {}
Expand All @@ -52,7 +52,7 @@ error: `...` must be the last argument of a C-variadic function
LL | extern "C" fn f3_3(..., x: isize) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:28:20
|
LL | extern "C" fn f3_3(..., x: isize) {}
Expand All @@ -70,7 +70,7 @@ error: functions cannot be both `const` and C-variadic
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
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:36:36
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
Expand All @@ -91,7 +91,7 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| | C-variadic because of this
| `const` because of this

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:41:26
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
Expand All @@ -103,13 +103,13 @@ error: `...` must be the last argument of a C-variadic function
LL | fn e_f2(..., x: isize);
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:23
|
LL | fn i_f1(x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:56:13
|
LL | fn i_f2(...) {}
Expand All @@ -121,7 +121,7 @@ error: `...` must be the last argument of a C-variadic function
LL | fn i_f3(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:58:13
|
LL | fn i_f3(..., x: isize, ...) {}
Expand All @@ -133,7 +133,7 @@ error: `...` must be the last argument of a C-variadic function
LL | fn i_f4(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
LL | fn i_f4(..., x: isize, ...) {}
Expand All @@ -147,31 +147,31 @@ LL | const fn i_f5(x: isize, ...) {}
| |
| `const` because of this

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $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
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $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
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:73:23
|
LL | fn t_f2(x: isize, ...);
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:75:13
|
LL | fn t_f3(...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:77:13
|
LL | fn t_f4(...);
Expand All @@ -183,7 +183,7 @@ error: `...` must be the last argument of a C-variadic function
LL | fn t_f5(..., x: isize) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
|
LL | fn t_f5(..., x: isize) {}
Expand All @@ -195,7 +195,7 @@ error: `...` must be the last argument of a C-variadic function
LL | fn t_f6(..., x: isize);
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
--> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
|
LL | fn t_f6(..., x: isize);
Expand Down
Loading