diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index f926da464e1c6..1b579052d1fba 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -385,7 +385,9 @@ const_eval_unreachable_unwind = const_eval_unsigned_offset_from_overflow = `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: {$a_offset} < {$b_offset} const_eval_unsized_local = unsized locals are not supported + const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn +const_eval_unstable_declared_here = `{$def_path}` declared unstable here const_eval_unstable_in_stable = const-stable function cannot use `#[feature({$gate})]` diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index cc8f3387238d0..eb516e4d55926 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -129,6 +129,9 @@ pub(crate) struct UnstableConstFn { #[primary_span] pub span: Span, pub def_path: String, + + #[label(const_eval_unstable_declared_here)] + pub declared: Span, } #[derive(Diagnostic)] 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 135c99fefbc85..a3d09c5cc0c51 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -992,8 +992,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // `extern` functions, and these have no way to get marked `const`. So instead we // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const` if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) { - self.check_op(ops::FnCallUnstable(callee, None)); - return; + if !super::rustc_allow_const_fn_unstable(tcx, caller, sym::any) { + self.check_op(ops::FnCallUnstable(callee, None)); + return; + } } } trace!("permitting call"); 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 40183baccf8fe..2d4f8656a4cfc 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -339,10 +339,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let FnCallUnstable(def_id, feature) = *self; - let mut err = ccx - .tcx - .sess - .create_err(errors::UnstableConstFn { span, def_path: ccx.tcx.def_path_str(def_id) }); + let mut err = ccx.tcx.sess.create_err(errors::UnstableConstFn { + span, + def_path: ccx.tcx.def_path_str(def_id), + declared: ccx.tcx.def_span(def_id), + }); if ccx.is_const_stable_const_fn() { err.help("const-stable functions can only call other const-stable functions"); diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 4d109285d1645..995aab1362cc9 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -282,7 +282,18 @@ impl HashMap { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[cfg_attr( + bootstrap, + rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575") + )] + #[cfg_attr( + not(bootstrap), + rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + ) + )] + #[rustc_allow_const_fn_unstable(any)] pub const fn with_hasher(hash_builder: S) -> HashMap { HashMap { base: base::HashMap::with_hasher(hash_builder) } } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 6a87f6e5f2dc5..57e780ac57be1 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -369,7 +369,18 @@ impl HashSet { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[cfg_attr( + bootstrap, + rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575") + )] + #[cfg_attr( + not(bootstrap), + rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + ) + )] + #[rustc_allow_const_fn_unstable(any)] pub const fn with_hasher(hasher: S) -> HashSet { HashSet { base: base::HashSet::with_hasher(hasher) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f57c8d4e7e282..f3aadf96c759f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -297,6 +297,7 @@ #![feature(no_sanitize)] #![feature(platform_intrinsics)] #![feature(prelude_import)] +#![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(staged_api)] @@ -308,6 +309,7 @@ // // Library features (core): // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(const_collections_with_hasher))] #![feature(char_internals)] #![feature(core_intrinsics)] #![feature(duration_constants)] @@ -387,7 +389,6 @@ // // Only for const-ness: // tidy-alphabetical-start -#![feature(const_collections_with_hasher)] #![feature(const_hash)] #![feature(const_io_structs)] #![feature(const_ip)]