diff options
| author | Ralf Jung <post@ralfj.de> | 2024-12-01 10:39:09 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-12-02 16:34:39 +0100 |
| commit | 3a9bc76f809634b0ae9844147766818a1bdcd32b (patch) | |
| tree | 5e18a69f102fbc4e9108d158257d8de28669c13b | |
| parent | 3bff51ea912d4dfd9caa1e3bc6f68352618208a7 (diff) | |
| download | rust-3a9bc76f809634b0ae9844147766818a1bdcd32b.tar.gz rust-3a9bc76f809634b0ae9844147766818a1bdcd32b.zip | |
stabilize const_collections_with_hasher and build_hasher_default_const_new
| -rw-r--r-- | library/core/src/hash/mod.rs | 6 | ||||
| -rw-r--r-- | library/std/src/collections/hash/map.rs | 24 | ||||
| -rw-r--r-- | library/std/src/collections/hash/set.rs | 24 | ||||
| -rw-r--r-- | 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 061690e88dd..84bbf985e8b 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -752,10 +752,10 @@ pub struct BuildHasherDefault<H>(marker::PhantomData<fn() -> H>); impl<H> BuildHasherDefault<H> { /// 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 09c0b61fb2b..59dcdfd08cb 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<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> = +/// HashMap::with_hasher(BuildHasherDefault::new()); +/// static MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> = +/// 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<K, V, S> HashMap<K, V, S> { /// ``` #[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<K, V, S> { 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 21a73259f61..2a481dbaa62 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<String, BuildHasherDefault<DefaultHasher>> = +/// HashSet::with_hasher(BuildHasherDefault::new()); +/// static SET: Mutex<HashSet<String, BuildHasherDefault<DefaultHasher>>> = +/// 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<T, S = RandomState> { @@ -369,7 +388,10 @@ impl<T, S> HashSet<T, S> { /// ``` #[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<T, S> { HashSet { base: base::HashSet::with_hasher(hasher) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 143878170f0..585946c1d50 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)] |
