diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 1442f1832b9b5..d7d64180ec9c1 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -419,7 +419,7 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unstable_in_stable = const-stable function cannot use `#[feature({$gate})]` .unstable_sugg = if it is not part of the public API, make this function unstably const - .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) const_eval_unterminated_c_string = reading a null-terminated string starting at {$pointer} with no null found before end of allocation diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index c4f06e5af0be5..f0998300dc843 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -9,13 +9,19 @@ use super::check::Qualifs; use super::ops::{self, NonConstOp}; use super::qualifs::{NeedsNonConstDrop, Qualif}; use super::ConstCx; +use crate::check_consts::rustc_allow_const_fn_unstable; /// Returns `true` if we should use the more precise live drop checker that runs after drop /// elaboration. pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool { - // Const-stable functions must always use the stable live drop checker. + // Const-stable functions must always use the stable live drop checker... if ccx.is_const_stable_const_fn() { - return false; + // ...except if they have the feature flag set via `rustc_allow_const_fn_unstable`. + return rustc_allow_const_fn_unstable( + ccx.tcx, + ccx.body.source.def_id().expect_local(), + sym::const_precise_live_drops, + ); } ccx.tcx.features().const_precise_live_drops diff --git a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs index a97eeadd92f4e..fe92787aec11b 100644 --- a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs +++ b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs @@ -1,6 +1,4 @@ //@ run-pass -#![feature(rustc_allow_const_fn_unstable)] - #![feature(rustc_attrs, staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index 7ec2508ca93a6..8f8a20399f94b 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -25,7 +25,7 @@ help: if it is not part of the public API, make this function unstably const LL + #[rustc_const_unstable(feature = "...", issue = "...")] LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } | -help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) | LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr index 72c1f175d1d6b..9179cd4b34134 100644 --- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr @@ -25,7 +25,7 @@ help: if it is not part of the public API, make this function unstably const LL + #[rustc_const_unstable(feature = "...", issue = "...")] LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } | -help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) | LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr new file mode 100644 index 0000000000000..6038c6d332fec --- /dev/null +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr @@ -0,0 +1,12 @@ +error[E0493]: destructor of `Option` cannot be evaluated at compile-time + --> $DIR/precise-drop-allow-const-fn-unstable.rs:11:24 + | +LL | pub const fn unwrap(this: Option) -> T { + | ^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs new file mode 100644 index 0000000000000..56155e519dca4 --- /dev/null +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs @@ -0,0 +1,17 @@ +//@ revisions: allow not_allow +//@ compile-flags: --crate-type=lib -Cinstrument-coverage -Zno-profiler-runtime +//@[allow] check-pass + +#![feature(staged_api, rustc_allow_const_fn_unstable)] +#![stable(feature = "rust_test", since = "1.0.0")] + +#[stable(feature = "rust_test", since = "1.0.0")] +#[rustc_const_stable(feature = "rust_test", since = "1.0.0")] +#[cfg_attr(allow, rustc_allow_const_fn_unstable(const_precise_live_drops))] +pub const fn unwrap(this: Option) -> T { +//[not_allow]~^ ERROR: cannot be evaluated + match this { + Some(x) => x, + None => panic!(), + } +} diff --git a/tests/ui/internal/internal-unstable-const.stderr b/tests/ui/internal/internal-unstable-const.stderr index ed9196d2b63bd..3263d518b38e8 100644 --- a/tests/ui/internal/internal-unstable-const.stderr +++ b/tests/ui/internal/internal-unstable-const.stderr @@ -9,7 +9,7 @@ help: if it is not part of the public API, make this function unstably const LL + #[rustc_const_unstable(feature = "...", issue = "...")] LL | pub const fn foo() -> f32 { | -help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) | LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] LL | pub const fn foo() -> f32 {