Rollup merge of #143619 - beetrees:varargs-named, r=jdonszelmann

`c_variadic`: Add future-incompatibility warning for `...` arguments without a pattern outside of `extern` blocks

This PR makes `...` arguments without a pattern in non-foreign functions (such as the argument in `unsafe extern "C" fn f(...) {}`) a future-compatibility warning; making this error would be consistent with how `unsafe extern "C" fn f(u32) {}` is handled. Allowing `...` arguments without a pattern in non-foreign functions is a source of confusion for programmers coming from C, where the `...` parameter is never named and instead calling `va_start` is required; disallowing `...` arguments without a pattern also improves the overall consistency of the Rust language by matching the treatment of other arguments without patterns. `...` arguments without a pattern in `extern` blocks (such as `unsafe extern "C" { fn f(...); }`) continue to compile without warnings after this PR, as they are already stable and heavily used (and don't cause the mentioned confusion as they are just being used in function declarations).

As all the syntax gating for `c_variadic` has been done post-expansion, this is technically a breaking change. In particular, code like this has compiled on stable since Rust 1.35.0:
```rust
#[cfg(any())] // Equivalent to the more recent #[cfg(false)]
unsafe extern "C" fn bar(_: u32, ...) {}
```
Since this is more or less a stability hole and a Crater run shows only the `binrw` crate is using this, I think it would be ok to break this. This will require a lang FCP.

The idea of rejecting `...` pre-expansion was first raised here https://github.com/rust-lang/rust/pull/143546#issuecomment-3043142052.

Tracking issue: rust-lang/rust#44930
cc `@folkertdev` `@workingjubilee`
r? `@joshtriplett`
This commit is contained in:
Stuart Cook 2025-11-11 21:09:33 +11:00 committed by GitHub
commit 3538bc18fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 496 additions and 192 deletions

View file

@ -144,6 +144,7 @@ declare_lint_pass! {
UNUSED_UNSAFE,
UNUSED_VARIABLES,
USELESS_DEPRECATED,
VARARGS_WITHOUT_PATTERN,
WARNINGS,
// tidy-alphabetical-end
]
@ -5295,3 +5296,50 @@ declare_lint! {
report_in_deps: false,
};
}
declare_lint! {
/// The `varargs_without_pattern` lint detects when `...` is used as an argument to a
/// non-foreign function without any pattern being specified.
///
/// ### Example
///
/// ```rust
/// // Using `...` in non-foreign function definitions is unstable, however stability is
/// // currently only checked after attributes are expanded, so using `#[cfg(false)]` here will
/// // allow this to compile on stable Rust.
/// #[cfg(false)]
/// fn foo(...) {
///
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Patterns are currently required for all non-`...` arguments in function definitions (with
/// some exceptions in the 2015 edition). Requiring `...` arguments to have patterns in
/// non-foreign function definitions makes the language more consistent, and removes a source of
/// confusion for the unstable C variadic feature. `...` arguments without a pattern are already
/// stable and widely used in foreign function definitions; this lint only affects non-foreign
/// function definitions.
///
/// Using `...` (C varargs) in a non-foreign function definition is currently unstable. However,
/// stability checking for the `...` syntax in non-foreign function definitions is currently
/// implemented after attributes have been expanded, meaning that if the attribute removes the
/// use of the unstable syntax (e.g. `#[cfg(false)]`, or a procedural macro), the code will
/// compile on stable Rust; this is the only situation where this lint affects code that
/// compiles on stable Rust.
///
/// This is a [future-incompatible] lint to transition this to a hard error in the future.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub VARARGS_WITHOUT_PATTERN,
Warn,
"detects usage of `...` arguments without a pattern in non-foreign items",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseError,
reference: "issue #145544 <https://github.com/rust-lang/rust/issues/145544>",
report_in_deps: false,
};
}

View file

@ -1004,6 +1004,9 @@ parse_use_if_else = use an `if-else` expression instead
parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable
parse_varargs_without_pattern = missing pattern for `...` argument
.suggestion = name the argument, or use `_` to continue ignoring it
parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by an item
.label = the visibility
.help = you likely meant to define an item, e.g., `{$vis} fn foo() {"{}"}`

View file

@ -3645,3 +3645,10 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
}
}
}
#[derive(LintDiagnostic)]
#[diag(parse_varargs_without_pattern)]
pub(crate) struct VarargsWithoutPattern {
#[suggestion(code = "_: ...", applicability = "machine-applicable")]
pub span: Span,
}

View file

@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
AttrWrapper::empty(),
true,
false,
FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true },
FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true },
ForceCollect::No,
) {
Ok(Some(item)) => {

View file

@ -45,6 +45,7 @@ use crate::errors::{
};
use crate::parser::FnContext;
use crate::parser::attr::InnerAttrPolicy;
use crate::parser::item::IsDotDotDot;
use crate::{exp, fluent_generated as fluent};
/// Creates a placeholder argument.
@ -2284,7 +2285,7 @@ impl<'a> Parser<'a> {
let maybe_emit_anon_params_note = |this: &mut Self, err: &mut Diag<'_>| {
let ed = this.token.span.with_neighbor(this.prev_token.span).edition();
if matches!(fn_parse_mode.context, crate::parser::item::FnContext::Trait)
&& (fn_parse_mode.req_name)(ed)
&& (fn_parse_mode.req_name)(ed, IsDotDotDot::No)
{
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
}

View file

@ -12,6 +12,7 @@ use rustc_ast::{
use rustc_ast_pretty::pprust;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN;
use rustc_span::edit_distance::edit_distance;
use rustc_span::edition::Edition;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, source_map, sym};
@ -119,7 +120,7 @@ impl<'a> Parser<'a> {
impl<'a> Parser<'a> {
pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Box<Item>>> {
let fn_parse_mode =
FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true };
FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new))
}
@ -976,7 +977,7 @@ impl<'a> Parser<'a> {
force_collect: ForceCollect,
) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
let fn_parse_mode =
FnParseMode { req_name: |_| true, context: FnContext::Impl, req_body: true };
FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true };
self.parse_assoc_item(fn_parse_mode, force_collect)
}
@ -985,7 +986,7 @@ impl<'a> Parser<'a> {
force_collect: ForceCollect,
) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
let fn_parse_mode = FnParseMode {
req_name: |edition| edition >= Edition::Edition2018,
req_name: |edition, _| edition >= Edition::Edition2018,
context: FnContext::Trait,
req_body: false,
};
@ -1245,8 +1246,11 @@ impl<'a> Parser<'a> {
&mut self,
force_collect: ForceCollect,
) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
let fn_parse_mode =
FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: false };
let fn_parse_mode = FnParseMode {
req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
context: FnContext::Free,
req_body: false,
};
Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
|Item { attrs, id, span, vis, kind, tokens }| {
let kind = match ForeignItemKind::try_from(kind) {
@ -2133,7 +2137,7 @@ impl<'a> Parser<'a> {
Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
// We use `parse_fn` to get a span for the function
let fn_parse_mode =
FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true };
FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
match self.parse_fn(
&mut AttrVec::new(),
fn_parse_mode,
@ -2366,8 +2370,16 @@ impl<'a> Parser<'a> {
/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
///
/// This function pointer accepts an edition, because in edition 2015, trait declarations
/// were allowed to omit parameter names. In 2018, they became required.
type ReqName = fn(Edition) -> bool;
/// were allowed to omit parameter names. In 2018, they became required. It also accepts an
/// `IsDotDotDot` parameter, as `extern` function declarations and function pointer types are
/// allowed to omit the name of the `...` but regular function items are not.
type ReqName = fn(Edition, IsDotDotDot) -> bool;
#[derive(Copy, Clone, PartialEq)]
pub(crate) enum IsDotDotDot {
Yes,
No,
}
/// Parsing configuration for functions.
///
@ -2400,6 +2412,9 @@ pub(crate) struct FnParseMode {
/// to true.
/// * The span is from Edition 2015. In particular, you can get a
/// 2015 span inside a 2021 crate using macros.
///
/// Or if `IsDotDotDot::Yes`, this function will also return `false` if the item being parsed
/// is inside an `extern` block.
pub(super) req_name: ReqName,
/// The context in which this function is parsed, used for diagnostics.
/// This indicates the fn is a free function or method and so on.
@ -3049,11 +3064,25 @@ impl<'a> Parser<'a> {
return Ok((res?, Trailing::No, UsePreAttrPos::No));
}
let is_name_required = match this.token.kind {
token::DotDotDot => false,
_ => (fn_parse_mode.req_name)(
this.token.span.with_neighbor(this.prev_token.span).edition(),
),
let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
IsDotDotDot::Yes
} else {
IsDotDotDot::No
};
let is_name_required = (fn_parse_mode.req_name)(
this.token.span.with_neighbor(this.prev_token.span).edition(),
is_dot_dot_dot,
);
let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
this.psess.buffer_lint(
VARARGS_WITHOUT_PATTERN,
this.token.span,
ast::CRATE_NODE_ID,
errors::VarargsWithoutPattern { span: this.token.span },
);
false
} else {
is_name_required
};
let (pat, ty) = if is_name_required || this.is_named_param() {
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);

View file

@ -404,7 +404,7 @@ impl<'a> Parser<'a> {
// Inside parenthesized type arguments, we want types only, not names.
let mode = FnParseMode {
context: FnContext::Free,
req_name: |_| false,
req_name: |_, _| false,
req_body: false,
};
let param = p.parse_param_general(&mode, false, false);

View file

@ -154,7 +154,7 @@ impl<'a> Parser<'a> {
attrs.clone(), // FIXME: unwanted clone of attrs
false,
true,
FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true },
FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true },
force_collect,
)? {
self.mk_stmt(lo.to(item.span), StmtKind::Item(Box::new(item)))

View file

@ -824,7 +824,7 @@ impl<'a> Parser<'a> {
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
}
let mode = crate::parser::item::FnParseMode {
req_name: |_| false,
req_name: |_, _| false,
context: FnContext::Free,
req_body: false,
};
@ -1380,7 +1380,8 @@ impl<'a> Parser<'a> {
self.bump();
let args_lo = self.token.span;
let snapshot = self.create_snapshot_for_diagnostic();
let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false };
let mode =
FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
match self.parse_fn_decl(&mode, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
Ok(decl) => {
self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
@ -1471,7 +1472,8 @@ impl<'a> Parser<'a> {
// Parse `(T, U) -> R`.
let inputs_lo = self.token.span;
let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false };
let mode =
FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
let inputs: ThinVec<_> =
self.parse_fn_params(&mode)?.into_iter().map(|input| input.ty).collect();
let inputs_span = inputs_lo.to(self.prev_token.span);

View file

@ -16,12 +16,12 @@ unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { va2.arg::<usize>() }
fn main() {
fn g1(_: extern "C" fn(_: u8, va: ...)) { }
fn g2(_: extern "C" fn(_: u8, ...)) { }
fn g2(_: extern "C" fn(_: u8, _: ...)) { }
fn g3(_: extern "C" fn(u8, va: ...)) { }
fn g4(_: extern "C" fn(u8, ...)) { }
fn g4(_: extern "C" fn(u8, _: ...)) { }
fn g5(_: extern "C" fn(va: ...)) { }
fn g6(_: extern "C" fn(...)) { }
fn g6(_: extern "C" fn(_: ...)) { }
{
let _ =

View file

@ -14,16 +14,16 @@ pub unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize {
fn main() {
fn g1(_: extern "C" fn(_: u8, va: ...)) {}
fn g2(_: extern "C" fn(_: u8, ...)) {}
fn g2(_: extern "C" fn(_: u8, _: ...)) {}
fn g3(_: extern "C" fn(u8, va: ...)) {}
fn g4(_: extern "C" fn(u8, ...)) {}
fn g4(_: extern "C" fn(u8, _: ...)) {}
fn g5(_: extern "C" fn(va: ...)) {}
fn g6(_: extern "C" fn(...)) {}
fn g6(_: extern "C" fn(_: ...)) {}
_ = { unsafe extern "C" fn f1(_: u8, va: ...) {} };
_ = { unsafe extern "C" fn f2(_: u8, ...) {} };
_ = { unsafe extern "C" fn f2(_: u8, _: ...) {} };
_ = { unsafe extern "C" fn f5(va: ...) {} };
_ = { unsafe extern "C" fn f6(...) {} };
_ = { unsafe extern "C" fn f6(_: ...) {} };
}

View file

@ -8,7 +8,7 @@ fn ordering4 < 'a , 'b > ( a : , self , self , self ,
//~| ERROR unexpected `self` parameter in function
//~| ERROR unexpected `self` parameter in function
//~| ERROR unexpected `self` parameter in function
self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
//~^ ERROR unexpected `self` parameter in function
//~| ERROR unexpected `self` parameter in function
//~| ERROR unexpected `self` parameter in function

View file

@ -25,48 +25,48 @@ LL | fn ordering4 < 'a , 'b > ( a : , self , self , self ,
error: unexpected `self` parameter in function
--> $DIR/issue-86053-1.rs:11:5
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^ must be the first parameter of an associated function
error: unexpected `self` parameter in function
--> $DIR/issue-86053-1.rs:11:20
--> $DIR/issue-86053-1.rs:11:23
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^ must be the first parameter of an associated function
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^ must be the first parameter of an associated function
error: unexpected `self` parameter in function
--> $DIR/issue-86053-1.rs:11:29
--> $DIR/issue-86053-1.rs:11:32
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^ must be the first parameter of an associated function
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^ must be the first parameter of an associated function
error: `...` must be the last argument of a C-variadic function
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^^^
error: `...` is not supported for non-extern functions
--> $DIR/issue-86053-1.rs:11:36
--> $DIR/issue-86053-1.rs:11:39
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error[E0412]: cannot find type `F` in this scope
--> $DIR/issue-86053-1.rs:11:48
--> $DIR/issue-86053-1.rs:11:54
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^
LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^
|
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
= note: similarly named trait `Fn` defined here
help: a trait with a similar name exists
|
LL | self , ... , self , self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) {
| +
LL | self , _: ... , self , self , _: ... ) where Fn : FnOnce ( & 'a & 'b usize ) {
| +
help: you might be missing a type parameter
|
LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self ,

View file

@ -5,7 +5,7 @@
trait H<T> {}
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() {}

View file

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

View file

@ -2,14 +2,14 @@
#![feature(c_variadic)]
#![crate_type = "lib"]
async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {}
async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {}
//~^ ERROR functions cannot be both `async` and C-variadic
//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
struct S;
impl S {
async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {}
async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {}
//~^ ERROR functions cannot be both `async` and C-variadic
//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
}

View file

@ -1,30 +1,30 @@
error: functions cannot be both `async` and C-variadic
--> $DIR/not-async.rs:5:1
|
LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {}
| ^^^^^ `async` because of this ^^^ C-variadic because of this
LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {}
| ^^^^^ `async` because of this ^^^^^^ C-variadic because of this
error: functions cannot be both `async` and C-variadic
--> $DIR/not-async.rs:12:5
|
LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {}
| ^^^^^ `async` because of this ^^^ C-variadic because of this
LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {}
| ^^^^^ `async` because of this ^^^^^^ C-variadic because of this
error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
--> $DIR/not-async.rs:5:62
--> $DIR/not-async.rs:5:65
|
LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {}
| ------------------------------------------------------------ ^^
LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {}
| --------------------------------------------------------------- ^^
| |
| opaque type defined here
|
= note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_`
error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
--> $DIR/not-async.rs:12:70
--> $DIR/not-async.rs:12:73
|
LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {}
| ---------------------------------------------------------------- ^^
LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {}
| ------------------------------------------------------------------- ^^
| |
| opaque type defined here
|

View file

@ -0,0 +1,36 @@
//@ check-fail
//@ run-rustfix
//@ revisions: e2015 e2018
//@[e2015] edition: 2015
//@[e2018] edition: 2018
#![crate_type = "lib"]
#![deny(varargs_without_pattern)]
#[cfg(false)]
mod module {
unsafe extern "C" fn f(_: ...) {
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
unsafe extern "C" fn f(_: ...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
impl A {
unsafe extern "C" fn f(_: ...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
trait A {
unsafe extern "C" fn f(...) {}
//[e2018]~^ ERROR missing pattern for `...` argument
//[e2018]~| WARN this was previously accepted by the compiler
}
unsafe extern "C" {
fn f(...); // no error
}
type A = unsafe extern "C" fn(...); // no error
}

View file

@ -0,0 +1,46 @@
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:11:28
|
LL | unsafe extern "C" fn f(...) {
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
note: the lint level is defined here
--> $DIR/parse-errors.rs:7:9
|
LL | #![deny(varargs_without_pattern)]
| ^^^^^^^^^^^^^^^^^^^^^^^
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {
| ++
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:14:32
|
LL | unsafe extern "C" fn f(...) {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {}
| ++
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:20:32
|
LL | unsafe extern "C" fn f(...) {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {}
| ++
error: aborting due to 3 previous errors

View file

@ -0,0 +1,36 @@
//@ check-fail
//@ run-rustfix
//@ revisions: e2015 e2018
//@[e2015] edition: 2015
//@[e2018] edition: 2018
#![crate_type = "lib"]
#![deny(varargs_without_pattern)]
#[cfg(false)]
mod module {
unsafe extern "C" fn f(_: ...) {
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
unsafe extern "C" fn f(_: ...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
impl A {
unsafe extern "C" fn f(_: ...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
trait A {
unsafe extern "C" fn f(_: ...) {}
//[e2018]~^ ERROR missing pattern for `...` argument
//[e2018]~| WARN this was previously accepted by the compiler
}
unsafe extern "C" {
fn f(...); // no error
}
type A = unsafe extern "C" fn(...); // no error
}

View file

@ -0,0 +1,59 @@
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:11:28
|
LL | unsafe extern "C" fn f(...) {
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
note: the lint level is defined here
--> $DIR/parse-errors.rs:7:9
|
LL | #![deny(varargs_without_pattern)]
| ^^^^^^^^^^^^^^^^^^^^^^^
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {
| ++
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:14:32
|
LL | unsafe extern "C" fn f(...) {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {}
| ++
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:20:32
|
LL | unsafe extern "C" fn f(...) {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {}
| ++
error: missing pattern for `...` argument
--> $DIR/parse-errors.rs:26:32
|
LL | unsafe extern "C" fn f(...) {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
help: name the argument, or use `_` to continue ignoring it
|
LL | unsafe extern "C" fn f(_: ...) {}
| ++
error: aborting due to 4 previous errors

View file

@ -0,0 +1,36 @@
//@ check-fail
//@ run-rustfix
//@ revisions: e2015 e2018
//@[e2015] edition: 2015
//@[e2018] edition: 2018
#![crate_type = "lib"]
#![deny(varargs_without_pattern)]
#[cfg(false)]
mod module {
unsafe extern "C" fn f(...) {
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
unsafe extern "C" fn f(...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
impl A {
unsafe extern "C" fn f(...) {}
//~^ ERROR missing pattern for `...` argument
//~| WARN this was previously accepted by the compiler
}
trait A {
unsafe extern "C" fn f(...) {}
//[e2018]~^ ERROR missing pattern for `...` argument
//[e2018]~| WARN this was previously accepted by the compiler
}
unsafe extern "C" {
fn f(...); // no error
}
type A = unsafe extern "C" fn(...); // no error
}

View file

@ -2,7 +2,7 @@
#![feature(c_variadic)]
async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {}
//~^ ERROR functions cannot be both `async` and C-variadic
//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds

View file

@ -1,14 +1,14 @@
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
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<Output = ()>` captures lifetime that does not appear in bounds
--> $DIR/note-and-explain-ReVar-124973.rs:5:73
--> $DIR/note-and-explain-ReVar-124973.rs:5:76
|
LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
| ----------------------------------------------------------------------- ^^
LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {}
| -------------------------------------------------------------------------- ^^
| |
| opaque type defined here
|

View file

@ -4,6 +4,6 @@
fn main() {}
unsafe extern "C" fn foo(_: Bar, ...) -> impl {}
unsafe extern "C" fn foo(_: Bar, _: ...) -> impl {}
//~^ ERROR cannot find type `Bar` in this scope
//~| ERROR at least one trait must be specified

View file

@ -1,13 +1,13 @@
error: at least one trait must be specified
--> $DIR/issue-83499-input-output-iteration-ice.rs:7:42
--> $DIR/issue-83499-input-output-iteration-ice.rs:7:45
|
LL | unsafe extern "C" 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:29
|
LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {}
LL | unsafe extern "C" fn foo(_: Bar, _: ...) -> impl {}
| ^^^ not found in this scope
error: aborting due to 2 previous errors

View file

@ -3,43 +3,43 @@
fn main() {}
fn f1_1(x: isize, ...) {}
fn f1_1(x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
fn f1_2(...) {}
fn f1_2(_: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
unsafe extern "Rust" fn f1_3(...) {}
unsafe extern "Rust" fn f1_3(_: ...) {}
//~^ ERROR `...` is not supported for `extern "Rust"` functions
extern "C" fn f2_1(x: isize, ...) {}
extern "C" fn f2_1(x: isize, _: ...) {}
//~^ ERROR functions with a C variable argument list must be unsafe
extern "C" fn f2_2(...) {}
extern "C" fn f2_2(_: ...) {}
//~^ ERROR functions with a C variable argument list must be unsafe
extern "C" fn f2_3(..., x: isize) {}
extern "C" fn f2_3(_: ..., x: isize) {}
//~^ ERROR `...` must be the last argument of a C-variadic function
extern "C" fn f3_1(x: isize, ...) {}
extern "C" fn f3_1(x: isize, _: ...) {}
//~^ ERROR functions with a C variable argument list must be unsafe
extern "C" fn f3_2(...) {}
extern "C" fn f3_2(_: ...) {}
//~^ ERROR functions with a C variable argument list must be unsafe
extern "C" fn f3_3(..., x: isize) {}
extern "C" fn f3_3(_: ..., x: isize) {}
//~^ ERROR `...` must be the last argument of a C-variadic function
const unsafe extern "C" fn f4_1(x: isize, ...) {}
const unsafe extern "C" fn f4_1(x: isize, _: ...) {}
//~^ ERROR functions cannot be both `const` and C-variadic
//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
const extern "C" fn f4_2(x: isize, ...) {}
const extern "C" fn f4_2(x: isize, _: ...) {}
//~^ ERROR functions cannot be both `const` and C-variadic
//~| 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, ...) {}
const extern "C" fn f4_3(_: ..., x: isize, _: ...) {}
//~^ ERROR functions cannot be both `const` and C-variadic
//~| ERROR functions with a C variable argument list must be unsafe
//~| ERROR `...` must be the last argument of a C-variadic function
@ -52,33 +52,33 @@ extern "C" {
struct X;
impl X {
fn i_f1(x: isize, ...) {}
fn i_f1(x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
fn i_f2(...) {}
fn i_f2(_: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
fn i_f3(..., x: isize, ...) {}
fn i_f3(_: ..., x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
//~| ERROR `...` must be the last argument of a C-variadic function
fn i_f4(..., x: isize, ...) {}
fn i_f4(_: ..., x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
//~| ERROR `...` must be the last argument of a C-variadic function
const fn i_f5(x: isize, ...) {}
const fn i_f5(x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
//~| 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, ...) {}
fn t_f1(x: isize, _: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
fn t_f2(x: isize, ...);
fn t_f2(x: isize, _: ...);
//~^ ERROR `...` is not supported for non-extern functions
fn t_f3(...) {}
fn t_f3(_: ...) {}
//~^ ERROR `...` is not supported for non-extern functions
fn t_f4(...);
fn t_f4(_: ...);
//~^ ERROR `...` is not supported for non-extern functions
fn t_f5(..., x: isize) {}
fn t_f5(_: ..., x: isize) {}
//~^ ERROR `...` must be the last argument of a C-variadic function
fn t_f6(..., x: isize);
fn t_f6(_: ..., x: isize);
//~^ ERROR `...` must be the last argument of a C-variadic function
}

View file

@ -1,24 +1,24 @@
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:6:19
|
LL | fn f1_1(x: isize, ...) {}
| ^^^
LL | fn f1_1(x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
|
LL | fn f1_2(...) {}
| ^^^
LL | fn f1_2(_: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for `extern "Rust"` functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
|
LL | unsafe extern "Rust" fn f1_3(...) {}
| ------------- ^^^
LL | unsafe extern "Rust" fn f1_3(_: ...) {}
| ------------- ^^^^^^
| |
| `extern "Rust"` because of this
|
@ -27,103 +27,103 @@ LL | unsafe extern "Rust" fn f1_3(...) {}
error: functions with a C variable argument list must be unsafe
--> $DIR/variadic-ffi-semantic-restrictions.rs:15:30
|
LL | extern "C" fn f2_1(x: isize, ...) {}
| ^^^
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, ...) {}
LL | unsafe extern "C" fn f2_1(x: isize, _: ...) {}
| ++++++
error: functions with a C variable argument list must be unsafe
--> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
|
LL | extern "C" fn f2_2(...) {}
| ^^^
LL | extern "C" fn f2_2(_: ...) {}
| ^^^^^^
|
help: add the `unsafe` keyword to this definition
|
LL | unsafe extern "C" fn f2_2(...) {}
LL | unsafe extern "C" fn f2_2(_: ...) {}
| ++++++
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:21:20
|
LL | extern "C" fn f2_3(..., x: isize) {}
| ^^^
LL | extern "C" fn f2_3(_: ..., x: isize) {}
| ^^^^^^
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, ...) {}
| ^^^
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, ...) {}
LL | unsafe extern "C" fn f3_1(x: isize, _: ...) {}
| ++++++
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(...) {}
| ^^^
LL | extern "C" fn f3_2(_: ...) {}
| ^^^^^^
|
help: add the `unsafe` keyword to this definition
|
LL | unsafe extern "C" fn f3_2(...) {}
LL | unsafe extern "C" fn f3_2(_: ...) {}
| ++++++
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:30:20
|
LL | extern "C" fn f3_3(..., x: isize) {}
| ^^^
LL | extern "C" fn f3_3(_: ..., x: isize) {}
| ^^^^^^
error: functions cannot be both `const` and C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:33:1
|
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
| ^^^^^ `const` because of this ^^^ C-variadic because of this
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:37:1
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^^^ `const` because of this ^^^ C-variadic because of this
LL | const extern "C" fn f4_2(x: isize, _: ...) {}
| ^^^^^ `const` because of this ^^^^^^ C-variadic because of this
error: functions with a C variable argument list must be unsafe
--> $DIR/variadic-ffi-semantic-restrictions.rs:37:36
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^
LL | const extern "C" fn f4_2(x: isize, _: ...) {}
| ^^^^^^
|
help: add the `unsafe` keyword to this definition
|
LL | const unsafe extern "C" fn f4_2(x: isize, ...) {}
LL | const unsafe extern "C" fn f4_2(x: isize, _: ...) {}
| ++++++
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^
LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {}
| ^^^^^^
error: functions cannot be both `const` and C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:1
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^^^ `const` because of this ^^^ C-variadic because of this
LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {}
| ^^^^^ `const` because of this ^^^^^^ C-variadic because of this
error: functions with a C variable argument list must be unsafe
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:41
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:44
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^
LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {}
| ^^^^^^
|
help: add the `unsafe` keyword to this definition
|
LL | const unsafe extern "C" fn f4_3(..., x: isize, ...) {}
LL | const unsafe extern "C" fn f4_3(_: ..., x: isize, _: ...) {}
| ++++++
error: `...` must be the last argument of a C-variadic function
@ -135,128 +135,128 @@ LL | fn e_f2(..., x: isize);
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:55:23
|
LL | fn i_f1(x: isize, ...) {}
| ^^^
LL | fn i_f1(x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:57:13
|
LL | fn i_f2(...) {}
| ^^^
LL | fn i_f2(_: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
|
LL | fn i_f3(..., x: isize, ...) {}
| ^^^
LL | fn i_f3(_: ..., x: isize, _: ...) {}
| ^^^^^^
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:28
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:31
|
LL | fn i_f3(..., x: isize, ...) {}
| ^^^
LL | fn i_f3(_: ..., x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^
LL | fn i_f4(_: ..., x: isize, _: ...) {}
| ^^^^^^
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:62:28
--> $DIR/variadic-ffi-semantic-restrictions.rs:62:31
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^
LL | fn i_f4(_: ..., x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: functions cannot be both `const` and C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:5
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^^^ ^^^ C-variadic because of this
LL | const fn i_f5(x: isize, _: ...) {}
| ^^^^^ ^^^^^^ C-variadic because of this
| |
| `const` because of this
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:29
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^
LL | const fn i_f5(x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:72:23
|
LL | fn t_f1(x: isize, ...) {}
| ^^^
LL | fn t_f1(x: isize, _: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:74:23
|
LL | fn t_f2(x: isize, ...);
| ^^^
LL | fn t_f2(x: isize, _: ...);
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:76:13
|
LL | fn t_f3(...) {}
| ^^^
LL | fn t_f3(_: ...) {}
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` is not supported for non-extern functions
--> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
|
LL | fn t_f4(...);
| ^^^
LL | fn t_f4(_: ...);
| ^^^^^^
|
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:80:13
|
LL | fn t_f5(..., x: isize) {}
| ^^^
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
|
LL | fn t_f6(..., x: isize);
| ^^^
LL | fn t_f6(_: ..., x: isize);
| ^^^^^^
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
--> $DIR/variadic-ffi-semantic-restrictions.rs:33:43
|
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
| ^^^ - value is dropped here
LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {}
| ^ - value is dropped here
| |
| 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:37:36
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^ - value is dropped here
LL | const extern "C" fn f4_2(x: isize, _: ...) {}
| ^ - value is dropped here
| |
| 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:65:29
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^ - value is dropped here
LL | const fn i_f5(x: isize, _: ...) {}
| ^ - value is dropped here
| |
| the destructor for this type cannot be evaluated in constant functions

View file

@ -3,28 +3,28 @@
fn main() {}
#[cfg(false)]
fn f1_1(x: isize, ...) {}
fn f1_1(x: isize, _: ...) {}
#[cfg(false)]
fn f1_2(...) {}
fn f1_2(_: ...) {}
#[cfg(false)]
extern "C" fn f2_1(x: isize, ...) {}
extern "C" fn f2_1(x: isize, _: ...) {}
#[cfg(false)]
extern "C" fn f2_2(...) {}
extern "C" fn f2_2(_: ...) {}
#[cfg(false)]
extern "C" fn f2_3(..., x: isize) {}
extern "C" fn f2_3(_: ..., x: isize) {}
#[cfg(false)]
extern fn f3_1(x: isize, ...) {}
extern fn f3_1(x: isize, _: ...) {}
#[cfg(false)]
extern fn f3_2(...) {}
extern fn f3_2(_: ...) {}
#[cfg(false)]
extern fn f3_3(..., x: isize) {}
extern fn f3_3(_: ..., x: isize) {}
#[cfg(false)]
extern {
@ -36,18 +36,18 @@ struct X;
#[cfg(false)]
impl X {
fn i_f1(x: isize, ...) {}
fn i_f2(...) {}
fn i_f3(..., x: isize, ...) {}
fn i_f4(..., x: isize, ...) {}
fn i_f1(x: isize, _: ...) {}
fn i_f2(_: ...) {}
fn i_f3(_: ..., x: isize, _: ...) {}
fn i_f4(_: ..., x: isize, _: ...) {}
}
#[cfg(false)]
trait T {
fn t_f1(x: isize, ...) {}
fn t_f2(x: isize, ...);
fn t_f3(...) {}
fn t_f4(...);
fn t_f5(..., x: isize) {}
fn t_f6(..., x: isize);
fn t_f1(x: isize, _: ...) {}
fn t_f2(x: isize, _: ...);
fn t_f3(_: ...) {}
fn t_f4(_: ...);
fn t_f5(_: ..., x: isize) {}
fn t_f6(_: ..., x: isize);
}

View file

@ -1,6 +1,7 @@
//@ compile-flags: -Zunpretty=thir-tree --crate-type=lib
//@ check-pass
#![feature(c_variadic)]
#![expect(varargs_without_pattern)]
// The `...` argument uses `PatKind::Missing`.
unsafe extern "C" fn foo(_: i32, ...) {}

View file

@ -2,13 +2,13 @@ DefId(0:3 ~ c_variadic[a5de]::foo):
params: [
Param {
ty: i32
ty_span: Some($DIR/c-variadic.rs:6:29: 6:32 (#0))
ty_span: Some($DIR/c-variadic.rs:7:29: 7:32 (#0))
self_kind: None
hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).1))
param: Some(
Pat: {
ty: i32
span: $DIR/c-variadic.rs:6:26: 6:27 (#0)
span: $DIR/c-variadic.rs:7:26: 7:27 (#0)
kind: PatKind {
Wild
}
@ -23,7 +23,7 @@ params: [
param: Some(
Pat: {
ty: std::ffi::VaListImpl<'{erased}>
span: $DIR/c-variadic.rs:6:34: 6:37 (#0)
span: $DIR/c-variadic.rs:7:34: 7:37 (#0)
kind: PatKind {
Missing
}
@ -35,7 +35,7 @@ body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None }
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
span: $DIR/c-variadic.rs:7:39: 7:41 (#0)
kind:
Scope {
region_scope: Node(6)
@ -44,11 +44,11 @@ body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None }
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
span: $DIR/c-variadic.rs:7:39: 7:41 (#0)
kind:
Block {
targeted_by_break: false
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
span: $DIR/c-variadic.rs:7:39: 7:41 (#0)
region_scope: Node(5)
safety_mode: Safe
stmts: []