From 3a9bc76f809634b0ae9844147766818a1bdcd32b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 1 Dec 2024 10:39:09 +0100 Subject: [PATCH 1/2] stabilize const_collections_with_hasher and build_hasher_default_const_new --- library/core/src/hash/mod.rs | 6 +++--- library/std/src/collections/hash/map.rs | 24 +++++++++++++++++++++++- library/std/src/collections/hash/set.rs | 24 +++++++++++++++++++++++- library/std/src/lib.rs | 1 - 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 061690e88ddf8..84bbf985e8be4 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -752,10 +752,10 @@ pub struct BuildHasherDefault(marker::PhantomData H>); impl BuildHasherDefault { /// Creates a new BuildHasherDefault for Hasher `H`. - #[unstable( + #[stable(feature = "build_hasher_default_const_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable( feature = "build_hasher_default_const_new", - issue = "123197", - reason = "recently added" + since = "CURRENT_RUSTC_VERSION" )] pub const fn new() -> Self { BuildHasherDefault(marker::PhantomData) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 09c0b61fb2b89..59dcdfd08cb3c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -204,6 +204,25 @@ use crate::ops::Index; /// println!("{viking:?} has {health} hp"); /// } /// ``` +/// +/// # Usage in `const` and `static` +/// +/// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed, +/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **`HashMap` constructed this +/// way are not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashMap; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_MAP: HashMap, BuildHasherDefault> = +/// HashMap::with_hasher(BuildHasherDefault::new()); +/// static MAP: Mutex, BuildHasherDefault>> = +/// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")] #[stable(feature = "rust1", since = "1.0.0")] @@ -277,7 +296,10 @@ impl HashMap { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + )] 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 21a73259f6179..2a481dbaa6271 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -101,6 +101,25 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// [`HashMap`]: crate::collections::HashMap /// [`RefCell`]: crate::cell::RefCell /// [`Cell`]: crate::cell::Cell +/// +/// # Usage in `const` and `static` +/// +/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed, +/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **`HashSet` constructed this +/// way are not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashSet; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_SET: HashSet> = +/// HashSet::with_hasher(BuildHasherDefault::new()); +/// static SET: Mutex>> = +/// Mutex::new(HashSet::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")] #[stable(feature = "rust1", since = "1.0.0")] pub struct HashSet { @@ -369,7 +388,10 @@ impl HashSet { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + )] 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 143878170f087..585946c1d50e0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -320,7 +320,6 @@ // Library features (core): // tidy-alphabetical-start #![feature(array_chunks)] -#![feature(build_hasher_default_const_new)] #![feature(c_str_module)] #![feature(char_internals)] #![feature(clone_to_uninit)] From 7ac7b4c285d3130af463ce27584e2a4c08abf500 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 1 Dec 2024 11:31:12 +0100 Subject: [PATCH 2/2] ./x miri: fix sysroot build --- library/std/src/collections/hash/map.rs | 4 ++-- library/std/src/collections/hash/set.rs | 4 ++-- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 59dcdfd08cb3c..109bc3946346f 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -210,8 +210,8 @@ use crate::ops::Index; /// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed, /// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the /// initializer of a `const` or `static` item, you will have to use a different hasher that does not -/// involve a random seed, as demonstrated in the following example. **`HashMap` constructed this -/// way are not resistant against HashDoS!** +/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this +/// way is not resistant against HashDoS!** /// /// ```rust /// use std::collections::HashMap; diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 2a481dbaa6271..4c81aaff45886 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -107,8 +107,8 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed, /// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the /// initializer of a `const` or `static` item, you will have to use a different hasher that does not -/// involve a random seed, as demonstrated in the following example. **`HashSet` constructed this -/// way are not resistant against HashDoS!** +/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this +/// way is not resistant against HashDoS!** /// /// ```rust /// use std::collections::HashSet; diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 4fa91c1a57144..161157acffe0e 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2756,6 +2756,10 @@ impl Step for Crate { // `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that // instead. But crucially we only do that for the library, not the test builds. cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1"); + // std needs to be built with `-Zforce-unstable-if-unmarked`. For some reason the builder + // does not set this directly, but relies on the rustc wrapper to set it, and we are not using + // the wrapper -- hence we have to set it ourselves. + cargo.rustflag("-Zforce-unstable-if-unmarked"); cargo } else { // Also prepare a sysroot for the target.