c_variadic: Add future-incompatibility warning for ... arguments without a pattern outside of extern blocks
This commit is contained in:
parent
a7b3715826
commit
02e1f4421d
31 changed files with 496 additions and 192 deletions
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {"{}"}`
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)) => {
|
||||
|
|
|
|||
|
|
@ -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)");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -838,7 +838,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,
|
||||
};
|
||||
|
|
@ -1394,7 +1394,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 });
|
||||
|
|
@ -1485,7 +1486,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);
|
||||
|
|
|
|||
|
|
@ -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 _ =
|
||||
|
|
|
|||
|
|
@ -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(_: ...) {} };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ,
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
36
tests/ui/c-variadic/parse-errors.e2015.fixed
Normal file
36
tests/ui/c-variadic/parse-errors.e2015.fixed
Normal 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
|
||||
}
|
||||
46
tests/ui/c-variadic/parse-errors.e2015.stderr
Normal file
46
tests/ui/c-variadic/parse-errors.e2015.stderr
Normal 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
|
||||
|
||||
36
tests/ui/c-variadic/parse-errors.e2018.fixed
Normal file
36
tests/ui/c-variadic/parse-errors.e2018.fixed
Normal 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
|
||||
}
|
||||
59
tests/ui/c-variadic/parse-errors.e2018.stderr
Normal file
59
tests/ui/c-variadic/parse-errors.e2018.stderr
Normal 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
|
||||
|
||||
36
tests/ui/c-variadic/parse-errors.rs
Normal file
36
tests/ui/c-variadic/parse-errors.rs
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, ...) {}
|
||||
|
|
|
|||
|
|
@ -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: []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue