From c2984179d91654162fac32c60be6f9cec5d655cd Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2024 17:07:02 +0200
Subject: [PATCH] const fn stability checking: also check declared language
 features

---
 .../src/check_consts/check.rs                 |  4 +---
 compiler/rustc_middle/src/ty/context.rs       |  5 +----
 .../min_const_fn/const-fn-lang-feature.rs     | 20 +++++++++++++++++++
 3 files changed, 22 insertions(+), 7 deletions(-)
 create mode 100644 tests/ui/consts/min_const_fn/const-fn-lang-feature.rs

diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 6a086a3a7e5..7cfb101399d 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -868,9 +868,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     // Calling an unstable function *always* requires that the corresponding gate
                     // (or implied gate) be enabled, even if the function has
                     // `#[rustc_allow_const_fn_unstable(the_gate)]`.
-                    let gate_declared = |gate| {
-                        tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
-                    };
+                    let gate_declared = |gate| tcx.features().declared(gate);
                     let feature_gate_declared = gate_declared(gate);
                     let implied_gate_declared = implied_by.is_some_and(gate_declared);
                     if !feature_gate_declared && !implied_gate_declared {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index cad3515f068..5e0f753d2dc 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3089,10 +3089,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 Some(stability) if stability.is_const_unstable() => {
                     // has a `rustc_const_unstable` attribute, check whether the user enabled the
                     // corresponding feature gate.
-                    self.features()
-                        .declared_lib_features
-                        .iter()
-                        .any(|&(sym, _)| sym == stability.feature)
+                    self.features().declared(stability.feature)
                 }
                 // functions without const stability are either stable user written
                 // const fn or the user is using feature gates and we thus don't
diff --git a/tests/ui/consts/min_const_fn/const-fn-lang-feature.rs b/tests/ui/consts/min_const_fn/const-fn-lang-feature.rs
new file mode 100644
index 00000000000..63ef12085f1
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/const-fn-lang-feature.rs
@@ -0,0 +1,20 @@
+//! Ensure that we can use a language feature with a `const fn`:
+//! enabling the feature gate actually lets us call the function.
+//@ check-pass
+
+#![feature(staged_api, abi_unadjusted)]
+#![stable(feature = "rust_test", since = "1.0.0")]
+
+#[unstable(feature = "abi_unadjusted", issue = "42")]
+#[rustc_const_unstable(feature = "abi_unadjusted", issue = "42")]
+const fn my_fun() {}
+
+#[unstable(feature = "abi_unadjusted", issue = "42")]
+#[rustc_const_unstable(feature = "abi_unadjusted", issue = "42")]
+const fn my_fun2() {
+    my_fun()
+}
+
+fn main() {
+    const { my_fun2() };
+}