diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index effaedd0820c3..4019ea817533e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -295,17 +295,19 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { let gate = match op.status_in_item(self.ccx) { Status::Allowed => return, - Status::Unstable(gate) if self.tcx.features().active(gate) => { + Status::Unstable(gate) => { let unstable_in_stable = self.ccx.is_const_stable_const_fn() && !super::rustc_allow_const_fn_unstable(self.tcx, self.def_id(), gate); if unstable_in_stable { emit_unstable_in_stable_error(self.ccx, span, gate); + return; + } else if self.tcx.features().declared(gate) && self.tcx.features().active(gate) { + return; + } else { + Some(gate) } - - return; } - Status::Unstable(gate) => Some(gate), Status::Forbidden => None, }; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 5b4bbf8510b60..fe49bb935c28b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -317,6 +317,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { pub struct FnCallUnstable(pub DefId, pub Option); impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { + fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status { + if let Some(symbol) = self.1 { Status::Unstable(symbol) } else { Status::Forbidden } + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { let FnCallUnstable(def_id, feature) = *self; @@ -327,7 +331,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { // FIXME: make this translatable #[allow(rustc::untranslatable_diagnostic)] if ccx.is_const_stable_const_fn() { - err.help("const-stable functions can only call other const-stable functions"); + if self.1.is_some() { + bug!("this should be triggering the UnstableInStable lint instead"); + } else { + err.help("const-stable functions can only call other const-stable functions"); + } } else if ccx.tcx.sess.is_nightly_build() { if let Some(feature) = feature { err.help(format!("add `#![feature({feature})]` to the crate attributes to enable")); diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs index bb240fb4ad62c..2adf14e38f9aa 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs @@ -13,7 +13,7 @@ const fn foo() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn +const fn bar() -> u32 { foo() } //~ ERROR const-stable function cannot use `#[feature(foo)]` #[unstable(feature = "foo2", issue = "none")] const fn foo2() -> u32 { 42 } @@ -21,7 +21,7 @@ const fn foo2() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn +const fn bar2() -> u32 { foo2() } //~ ERROR const-stable function cannot use `#[feature(foo2)]` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] @@ -36,6 +36,6 @@ const fn foo2_gated() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn +const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR const-stable function cannot use `#[feature(foo2)]` fn main() {} 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..b1e80eccb2c7b 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 @@ -1,10 +1,19 @@ -error: `foo` is not yet stable as a const fn +error: const-stable function cannot use `#[feature(foo)]` --> $DIR/min_const_fn_libstd_stability.rs:16:25 | LL | const fn bar() -> u32 { foo() } | ^^^^^ | - = help: const-stable functions can only call other const-stable functions +help: if it is not part of the public API, make this function unstably const + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const fn bar() -> u32 { foo() } + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(foo)] +LL | const fn bar() -> u32 { foo() } + | error: `foo2` is not yet stable as a const fn --> $DIR/min_const_fn_libstd_stability.rs:24:26 diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs index 03084c8674dc2..234a9342a5716 100644 --- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs +++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs @@ -13,7 +13,7 @@ const unsafe fn foo() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR not yet stable as a const fn +const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR const-stable function cannot use `#[feature(foo)]` #[unstable(feature = "foo2", issue = "none")] const unsafe fn foo2() -> u32 { 42 } @@ -21,7 +21,7 @@ const unsafe fn foo2() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as a const fn +const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR const-stable function cannot use `#[feature(foo2)]` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] @@ -37,6 +37,6 @@ const unsafe fn foo2_gated() -> u32 { 42 } #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } -//~^ ERROR not yet stable as a const fn +//~^ ERROR const-stable function cannot use `#[feature(foo2)]` fn main() {} 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..701d91f5fedd9 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 @@ -1,10 +1,19 @@ -error: `foo` is not yet stable as a const fn +error: const-stable function cannot use `#[feature(foo)]` --> $DIR/min_const_unsafe_fn_libstd_stability.rs:16:41 | LL | const unsafe fn bar() -> u32 { unsafe { foo() } } | ^^^^^ | - = help: const-stable functions can only call other const-stable functions +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 bar() -> u32 { unsafe { foo() } } + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(foo)] +LL | const unsafe fn bar() -> u32 { unsafe { foo() } } + | error: `foo2` is not yet stable as a const fn --> $DIR/min_const_unsafe_fn_libstd_stability.rs:24:42 diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs index 94b6207136298..2e36c52ce2e82 100644 --- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs +++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs @@ -13,7 +13,7 @@ const fn foo() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const unsafe fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn +const unsafe fn bar() -> u32 { foo() } //~ ERROR const-stable function cannot use `#[feature(foo)]` #[unstable(feature = "foo2", issue = "none")] const fn foo2() -> u32 { 42 } @@ -21,7 +21,7 @@ const fn foo2() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const unsafe fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn +const unsafe fn bar2() -> u32 { foo2() } //~ ERROR const-stable function cannot use `#[feature(foo)]` // check whether this function cannot be called even with the feature gate active #[unstable(feature = "foo2", issue = "none")] @@ -30,6 +30,6 @@ const fn foo2_gated() -> u32 { 42 } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] // can't call non-min_const_fn -const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn +const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR const-stable function cannot use `#[feature(foo)]` fn main() {} diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr index e90ba9b912fe1..f6230f8a5ae82 100644 --- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr +++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr @@ -1,10 +1,19 @@ -error: `foo` is not yet stable as a const fn +error: const-stable function cannot use `#[feature(foo)]` --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:16:32 | LL | const unsafe fn bar() -> u32 { foo() } | ^^^^^ | - = help: const-stable functions can only call other const-stable functions +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 bar() -> u32 { foo() } + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(foo)] +LL | const unsafe fn bar() -> u32 { foo() } + | error: `foo2` is not yet stable as a const fn --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:24:33 diff --git a/tests/ui/intrinsics/const-eval-select-stability.rs b/tests/ui/intrinsics/const-eval-select-stability.rs index f9554decec16b..3bb161aef8957 100644 --- a/tests/ui/intrinsics/const-eval-select-stability.rs +++ b/tests/ui/intrinsics/const-eval-select-stability.rs @@ -15,7 +15,7 @@ const fn nothing(){} #[rustc_const_stable(since = "1.0", feature = "const_hey")] pub const unsafe fn hey() { const_eval_select((), nothing, log); - //~^ ERROR `const_eval_select` is not yet stable as a const fn + //~^ ERROR const-stable function cannot use `#[feature(const_eval_select)]` } fn main() {} diff --git a/tests/ui/intrinsics/const-eval-select-stability.stderr b/tests/ui/intrinsics/const-eval-select-stability.stderr index 335b9877aa008..6ccee6a6262b9 100644 --- a/tests/ui/intrinsics/const-eval-select-stability.stderr +++ b/tests/ui/intrinsics/const-eval-select-stability.stderr @@ -1,10 +1,19 @@ -error: `const_eval_select` is not yet stable as a const fn +error: const-stable function cannot use `#[feature(const_eval_select)]` --> $DIR/const-eval-select-stability.rs:17:5 | LL | const_eval_select((), nothing, log); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions +help: if it is not part of the public API, make this function unstably const + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | pub const unsafe fn hey() { + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(const_eval_select)] +LL | pub const unsafe fn hey() { + | error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs index 31ca9419589cb..4e99d5f48d942 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs @@ -51,11 +51,11 @@ pub const fn const_context_not_const_stable() { #[rustc_const_stable(feature = "cheese", since = "1.0.0")] const fn stable_const_context() { Unstable::func(); - //~^ ERROR not yet stable as a const fn + //~^ ERROR const-stable function cannot use `#[feature(unstable)]` Foo::func(); - //[unstable]~^ ERROR not yet stable as a const fn + //[unstable]~^ ERROR const-stable function cannot use `#[feature(foo)]` const_context_not_const_stable() - //[unstable]~^ ERROR not yet stable as a const fn + //[unstable]~^ ERROR const-stable function cannot use `#[feature(foo)]` } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr index c9ca15d5b565f..4bc028554481b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -14,29 +14,55 @@ LL | Foo::func(); | = help: add `#![feature(foo)]` to the crate attributes to enable -error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:53:5 +error: const-stable function cannot use `#[feature(unstable)]` + --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions +help: if it is not part of the public API, make this function unstably const + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const fn stable_const_context() { + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(unstable)] +LL | const fn stable_const_context() { + | -error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:55:5 +error: const-stable function cannot use `#[feature(foo)]` + --> $DIR/staged-api.rs:57:5 | LL | Foo::func(); | ^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions +help: if it is not part of the public API, make this function unstably const + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const fn stable_const_context() { + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(foo)] +LL | const fn stable_const_context() { + | -error: `const_context_not_const_stable` is not yet stable as a const fn - --> $DIR/staged-api.rs:57:5 +error: const-stable function cannot use `#[feature(foo)]` + --> $DIR/staged-api.rs:59:5 | LL | const_context_not_const_stable() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions +help: if it is not part of the public API, make this function unstably const + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const fn stable_const_context() { + | +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + | +LL + #[rustc_allow_const_fn_unstable(foo)] +LL | const fn stable_const_context() { + | error: aborting due to 5 previous errors -