diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3c576316f6230..5423a1c213973 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2227,6 +2227,62 @@ pub struct FnSig { pub span: Span, } +impl FnSig { + /// Return a span encompassing the header, or where to insert it if empty. + pub fn header_span(&self) -> Span { + match self.header.ext { + Extern::Implicit(span) | Extern::Explicit(_, span) => { + return self.span.with_hi(span.hi()); + } + Extern::None => {} + } + + match self.header.safety { + Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()), + Safety::Default => {} + }; + + if let Some(coroutine_kind) = self.header.coroutine_kind { + return self.span.with_hi(coroutine_kind.span().hi()); + } + + if let Const::Yes(span) = self.header.constness { + return self.span.with_hi(span.hi()); + } + + self.span.shrink_to_lo() + } + + /// The span of the header's safety, or where to insert it if empty. + pub fn safety_span(&self) -> Span { + match self.header.safety { + Safety::Unsafe(span) | Safety::Safe(span) => span, + Safety::Default => { + // Insert after the `coroutine_kind` if available. + if let Some(coroutine_kind) = self.header.coroutine_kind { + return coroutine_kind.span().shrink_to_hi(); + } + + // Insert after the `const` keyword if available. + if let Const::Yes(const_span) = self.header.constness { + return const_span.shrink_to_hi(); + } + + // Insert right at the front of the signature. + self.span.shrink_to_lo() + } + } + } + + /// The span of the header's extern, or where to insert it if empty. + pub fn extern_span(&self) -> Span { + match self.header.ext { + Extern::Implicit(span) | Extern::Explicit(_, span) => span, + Extern::None => self.safety_span().shrink_to_hi(), + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Encodable, Decodable, HashStable_Generic)] pub enum FloatTy { @@ -3571,12 +3627,12 @@ impl Extern { /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`). #[derive(Clone, Copy, Encodable, Decodable, Debug)] pub struct FnHeader { - /// Whether this is `unsafe`, or has a default safety. - pub safety: Safety, - /// Whether this is `async`, `gen`, or nothing. - pub coroutine_kind: Option, /// The `const` keyword, if any pub constness: Const, + /// Whether this is `async`, `gen`, or nothing. + pub coroutine_kind: Option, + /// Whether this is `unsafe`, or has a default safety. + pub safety: Safety, /// The `extern` keyword and corresponding ABI string, if any. pub ext: Extern, } @@ -3590,38 +3646,6 @@ impl FnHeader { || matches!(constness, Const::Yes(_)) || !matches!(ext, Extern::None) } - - /// Return a span encompassing the header, or none if all options are default. - pub fn span(&self) -> Option { - fn append(a: &mut Option, b: Span) { - *a = match a { - None => Some(b), - Some(x) => Some(x.to(b)), - } - } - - let mut full_span = None; - - match self.safety { - Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span), - Safety::Default => {} - }; - - if let Some(coroutine_kind) = self.coroutine_kind { - append(&mut full_span, coroutine_kind.span()); - } - - if let Const::Yes(span) = self.constness { - append(&mut full_span, span); - } - - match self.ext { - Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span), - Extern::None => {} - } - - full_span - } } impl Default for FnHeader { diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index c5780c957c974..bd41d91bae83f 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -46,8 +46,6 @@ 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, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg - ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block .cannot_have = cannot have a body .invalid = the invalid body @@ -55,6 +53,18 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block 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_bad_extern = `...` is not supported for `extern "{$abi}"` functions + .label = `extern "{$abi}"` because of this + .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +ast_passes_c_variadic_must_be_unsafe = + functions with a C variable argument list must be unsafe + .suggestion = add the `unsafe` keyword to this definition + +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 @@ -73,6 +83,10 @@ ast_passes_const_without_body = ast_passes_constraint_on_negative_bound = associated type constraints not allowed on negative bounds +ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic + .const = `{$coroutine_kind}` because of this + .variadic = C-variadic because of this + ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses .label = not supported .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 38889d28151b3..a208e529c8cb2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -460,7 +460,7 @@ impl<'a> AstValidator<'a> { } if !spans.is_empty() { - let header_span = sig.header.span().unwrap_or(sig.span.shrink_to_lo()); + let header_span = sig.header_span(); let suggestion_span = header_span.shrink_to_hi().to(sig.decl.output.span()); let padding = if header_span.is_empty() { "" } else { " " }; @@ -633,46 +633,73 @@ impl<'a> AstValidator<'a> { /// - Non-const /// - Either foreign, or free and `unsafe extern "C"` semantically fn check_c_variadic_type(&self, fk: FnKind<'a>) { - let variadic_spans: Vec<_> = fk - .decl() - .inputs - .iter() - .filter(|arg| matches!(arg.ty.kind, TyKind::CVarArgs)) - .map(|arg| arg.span) - .collect(); + let variadic_params: Vec<_> = + fk.decl().inputs.iter().filter(|arg| matches!(arg.ty.kind, TyKind::CVarArgs)).collect(); - if variadic_spans.is_empty() { + // The parser already rejects `...` if it's not the final argument, but we still want to + // emit the errors below, so we only consider the final `...` here. + let Some(variadic_param) = variadic_params.last() else { return; + }; + + let FnKind::Fn(fn_ctxt, _, Fn { sig, .. }) = fk else { + // Unreachable because the parser already rejects `...` in closures. + unreachable!("C variable argument list cannot be used in closures") + }; + + // C-variadics are not yet implemented in const evaluation. + if let Const::Yes(const_span) = sig.header.constness { + self.dcx().emit_err(errors::ConstAndCVariadic { + span: const_span.to(variadic_param.span), + const_span, + variadic_span: variadic_param.span, + }); } - if let Some(header) = fk.header() { - if let Const::Yes(const_span) = header.constness { - let mut spans = variadic_spans.clone(); - spans.push(const_span); - self.dcx().emit_err(errors::ConstAndCVariadic { - spans, - const_span, - variadic_spans: variadic_spans.clone(), - }); - } + if let Some(coroutine_kind) = sig.header.coroutine_kind { + self.dcx().emit_err(errors::CoroutineAndCVariadic { + span: coroutine_kind.span().to(variadic_param.span), + coroutine_kind: coroutine_kind.as_str(), + coroutine_span: coroutine_kind.span(), + variadic_span: variadic_param.span, + }); } - match (fk.ctxt(), fk.header()) { - (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(_)) => - { - return; - } - _ => {} - }, - _ => {} - }; + match fn_ctxt { + FnCtxt::Free => { + match sig.header.ext { + Extern::Implicit(_) => { /* defaults to "C" */ } + Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { + if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) { + self.dcx().emit_err(errors::CVariadicBadExtern { + span: variadic_param.span, + abi: symbol_unescaped, + extern_span: sig.extern_span(), + }); + } + } + Extern::None => { + self.dcx() + .emit_err(errors::CVariadicNoExtern { span: variadic_param.span }); + } + }; - self.dcx().emit_err(errors::BadCVariadic { span: variadic_spans }); + if !matches!(sig.header.safety, Safety::Unsafe(_)) { + self.dcx().emit_err(errors::CVariadicMustBeUnsafe { + span: variadic_param.span, + unsafe_span: sig.safety_span(), + }); + } + } + FnCtxt::Assoc(_) => { + // For now, C variable argument lists are unsupported in associated functions. + self.dcx() + .emit_err(errors::CVariadicAssociatedFunction { span: variadic_param.span }); + } + FnCtxt::Foreign => { + // Whether the ABI supports C variable argument lists is checked later. + } + } } fn check_item_named(&self, ident: Ident, kind: &str) { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 3b2730d4ff9de..5aba810885eaa 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -309,10 +309,42 @@ pub(crate) struct ExternItemAscii { } #[derive(Diagnostic)] -#[diag(ast_passes_bad_c_variadic)] -pub(crate) struct BadCVariadic { +#[diag(ast_passes_c_variadic_associated_function)] +pub(crate) struct CVariadicAssociatedFunction { #[primary_span] - pub span: Vec, + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_c_variadic_bad_extern)] +pub(crate) struct CVariadicBadExtern { + #[primary_span] + pub span: Span, + pub abi: Symbol, + #[label] + pub extern_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_c_variadic_must_be_unsafe)] +pub(crate) struct CVariadicMustBeUnsafe { + #[primary_span] + pub span: Span, + + #[suggestion( + ast_passes_suggestion, + applicability = "maybe-incorrect", + code = "unsafe ", + style = "verbose" + )] + pub unsafe_span: Span, } #[derive(Diagnostic)] @@ -663,11 +695,23 @@ pub(crate) struct ConstAndCoroutine { #[diag(ast_passes_const_and_c_variadic)] pub(crate) struct ConstAndCVariadic { #[primary_span] - pub spans: Vec, + pub span: Span, #[label(ast_passes_const)] pub const_span: Span, #[label(ast_passes_variadic)] - pub variadic_spans: Vec, + pub variadic_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_coroutine_and_c_variadic)] +pub(crate) struct CoroutineAndCVariadic { + #[primary_span] + pub span: Span, + pub coroutine_kind: &'static str, + #[label(ast_passes_const)] + pub coroutine_span: Span, + #[label(ast_passes_variadic)] + pub variadic_span: Span, } #[derive(Diagnostic)] diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index 8eeb99a4cc19c..6e85655065edf 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -13,6 +13,7 @@ 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 only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~| ERROR `...` is not supported for non-extern functions + //~| ERROR: functions with a C variable argument list must be unsafe //~| 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 dc323f9a234d6..951af86e1cb72 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -46,11 +46,22 @@ error: `...` must be the last argument of a C-variadic function LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ -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 +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 ) { + | ^^^ + +error: functions with a C variable argument list must be unsafe + --> $DIR/issue-86053-1.rs:11:36 | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^ ^^^ + | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ++++++ error[E0412]: cannot find type `F` in this scope --> $DIR/issue-86053-1.rs:11:48 @@ -70,6 +81,6 @@ help: you might be missing a type parameter LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self , | +++ -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/c-variadic/issue-86053-2.rs b/tests/ui/c-variadic/issue-86053-2.rs index c545831f7171a..0914676a35f4f 100644 --- a/tests/ui/c-variadic/issue-86053-2.rs +++ b/tests/ui/c-variadic/issue-86053-2.rs @@ -5,7 +5,7 @@ trait H {} -unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} //~^ ERROR: in type `&'static &'a ()`, reference has a longer lifetime than the data it references [E0491] fn main() {} diff --git a/tests/ui/c-variadic/issue-86053-2.stderr b/tests/ui/c-variadic/issue-86053-2.stderr index 2c4be2522f614..823dadff6f895 100644 --- a/tests/ui/c-variadic/issue-86053-2.stderr +++ b/tests/ui/c-variadic/issue-86053-2.stderr @@ -1,14 +1,14 @@ error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references --> $DIR/issue-86053-2.rs:8:39 | -LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} | ^^^^^^^^^^^^^^^^^^ | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the lifetime `'a` as defined here --> $DIR/issue-86053-2.rs:8:32 | -LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} | ^^ error: aborting due to 1 previous error diff --git a/tests/ui/c-variadic/no-associated-function.rs b/tests/ui/c-variadic/no-associated-function.rs new file mode 100644 index 0000000000000..92ea40a4574fd --- /dev/null +++ b/tests/ui/c-variadic/no-associated-function.rs @@ -0,0 +1,42 @@ +// For now C-variadic arguments in associated functions are rejected. Especially when `self` +// parameters are used there may be weird interactions with other compiler features. We may +// relax this restriction in the future. +#![feature(c_variadic)] +#![crate_type = "lib"] +struct S; + +impl S { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + //~^ ERROR: associated functions cannot have a C variable argument list + unsafe { ap.arg() } + } + + unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { + //~^ ERROR: associated functions cannot have a C variable argument list + unsafe { ap.arg() } + } +} + +trait T { + unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { + //~^ ERROR: associated functions cannot have a C variable argument list + unsafe { ap.arg() } + } + + unsafe extern "C" fn trait_method(&self, mut ap: ...) -> i32 { + //~^ ERROR: associated functions cannot have a C variable argument list + unsafe { ap.arg() } + } +} + +impl T for S {} + +fn main() { + unsafe { + assert_eq!(S::associated_function(32), 32); + assert_eq!(S.method(32), 32); + + assert_eq!(S::trait_associated_function(32), 32); + assert_eq!(S.trait_method(32), 32); + } +} diff --git a/tests/ui/c-variadic/no-associated-function.stderr b/tests/ui/c-variadic/no-associated-function.stderr new file mode 100644 index 0000000000000..fbc8375e5d240 --- /dev/null +++ b/tests/ui/c-variadic/no-associated-function.stderr @@ -0,0 +1,26 @@ +error: associated functions cannot have a C variable argument list + --> $DIR/no-associated-function.rs:9:46 + | +LL | unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + | ^^^^^^^^^^^ + +error: associated functions cannot have a C variable argument list + --> $DIR/no-associated-function.rs:14:40 + | +LL | unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { + | ^^^^^^^^^^^ + +error: associated functions cannot have a C variable argument list + --> $DIR/no-associated-function.rs:21:52 + | +LL | unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { + | ^^^^^^^^^^^ + +error: associated functions cannot have a C variable argument list + --> $DIR/no-associated-function.rs:26:46 + | +LL | unsafe extern "C" fn trait_method(&self, mut ap: ...) -> i32 { + | ^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/c-variadic/no-closure.rs b/tests/ui/c-variadic/no-closure.rs new file mode 100644 index 0000000000000..934105474ec49 --- /dev/null +++ b/tests/ui/c-variadic/no-closure.rs @@ -0,0 +1,16 @@ +// A rust c-variadic function definition must use `_: ...`, not `...`. +#![feature(c_variadic)] +#![crate_type = "lib"] + +const F: extern "C" fn(...) = |_: ...| {}; +//~^ ERROR C-variadic type `...` may not be nested inside another type + +fn foo() { + let f = |...| {}; + //~^ ERROR: `..` patterns are not allowed here + //~| ERROR: unexpected `...` + + let f = |_: ...| {}; + //~^ ERROR C-variadic type `...` may not be nested inside another type + f(1i64) +} diff --git a/tests/ui/c-variadic/no-closure.stderr b/tests/ui/c-variadic/no-closure.stderr new file mode 100644 index 0000000000000..b167077e48425 --- /dev/null +++ b/tests/ui/c-variadic/no-closure.stderr @@ -0,0 +1,35 @@ +error[E0743]: C-variadic type `...` may not be nested inside another type + --> $DIR/no-closure.rs:5:35 + | +LL | const F: extern "C" fn(...) = |_: ...| {}; + | ^^^ + +error: unexpected `...` + --> $DIR/no-closure.rs:9:14 + | +LL | let f = |...| {}; + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - let f = |...| {}; +LL + let f = |..| {}; + | + +error[E0743]: C-variadic type `...` may not be nested inside another type + --> $DIR/no-closure.rs:13:17 + | +LL | let f = |_: ...| {}; + | ^^^ + +error: `..` patterns are not allowed here + --> $DIR/no-closure.rs:9:14 + | +LL | let f = |...| {}; + | ^^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0743`. diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs new file mode 100644 index 0000000000000..45a7e1f8972bf --- /dev/null +++ b/tests/ui/c-variadic/not-async.rs @@ -0,0 +1,7 @@ +//@ edition: 2021 +#![feature(c_variadic)] +#![crate_type = "lib"] + +async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} +//~^ ERROR functions cannot be both `async` and C-variadic +//~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr new file mode 100644 index 0000000000000..a384b548ab79d --- /dev/null +++ b/tests/ui/c-variadic/not-async.stderr @@ -0,0 +1,21 @@ +error: functions cannot be both `async` and C-variadic + --> $DIR/not-async.rs:5:1 + | +LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | | + | `async` because of this C-variadic because of this + +error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds + --> $DIR/not-async.rs:5:59 + | +LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} + | --------------------------------------------------------- ^^ + | | + | opaque type defined here + | + = note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/c-variadic/valid.rs b/tests/ui/c-variadic/valid.rs new file mode 100644 index 0000000000000..5a0b32026dc7a --- /dev/null +++ b/tests/ui/c-variadic/valid.rs @@ -0,0 +1,29 @@ +//@ run-pass +#![feature(c_variadic)] + +// In rust (and C23 and above) `...` can be the only argument. +unsafe extern "C" fn only_dot_dot_dot(mut ap: ...) -> i32 { + unsafe { ap.arg() } +} + +unsafe extern "C-unwind" fn abi_c_unwind(mut ap: ...) -> i32 { + unsafe { ap.arg() } +} + +#[allow(improper_ctypes_definitions)] +unsafe extern "C" fn mix_int_float(mut ap: ...) -> (i64, f64, *const i32, f64) { + (ap.arg(), ap.arg(), ap.arg(), ap.arg()) +} + +fn main() { + unsafe { + assert_eq!(only_dot_dot_dot(32), 32); + assert_eq!(abi_c_unwind(32), 32); + + // Passing more arguments than expected is allowed. + assert_eq!(only_dot_dot_dot(32, 1i64, core::ptr::null::(), 3.14f64), 32); + + let ptr = &14i32 as *const i32; + assert_eq!(mix_int_float(12i64, 13.0f64, ptr, 15.0f64), (12, 13.0, ptr, 15.0)); + } +} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 800dd580af290..eb6f4a323655b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -53,9 +53,7 @@ extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { x } -extern "cmse-nonsecure-entry" fn static_trait_object( - x: &'static dyn Trait, -) -> &'static dyn Trait { +extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait { //~^ ERROR return value of `"cmse-nonsecure-entry"` function too large to pass via registers [E0798] x } @@ -63,14 +61,12 @@ extern "cmse-nonsecure-entry" fn static_trait_object( #[repr(transparent)] struct WrapperTransparent<'a>(&'a dyn Trait); -extern "cmse-nonsecure-entry" fn wrapped_trait_object( - x: WrapperTransparent, -) -> WrapperTransparent { +extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent { //~^ ERROR return value of `"cmse-nonsecure-entry"` function too large to pass via registers [E0798] x } -extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions //~| ERROR requires `va_list` lang_item } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index f0190671b5a17..fdf29aabcaa9f 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,8 +1,10 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg - --> $DIR/generics.rs:73:53 +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions + --> $DIR/generics.rs:69:60 | -LL | extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ^^^^^^ +LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type --> $DIR/generics.rs:30:1 @@ -50,28 +52,28 @@ LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:58:6 + --> $DIR/generics.rs:56:80 | -LL | ) -> &'static dyn Trait { - | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers +LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait { + | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:68:6 + --> $DIR/generics.rs:64:81 | -LL | ) -> WrapperTransparent { - | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers +LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent { + | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error: requires `va_list` lang_item - --> $DIR/generics.rs:73:53 + --> $DIR/generics.rs:69:60 | -LL | extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ^^^^^^ +LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ^^^^^^ error: aborting due to 9 previous errors diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.rs b/tests/ui/inference/note-and-explain-ReVar-124973.rs index f1e2464563699..f55387e1dbb1a 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.rs +++ b/tests/ui/inference/note-and-explain-ReVar-124973.rs @@ -4,5 +4,6 @@ async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} //~^ ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds +//~| ERROR functions cannot be both `async` and C-variadic fn main() {} diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr index 574f6508e4c78..bbcc137684e9d 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -1,3 +1,11 @@ +error: functions cannot be both `async` and C-variadic + --> $DIR/note-and-explain-ReVar-124973.rs:5:1 + | +LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | | + | `async` because of this C-variadic because of this + error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds --> $DIR/note-and-explain-ReVar-124973.rs:5:73 | @@ -8,6 +16,6 @@ LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} | = note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0700`. 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 78e5c96180285..5c21b9438116c 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -5,6 +5,7 @@ fn main() {} fn foo(_: Bar, ...) -> impl {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR: `...` is not supported for non-extern functions +//~| ERROR functions with a C variable argument list must be unsafe //~| 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 80a8a94aea400..eed8471e3356e 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,9 +1,20 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: `...` is not supported for non-extern functions --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 | LL | fn foo(_: Bar, ...) -> impl {} | ^^^ +error: functions with a C variable argument list must be unsafe + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 + | +LL | fn foo(_: Bar, ...) -> impl {} + | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe fn foo(_: Bar, ...) -> impl {} + | ++++++ + error: at least one trait must be specified --> $DIR/issue-83499-input-output-iteration-ice.rs:7:24 | @@ -16,6 +27,6 @@ error[E0412]: cannot find type `Bar` in this scope LL | fn foo(_: Bar, ...) -> impl {} | ^^^ not found in this scope -error: aborting due to 3 previous errors +error: aborting due to 4 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 1cd6d13d56b6b..469d006135026 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -4,29 +4,31 @@ fn main() {} fn f1_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR `...` is not supported for non-extern functions +//~| ERROR functions with a C variable argument list must be unsafe fn f1_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR `...` is not supported for non-extern functions +//~| ERROR functions with a C variable argument list must be unsafe extern "C" fn f2_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe extern "C" fn f2_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe extern "C" fn f2_3(..., x: isize) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe //~| ERROR `...` must be the last argument of a C-variadic function extern "C" fn f3_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe extern "C" fn f3_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe extern "C" fn f3_3(..., x: isize) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR functions with a C variable argument list must be unsafe //~| ERROR `...` must be the last argument of a C-variadic function const unsafe extern "C" fn f4_1(x: isize, ...) {} @@ -35,12 +37,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, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~| ERROR functions with a C variable argument list must be unsafe //~| 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, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~| ERROR functions with a C variable argument list must be unsafe //~| ERROR `...` must be the last argument of a C-variadic function extern "C" { @@ -52,34 +54,34 @@ struct X; impl X { fn i_f1(x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn i_f2(...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn i_f3(..., x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list //~| ERROR `...` must be the last argument of a C-variadic function fn i_f4(..., x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list //~| 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, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn t_f2(x: isize, ...); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn t_f3(...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn t_f4(...); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list fn t_f5(..., x: isize) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list //~| ERROR `...` must be the last argument of a C-variadic function fn t_f6(..., x: isize); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR associated functions cannot have a C variable argument list //~| ERROR `...` must be the last argument of a C-variadic function } diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index b740cef020055..d8a73516f6c21 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,208 +1,274 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 | LL | fn f1_1(x: isize, ...) {} | ^^^ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 + | +LL | fn f1_1(x: isize, ...) {} + | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe fn f1_1(x: isize, ...) {} + | ++++++ + +error: `...` is not supported for non-extern functions + --> $DIR/variadic-ffi-semantic-restrictions.rs:10:9 + | +LL | fn f1_2(...) {} + | ^^^ + +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:10:9 | LL | fn f1_2(...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe fn f1_2(...) {} + | ++++++ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:14:30 | LL | extern "C" fn f2_1(x: isize, ...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f2_1(x: isize, ...) {} + | ++++++ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:17:20 | LL | extern "C" fn f2_2(...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f2_2(...) {} + | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f2_3(..., x: isize) {} + | ++++++ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 | LL | extern "C" fn f3_1(x: isize, ...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f3_1(x: isize, ...) {} + | ++++++ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 | LL | extern "C" fn f3_2(...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f3_2(...) {} + | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:30:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:30:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | unsafe extern "C" fn f3_3(..., x: isize) {} + | ++++++ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:32:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:34:1 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} - | ^^^^^ `const` because of this ^^^ C-variadic because of this + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | | + | `const` because of this C-variadic because of this error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:36:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:38:1 | LL | const extern "C" fn f4_2(x: isize, ...) {} - | ^^^^^ `const` because of this ^^^ C-variadic because of this + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | | + | `const` because of this C-variadic because of this -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:38:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | constunsafe extern "C" fn f4_2(x: isize, ...) {} + | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:43: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:41:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:43:1 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^^^ ^^^ ^^^ C-variadic because of this - | | | - | | C-variadic because of this - | `const` because of this + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | | + | `const` because of this C-variadic because of this -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 +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:43:41 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^ ^^^ + | ^^^ + | +help: add the `unsafe` keyword to this definition + | +LL | constunsafe extern "C" fn f4_3(..., x: isize, ...) {} + | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:49:13 | LL | fn e_f2(..., x: isize); | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:56:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:60:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:60:28 | LL | fn i_f3(..., x: isize, ...) {} - | ^^^ ^^^ + | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:63:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:63:28 | LL | fn i_f4(..., x: isize, ...) {} - | ^^^ ^^^ + | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:64:5 + --> $DIR/variadic-ffi-semantic-restrictions.rs:66:5 | LL | const fn i_f5(x: isize, ...) {} - | ^^^^^ ^^^ C-variadic because of this - | | + | -----^^^^^^^^^^^^^^^^^^^--- + | | | + | | C-variadic because of this | `const` because of this -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:66:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:75:23 | LL | fn t_f2(x: isize, ...); | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 | LL | fn t_f3(...) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f4(...); | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 | LL | fn t_f5(..., x: isize) {} | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 | LL | fn t_f6(..., x: isize); | ^^^ -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 +error: associated functions cannot have a C variable argument list + --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 | LL | fn t_f6(..., x: isize); | ^^^ error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:32:43 + --> $DIR/variadic-ffi-semantic-restrictions.rs:34:43 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^ - value is dropped here @@ -210,7 +276,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:36:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:38:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ - value is dropped here @@ -218,13 +284,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:64:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:66: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 36 previous errors +error: aborting due to 38 previous errors For more information about this error, try `rustc --explain E0493`.