Rollup merge of #143619 - beetrees:varargs-named, r=jdonszelmann
`c_variadic`: Add future-incompatibility warning for `...` arguments without a pattern outside of `extern` blocks
This PR makes `...` arguments without a pattern in non-foreign functions (such as the argument in `unsafe extern "C" fn f(...) {}`) a future-compatibility warning; making this error would be consistent with how `unsafe extern "C" fn f(u32) {}` is handled. Allowing `...` arguments without a pattern in non-foreign functions is a source of confusion for programmers coming from C, where the `...` parameter is never named and instead calling `va_start` is required; disallowing `...` arguments without a pattern also improves the overall consistency of the Rust language by matching the treatment of other arguments without patterns. `...` arguments without a pattern in `extern` blocks (such as `unsafe extern "C" { fn f(...); }`) continue to compile without warnings after this PR, as they are already stable and heavily used (and don't cause the mentioned confusion as they are just being used in function declarations).
As all the syntax gating for `c_variadic` has been done post-expansion, this is technically a breaking change. In particular, code like this has compiled on stable since Rust 1.35.0:
```rust
#[cfg(any())] // Equivalent to the more recent #[cfg(false)]
unsafe extern "C" fn bar(_: u32, ...) {}
```
Since this is more or less a stability hole and a Crater run shows only the `binrw` crate is using this, I think it would be ok to break this. This will require a lang FCP.
The idea of rejecting `...` pre-expansion was first raised here https://github.com/rust-lang/rust/pull/143546#issuecomment-3043142052.
Tracking issue: rust-lang/rust#44930
cc `@folkertdev` `@workingjubilee`
r? `@joshtriplett`
This commit is contained in:
commit
3538bc18fe
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)))
|
||||
|
|
|
|||
|
|
@ -824,7 +824,7 @@ impl<'a> Parser<'a> {
|
|||
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
|
||||
}
|
||||
let mode = crate::parser::item::FnParseMode {
|
||||
req_name: |_| false,
|
||||
req_name: |_, _| false,
|
||||
context: FnContext::Free,
|
||||
req_body: false,
|
||||
};
|
||||
|
|
@ -1380,7 +1380,8 @@ impl<'a> Parser<'a> {
|
|||
self.bump();
|
||||
let args_lo = self.token.span;
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false };
|
||||
let mode =
|
||||
FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
|
||||
match self.parse_fn_decl(&mode, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
|
||||
Ok(decl) => {
|
||||
self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
|
||||
|
|
@ -1471,7 +1472,8 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// Parse `(T, U) -> R`.
|
||||
let inputs_lo = self.token.span;
|
||||
let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false };
|
||||
let mode =
|
||||
FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
|
||||
let inputs: ThinVec<_> =
|
||||
self.parse_fn_params(&mode)?.into_iter().map(|input| input.ty).collect();
|
||||
let inputs_span = inputs_lo.to(self.prev_token.span);
|
||||
|
|
|
|||
|
|
@ -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