feature-gate c-variadic definitions and calls in const contexts
This commit is contained in:
parent
f5bf3353e6
commit
981dacc34f
11 changed files with 88 additions and 5 deletions
|
|
@ -698,6 +698,13 @@ impl<'a> AstValidator<'a> {
|
|||
unreachable!("C variable argument list cannot be used in closures")
|
||||
};
|
||||
|
||||
if let Const::Yes(_) = sig.header.constness
|
||||
&& !self.features.enabled(sym::const_c_variadic)
|
||||
{
|
||||
let msg = format!("c-variadic const function definitions are unstable");
|
||||
feature_err(&self.sess, sym::const_c_variadic, sig.span, msg).emit();
|
||||
}
|
||||
|
||||
if let Some(coroutine_kind) = sig.header.coroutine_kind {
|
||||
self.dcx().emit_err(errors::CoroutineAndCVariadic {
|
||||
spans: vec![coroutine_kind.span(), variadic_param.span],
|
||||
|
|
|
|||
|
|
@ -815,6 +815,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
if self.tcx.fn_sig(callee).skip_binder().c_variadic() {
|
||||
self.check_op(ops::FnCallCVariadic)
|
||||
}
|
||||
|
||||
// At this point, we are calling a function, `callee`, whose `DefId` is known...
|
||||
|
||||
// `begin_panic` and `panic_display` functions accept generic
|
||||
|
|
|
|||
|
|
@ -75,6 +75,27 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
|
|||
}
|
||||
}
|
||||
|
||||
/// A c-variadic function call.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct FnCallCVariadic;
|
||||
impl<'tcx> NonConstOp<'tcx> for FnCallCVariadic {
|
||||
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
|
||||
Status::Unstable {
|
||||
gate: sym::const_c_variadic,
|
||||
gate_already_checked: false,
|
||||
safe_to_expose_on_stable: false,
|
||||
is_function_call: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||
ccx.tcx.sess.create_feature_err(
|
||||
errors::NonConstCVariadicCall { span, kind: ccx.const_kind() },
|
||||
sym::const_c_variadic,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A call to a function that is in a trait, or has trait bounds that make it conditionally-const.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ConditionallyConstCall<'tcx> {
|
||||
|
|
|
|||
|
|
@ -531,6 +531,19 @@ pub struct NonConstClosure {
|
|||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(r#"calling const c-variadic functions is unstable in {$kind ->
|
||||
[const] constant
|
||||
[static] static
|
||||
[const_fn] constant function
|
||||
*[other] {""}
|
||||
}s"#, code = E0015)]
|
||||
pub struct NonConstCVariadicCall {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum NonConstClosureNote {
|
||||
#[note("function defined here, but it is not `const`")]
|
||||
|
|
|
|||
|
|
@ -420,6 +420,8 @@ declare_features! (
|
|||
(unstable, const_async_blocks, "1.53.0", Some(85368)),
|
||||
/// Allows `const { ... }` as a shorthand for `const _: () = const { ... };` for module items.
|
||||
(unstable, const_block_items, "CURRENT_RUSTC_VERSION", Some(149226)),
|
||||
/// Allows defining and calling c-variadic functions in const contexts.
|
||||
(unstable, const_c_variadic, "CURRENT_RUSTC_VERSION", Some(151787)),
|
||||
/// Allows `const || {}` closures in const contexts.
|
||||
(incomplete, const_closures, "1.68.0", Some(106003)),
|
||||
/// Allows using `[const] Destruct` bounds and calling drop impls in const contexts.
|
||||
|
|
|
|||
|
|
@ -740,6 +740,7 @@ symbols! {
|
|||
const_allocate,
|
||||
const_async_blocks,
|
||||
const_block_items,
|
||||
const_c_variadic,
|
||||
const_closures,
|
||||
const_compare_raw_pointers,
|
||||
const_constructor,
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ impl VaList<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_const_unstable(feature = "c_variadic_const", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")]
|
||||
impl<'f> const Clone for VaList<'f> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
|
|
@ -217,7 +217,7 @@ impl<'f> const Clone for VaList<'f> {
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_const_unstable(feature = "c_variadic_const", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")]
|
||||
impl<'f> const Drop for VaList<'f> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: this variable argument list is being dropped, so won't be read from again.
|
||||
|
|
@ -293,7 +293,7 @@ impl<'f> VaList<'f> {
|
|||
///
|
||||
/// [valid]: https://doc.rust-lang.org/nightly/nomicon/what-unsafe-does.html
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "c_variadic_const", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")]
|
||||
pub const unsafe fn arg<T: VaArgSafe>(&mut self) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `va_arg`.
|
||||
unsafe { va_arg(self) }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@ build-fail
|
||||
|
||||
#![feature(c_variadic)]
|
||||
#![feature(c_variadic_const)]
|
||||
#![feature(const_c_variadic)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(const_clone)]
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
//@ ignore-backends: gcc
|
||||
|
||||
#![feature(c_variadic)]
|
||||
#![feature(const_c_variadic)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(c_variadic_const)]
|
||||
#![feature(const_cmp)]
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
|
|
|
|||
11
tests/ui/feature-gates/feature-gate-const-c-variadic.rs
Normal file
11
tests/ui/feature-gates/feature-gate-const-c-variadic.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(c_variadic)]
|
||||
|
||||
fn main() {
|
||||
const unsafe extern "C" fn foo(ap: ...) {
|
||||
//~^ ERROR c-variadic const function definitions are unstable
|
||||
core::mem::forget(ap);
|
||||
}
|
||||
|
||||
const { unsafe { foo() } }
|
||||
//~^ ERROR calling const c-variadic functions is unstable in constants
|
||||
}
|
||||
24
tests/ui/feature-gates/feature-gate-const-c-variadic.stderr
Normal file
24
tests/ui/feature-gates/feature-gate-const-c-variadic.stderr
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
error[E0658]: c-variadic const function definitions are unstable
|
||||
--> $DIR/feature-gate-const-c-variadic.rs:4:5
|
||||
|
|
||||
LL | const unsafe extern "C" fn foo(ap: ...) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151787 <https://github.com/rust-lang/rust/issues/151787> for more information
|
||||
= help: add `#![feature(const_c_variadic)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0015]: calling const c-variadic functions is unstable in constants
|
||||
--> $DIR/feature-gate-const-c-variadic.rs:9:22
|
||||
|
|
||||
LL | const { unsafe { foo() } }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #151787 <https://github.com/rust-lang/rust/issues/151787> for more information
|
||||
= help: add `#![feature(const_c_variadic)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0658.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue