From ec12feaf5717e2c67011c54ee45bbc2511162bf8 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 29 Nov 2023 00:20:56 +0000 Subject: [PATCH 1/4] const_eval: Allow std to stabley call const fns from deps. Because std's dependencies are build with `-Zforce-unstable-if-unmarked` normally, std is unable to call them in const-stable function. However, becuase they had no explicit feature gates, there was no way to use `rustc_allow_const_fn_unstable` to allow this. Therefor we add `#[rustc_allow_const_fn_unstable(any)]` to allow using these functions. The reson to do this is #102575, which relies on calling hashbrow function in const-stable std functions. --- .../src/transform/check_consts/check.rs | 4 +++- .../auxiliary/normal-const-fn.rs | 6 +++++ .../const-stable-cross-crate.rs | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/ui/stability-attribute/auxiliary/normal-const-fn.rs create mode 100644 tests/ui/stability-attribute/const-stable-cross-crate.rs 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 13742ad273b59..481afb2237813 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -986,7 +986,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // should be fixed later. let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none() && tcx.lookup_stability(callee).is_some_and(|s| s.is_unstable()); - if callee_is_unstable_unmarked { + let can_call_any_function = + super::rustc_allow_const_fn_unstable(tcx, caller, sym::any); + if callee_is_unstable_unmarked && !can_call_any_function { trace!("callee_is_unstable_unmarked"); // We do not use `const` modifiers for intrinsic "functions", as intrinsics are // `extern` functions, and these have no way to get marked `const`. So instead we diff --git a/tests/ui/stability-attribute/auxiliary/normal-const-fn.rs b/tests/ui/stability-attribute/auxiliary/normal-const-fn.rs new file mode 100644 index 0000000000000..222063a55f887 --- /dev/null +++ b/tests/ui/stability-attribute/auxiliary/normal-const-fn.rs @@ -0,0 +1,6 @@ +// compile-flags: -Zforce-unstable-if-unmarked + +// This emulates a dep-of-std (eg hashbrown), that has const functions it +// cannot mark as stable, and is build with force-unstable-if-unmarked. + +pub const fn do_something_else() {} diff --git a/tests/ui/stability-attribute/const-stable-cross-crate.rs b/tests/ui/stability-attribute/const-stable-cross-crate.rs new file mode 100644 index 0000000000000..a45019c12476f --- /dev/null +++ b/tests/ui/stability-attribute/const-stable-cross-crate.rs @@ -0,0 +1,22 @@ +// aux-build:normal-const-fn.rs +// check-pass +#![crate_type = "lib"] +#![feature(staged_api)] +#![feature(rustc_attrs)] +#![feature(rustc_private)] +#![allow(internal_features)] +#![feature(rustc_allow_const_fn_unstable)] +#![stable(feature = "stable_feature", since = "1.0.0")] + +extern crate normal_const_fn; + +// This ensures std can call const functions in it's deps that don't have +// access to rustc_const_stable annotations (and hense don't have a feature) +// gate. + +#[rustc_const_stable(feature = "stable_feature", since = "1.0.0")] +#[stable(feature = "stable_feature", since = "1.0.0")] +#[rustc_allow_const_fn_unstable(any)] +pub const fn do_something() { + normal_const_fn::do_something_else() +} From 9318d0ad1b932fea1e98f9a1f48e860bb1b1ece1 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 29 Nov 2023 00:26:45 +0000 Subject: [PATCH 2/4] const-stabilize HashMap/HashSet::with_hasher This needs to be `cfg(bootstrap)`ed, because we rely on `#[rustc_allow_const_fn_unstable(any)]`, which was introduced in the previous commit. --- library/std/src/collections/hash/map.rs | 13 ++++++++++++- library/std/src/collections/hash/set.rs | 13 ++++++++++++- library/std/src/lib.rs | 3 ++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 39e94902cfe5f..de4d3f02b77e3 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -279,7 +279,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 8bc5960829066..7dff64198b8e2 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 d06012c14dcfe..26c8f63ceea61 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)] @@ -388,7 +389,7 @@ // // Only for const-ness: // tidy-alphabetical-start -#![feature(const_collections_with_hasher)] +#![cfg_attr(bootstrap, feature(const_collections_with_hasher))] #![feature(const_hash)] #![feature(const_io_structs)] #![feature(const_ip)] From f4136ebc00672f0f74e6a65747496eda575bb0a7 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 1 Dec 2023 15:06:41 +0000 Subject: [PATCH 3/4] `any` -> `any_unmarked` for `rustc_allow_const_fn_unstable` --- .../rustc_const_eval/src/transform/check_consts/check.rs | 6 +++--- compiler/rustc_span/src/symbol.rs | 1 + library/std/src/collections/hash/map.rs | 2 +- library/std/src/collections/hash/set.rs | 2 +- tests/ui/stability-attribute/const-stable-cross-crate.rs | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) 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 481afb2237813..d64bd2d98892d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -986,9 +986,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // should be fixed later. let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none() && tcx.lookup_stability(callee).is_some_and(|s| s.is_unstable()); - let can_call_any_function = - super::rustc_allow_const_fn_unstable(tcx, caller, sym::any); - if callee_is_unstable_unmarked && !can_call_any_function { + let can_call_unmarked_function = + super::rustc_allow_const_fn_unstable(tcx, caller, sym::any_unmarked); + if callee_is_unstable_unmarked && !can_call_unmarked_function { trace!("callee_is_unstable_unmarked"); // We do not use `const` modifiers for intrinsic "functions", as intrinsics are // `extern` functions, and these have no way to get marked `const`. So instead we diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 40b0387424221..4aea5da7d9bb8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -397,6 +397,7 @@ symbols! { anon, anonymous_lifetime_in_impl_trait, any, + any_unmarked, append_const_msg, arbitrary_enum_discriminant, arbitrary_self_types, diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index de4d3f02b77e3..2c7650503df38 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -290,7 +290,7 @@ impl HashMap { since = "CURRENT_RUSTC_VERSION" ) )] - #[rustc_allow_const_fn_unstable(any)] + #[rustc_allow_const_fn_unstable(any_unmarked)] 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 7dff64198b8e2..4bd04bfe4d5d3 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -380,7 +380,7 @@ impl HashSet { since = "CURRENT_RUSTC_VERSION" ) )] - #[rustc_allow_const_fn_unstable(any)] + #[rustc_allow_const_fn_unstable(any_unmarked)] pub const fn with_hasher(hasher: S) -> HashSet { HashSet { base: base::HashSet::with_hasher(hasher) } } diff --git a/tests/ui/stability-attribute/const-stable-cross-crate.rs b/tests/ui/stability-attribute/const-stable-cross-crate.rs index a45019c12476f..d102979dd7d5d 100644 --- a/tests/ui/stability-attribute/const-stable-cross-crate.rs +++ b/tests/ui/stability-attribute/const-stable-cross-crate.rs @@ -16,7 +16,7 @@ extern crate normal_const_fn; #[rustc_const_stable(feature = "stable_feature", since = "1.0.0")] #[stable(feature = "stable_feature", since = "1.0.0")] -#[rustc_allow_const_fn_unstable(any)] +#[rustc_allow_const_fn_unstable(any_unmarked)] pub const fn do_something() { normal_const_fn::do_something_else() } From ec8f6af88c02fb830a6966e9a378f2890d852fa6 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 1 Dec 2023 15:54:26 +0000 Subject: [PATCH 4/4] Add test for calling const-unstable function with `-Zforce-unstable-if-unmarked` --- .../auxiliary/const-unstable.rs | 8 ++++++++ .../const-unstable-from-unmarked.rs | 16 ++++++++++++++++ .../const-unstable-from-unmarked.stderr | 10 ++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/ui/stability-attribute/auxiliary/const-unstable.rs create mode 100644 tests/ui/stability-attribute/const-unstable-from-unmarked.rs create mode 100644 tests/ui/stability-attribute/const-unstable-from-unmarked.stderr diff --git a/tests/ui/stability-attribute/auxiliary/const-unstable.rs b/tests/ui/stability-attribute/auxiliary/const-unstable.rs new file mode 100644 index 0000000000000..86d159c7c32a1 --- /dev/null +++ b/tests/ui/stability-attribute/auxiliary/const-unstable.rs @@ -0,0 +1,8 @@ +#![feature(staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_identity", issue = "1")] +pub const fn identity(x: i32) -> i32 { + x +} diff --git a/tests/ui/stability-attribute/const-unstable-from-unmarked.rs b/tests/ui/stability-attribute/const-unstable-from-unmarked.rs new file mode 100644 index 0000000000000..006768de95ed6 --- /dev/null +++ b/tests/ui/stability-attribute/const-unstable-from-unmarked.rs @@ -0,0 +1,16 @@ +// aux-build: const-unstable.rs +// compile-flags: -Zforce-unstable-if-unmarked +#![crate_type = "lib"] +extern crate const_unstable; + +// Check that crates build with `-Zforce-unstable-if-unmarked` can't call +// const-unstable functions, despite their functions sometimes being considerd +// unstable. +// +// See https://github.com/rust-lang/rust/pull/118427#discussion_r1409914941 for +// more context. + +pub const fn identity(x: i32) -> i32 { + const_unstable::identity(x) + //~^ ERROR `const_unstable::identity` is not yet stable as a const fn +} diff --git a/tests/ui/stability-attribute/const-unstable-from-unmarked.stderr b/tests/ui/stability-attribute/const-unstable-from-unmarked.stderr new file mode 100644 index 0000000000000..320fa210bfba8 --- /dev/null +++ b/tests/ui/stability-attribute/const-unstable-from-unmarked.stderr @@ -0,0 +1,10 @@ +error: `const_unstable::identity` is not yet stable as a const fn + --> $DIR/const-unstable-from-unmarked.rs:14:5 + | +LL | const_unstable::identity(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(const_identity)]` to the crate attributes to enable + +error: aborting due to 1 previous error +