From 5dcbd089418eb7c13653b8fb75e79059a8fbdecd Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 8 Jul 2025 00:09:05 +0100 Subject: [PATCH] `c_variadic`: Add future-incompatibility warning for `...` arguments without a pattern outside of `extern` blocks --- compiler/rustc_lint_defs/src/builtin.rs | 48 ++++++ compiler/rustc_parse/messages.ftl | 3 + compiler/rustc_parse/src/errors.rs | 7 + compiler/rustc_parse/src/parser/attr.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 3 +- compiler/rustc_parse/src/parser/item.rs | 55 +++++-- compiler/rustc_parse/src/parser/path.rs | 2 +- compiler/rustc_parse/src/parser/stmt.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 8 +- tests/crashes/132142.rs | 2 +- tests/pretty/hir-fn-variadic.pp | 6 +- tests/pretty/hir-fn-variadic.rs | 10 +- tests/ui/c-variadic/issue-86053-1.rs | 2 +- tests/ui/c-variadic/issue-86053-1.stderr | 32 ++-- tests/ui/c-variadic/issue-86053-2.rs | 2 +- tests/ui/c-variadic/issue-86053-2.stderr | 4 +- tests/ui/c-variadic/parse-errors.e2015.fixed | 36 +++++ tests/ui/c-variadic/parse-errors.e2015.stderr | 46 ++++++ tests/ui/c-variadic/parse-errors.e2018.fixed | 36 +++++ tests/ui/c-variadic/parse-errors.e2018.stderr | 59 ++++++++ tests/ui/c-variadic/parse-errors.rs | 36 +++++ .../note-and-explain-ReVar-124973.rs | 2 +- .../note-and-explain-ReVar-124973.stderr | 6 +- .../issue-83499-input-output-iteration-ice.rs | 2 +- ...ue-83499-input-output-iteration-ice.stderr | 12 +- .../variadic-ffi-semantic-restrictions.rs | 44 +++--- .../variadic-ffi-semantic-restrictions.stderr | 140 +++++++++--------- .../ui/parser/variadic-ffi-syntactic-pass.rs | 36 ++--- 28 files changed, 473 insertions(+), 170 deletions(-) create mode 100644 tests/ui/c-variadic/parse-errors.e2015.fixed create mode 100644 tests/ui/c-variadic/parse-errors.e2015.stderr create mode 100644 tests/ui/c-variadic/parse-errors.e2018.fixed create mode 100644 tests/ui/c-variadic/parse-errors.e2018.stderr create mode 100644 tests/ui/c-variadic/parse-errors.rs diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index b79075ac09b9c..8e000b5010c55 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -142,6 +142,7 @@ declare_lint_pass! { UNUSED_UNSAFE, UNUSED_VARIABLES, USELESS_DEPRECATED, + VARARGS_WITHOUT_PATTERN, WARNINGS, // tidy-alphabetical-end ] @@ -5195,3 +5196,50 @@ declare_lint! { Warn, r#"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"#, } + +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 ", + report_in_deps: false, + }; +} diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 77dd313d9b8eb..1fe999a60129c 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -1012,6 +1012,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() {"{}"}` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 797d4830c2ff2..e98edbbcd4f16 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3675,3 +3675,10 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { } } } + +#[derive(LintDiagnostic)] +#[diag(parse_varargs_without_pattern)] +pub(crate) struct VarargsWithoutPattern { + #[suggestion(code = "_: ...", applicability = "machine-applicable")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index acd338156ce88..4ba85c73b376f 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -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)) => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a28af7833c387..bc4e771e7d49e 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -46,6 +46,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. @@ -2273,7 +2274,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)"); } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index eb264f59fedbe..86a031e8eca00 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -10,6 +10,7 @@ use rustc_ast::{self as 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}; @@ -117,7 +118,7 @@ impl<'a> Parser<'a> { impl<'a> Parser<'a> { pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option>> { 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)) } @@ -977,7 +978,7 @@ impl<'a> Parser<'a> { force_collect: ForceCollect, ) -> PResult<'a, Option>>> { 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) } @@ -986,7 +987,7 @@ impl<'a> Parser<'a> { force_collect: ForceCollect, ) -> PResult<'a, Option>>> { let fn_parse_mode = FnParseMode { - req_name: |edition| edition >= Edition::Edition2018, + req_name: |edition, _| edition >= Edition::Edition2018, context: FnContext::Trait, req_body: false, }; @@ -1266,8 +1267,11 @@ impl<'a> Parser<'a> { &mut self, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - 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) { @@ -2142,7 +2146,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, @@ -2375,8 +2379,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. /// @@ -2409,6 +2421,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. @@ -3055,11 +3070,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); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 8604564885916..c8d35218063f5 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -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); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index ad5ab6e6b7794..3fe8971f3d6c6 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -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))) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 6168647183fdb..fcd65198af862 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -794,7 +794,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, }; @@ -1352,7 +1352,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 }); @@ -1443,7 +1444,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); diff --git a/tests/crashes/132142.rs b/tests/crashes/132142.rs index 813bf0bf0a8e5..bfad88721aa8a 100644 --- a/tests/crashes/132142.rs +++ b/tests/crashes/132142.rs @@ -1,3 +1,3 @@ //@ known-bug: #132142 -async extern "cmse-nonsecure-entry" fn fun(...) {} +async extern "cmse-nonsecure-entry" fn fun(_: ...) {} diff --git a/tests/pretty/hir-fn-variadic.pp b/tests/pretty/hir-fn-variadic.pp index c0f5b7069a2d7..8cbd8f41b6469 100644 --- a/tests/pretty/hir-fn-variadic.pp +++ b/tests/pretty/hir-fn-variadic.pp @@ -16,12 +16,12 @@ 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 _ = diff --git a/tests/pretty/hir-fn-variadic.rs b/tests/pretty/hir-fn-variadic.rs index 99aa402c480b0..ce1b0f835ab27 100644 --- a/tests/pretty/hir-fn-variadic.rs +++ b/tests/pretty/hir-fn-variadic.rs @@ -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(_: ...) {} }; } diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index 537d0263adf78..4e217e4fd6771 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -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 diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index 675dfd335c42e..9e5a703f49d3c 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -25,46 +25,46 @@ 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: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $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[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 , 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/parse-errors.e2015.fixed b/tests/ui/c-variadic/parse-errors.e2015.fixed new file mode 100644 index 0000000000000..042736cdf6c0d --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2015.fixed @@ -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 +} diff --git a/tests/ui/c-variadic/parse-errors.e2015.stderr b/tests/ui/c-variadic/parse-errors.e2015.stderr new file mode 100644 index 0000000000000..de9362c4380de --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2015.stderr @@ -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 +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 +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 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/c-variadic/parse-errors.e2018.fixed b/tests/ui/c-variadic/parse-errors.e2018.fixed new file mode 100644 index 0000000000000..596e57ca5614b --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2018.fixed @@ -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 +} diff --git a/tests/ui/c-variadic/parse-errors.e2018.stderr b/tests/ui/c-variadic/parse-errors.e2018.stderr new file mode 100644 index 0000000000000..a7d5f79bf1339 --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2018.stderr @@ -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 +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 +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 +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 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/c-variadic/parse-errors.rs b/tests/ui/c-variadic/parse-errors.rs new file mode 100644 index 0000000000000..f8b25c545dd1a --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.rs @@ -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 +} diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.rs b/tests/ui/inference/note-and-explain-ReVar-124973.rs index f1e2464563699..ad304969fcf04 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.rs +++ b/tests/ui/inference/note-and-explain-ReVar-124973.rs @@ -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 hidden type for `impl Future` captures lifetime that does not appear in bounds 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..29c4f3b57c7cc 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Future` 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 | 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 9277994d9b30f..cabd950ea0add 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -4,7 +4,7 @@ fn main() {} -fn foo(_: Bar, ...) -> impl {} +fn foo(_: Bar, _: ...) -> impl {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR cannot find type `Bar` in this scope //~| 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 4a1aa49eb6e6f..bba74d5e10622 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,19 +1,19 @@ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 | -LL | fn foo(_: Bar, ...) -> impl {} - | ^^^ +LL | fn foo(_: Bar, _: ...) -> impl {} + | ^^^^^^ error: at least one trait must be specified - --> $DIR/issue-83499-input-output-iteration-ice.rs:7:24 + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:27 | -LL | fn foo(_: Bar, ...) -> impl {} - | ^^^^ +LL | fn foo(_: Bar, _: ...) -> impl {} + | ^^^^ error[E0412]: cannot find type `Bar` in this scope --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11 | -LL | fn foo(_: Bar, ...) -> impl {} +LL | fn foo(_: Bar, _: ...) -> impl {} | ^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index e7a0248cffab9..d4946b4bf63e0 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -3,42 +3,42 @@ fn main() {} -fn f1_1(x: isize, ...) {} +fn f1_1(x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -fn f1_2(...) {} +fn f1_2(_: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -extern "C" fn f2_1(x: isize, ...) {} +extern "C" fn f2_1(x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -extern "C" fn f2_2(...) {} +extern "C" fn f2_2(_: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -extern "C" fn f2_3(..., x: isize) {} +extern "C" fn f2_3(_: ..., x: isize) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| 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 defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -extern "C" fn f3_2(...) {} +extern "C" fn f3_2(_: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention -extern "C" fn f3_3(..., x: isize) {} +extern "C" fn f3_3(_: ..., x: isize) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| 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 defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| 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 defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function @@ -51,35 +51,35 @@ extern "C" { struct X; impl X { - fn i_f1(x: isize, ...) {} + fn i_f1(x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn i_f2(...) {} + fn i_f2(_: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn i_f3(..., x: isize, ...) {} + fn i_f3(_: ..., x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function - fn i_f4(..., x: isize, ...) {} + fn i_f4(_: ..., x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function - const fn i_f5(x: isize, ...) {} + const fn i_f5(x: isize, _: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| 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 defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn t_f2(x: isize, ...); + fn t_f2(x: isize, _: ...); //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn t_f3(...) {} + fn t_f3(_: ...) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn t_f4(...); + fn t_f4(_: ...); //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - fn t_f5(..., x: isize) {} + fn t_f5(_: ..., x: isize) {} //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function - fn t_f6(..., x: isize); + fn t_f6(_: ..., x: isize); //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| 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 5379045967aa0..99a11a2f6084e 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,92 +1,92 @@ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 | -LL | fn f1_1(x: isize, ...) {} - | ^^^ +LL | fn f1_1(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | -LL | fn f1_2(...) {} - | ^^^ +LL | fn f1_2(_: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | -LL | extern "C" fn f2_1(x: isize, ...) {} - | ^^^ +LL | extern "C" fn f2_1(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20 | -LL | extern "C" fn f2_2(...) {} - | ^^^ +LL | extern "C" fn f2_2(_: ...) {} + | ^^^^^^ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | -LL | extern "C" fn f2_3(..., x: isize) {} - | ^^^ +LL | extern "C" fn f2_3(_: ..., x: isize) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | -LL | extern "C" fn f2_3(..., x: isize) {} - | ^^^ +LL | extern "C" fn f2_3(_: ..., x: isize) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:22:30 | -LL | extern "C" fn f3_1(x: isize, ...) {} - | ^^^ +LL | extern "C" fn f3_1(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:25:20 | -LL | extern "C" fn f3_2(...) {} - | ^^^ +LL | extern "C" fn f3_2(_: ...) {} + | ^^^^^^ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | -LL | extern "C" fn f3_3(..., x: isize) {} - | ^^^ +LL | extern "C" fn f3_3(_: ..., x: isize) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:28: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:32: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:36: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: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | -LL | const extern "C" fn f4_2(x: isize, ...) {} - | ^^^ +LL | const 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 | -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:41:1 | -LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^^^ ^^^ ^^^ C-variadic because of this +LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} + | ^^^^^ ^^^^^^ ^^^^^^ C-variadic because of this | | | | | C-variadic because of this | `const` because of this @@ -94,8 +94,8 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {} error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | -LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^ ^^^ +LL | const 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 @@ -106,122 +106,122 @@ LL | fn e_f2(..., x: isize); error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:54:23 | -LL | fn i_f1(x: isize, ...) {} - | ^^^ +LL | fn i_f1(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13 | -LL | fn i_f2(...) {} - | ^^^ +LL | fn i_f2(_: ...) {} + | ^^^^^^ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | -LL | fn i_f3(..., x: isize, ...) {} - | ^^^ +LL | fn i_f3(_: ..., x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | -LL | fn i_f3(..., x: isize, ...) {} - | ^^^ ^^^ +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 | -LL | fn i_f4(..., x: isize, ...) {} - | ^^^ +LL | fn i_f4(_: ..., x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | -LL | fn i_f4(..., x: isize, ...) {} - | ^^^ ^^^ +LL | fn i_f4(_: ..., x: isize, _: ...) {} + | ^^^^^^ ^^^^^^ error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:64: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: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | -LL | const fn i_f5(x: isize, ...) {} - | ^^^ +LL | const fn i_f5(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23 | -LL | fn t_f1(x: isize, ...) {} - | ^^^ +LL | fn t_f1(x: isize, _: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23 | -LL | fn t_f2(x: isize, ...); - | ^^^ +LL | fn t_f2(x: isize, _: ...); + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13 | -LL | fn t_f3(...) {} - | ^^^ +LL | fn t_f3(_: ...) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 | -LL | fn t_f4(...); - | ^^^ +LL | fn t_f4(_: ...); + | ^^^^^^ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | -LL | fn t_f5(..., x: isize) {} - | ^^^ +LL | fn t_f5(_: ..., x: isize) {} + | ^^^^^^ error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:79: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: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $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:32: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:36: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:64: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 diff --git a/tests/ui/parser/variadic-ffi-syntactic-pass.rs b/tests/ui/parser/variadic-ffi-syntactic-pass.rs index ebe0b6c2dd258..6a6656044e174 100644 --- a/tests/ui/parser/variadic-ffi-syntactic-pass.rs +++ b/tests/ui/parser/variadic-ffi-syntactic-pass.rs @@ -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); }