about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-03-14 01:37:30 -0400
committerGitHub <noreply@github.com>2025-03-14 01:37:30 -0400
commit936e51ee12359d763529d2986324d4b671e6cdf1 (patch)
treeffc2b45486adb89c87bbdfe0d9724f6fe32b1161
parent6ae5c8df1d29dd763000d5b769e8a71181af7056 (diff)
parent4e703f582528aa17301090925e4ead6dae841099 (diff)
downloadrust-936e51ee12359d763529d2986324d4b671e6cdf1.tar.gz
rust-936e51ee12359d763529d2986324d4b671e6cdf1.zip
Rollup merge of #137870 - karolzwolak:lazylock-const-hashmaps-137566, r=cuviper
 Improve HashMap docs for const and static initializers

Closes #137566.
I clarified the HashMap usage in const and static initializers.
I also added examples of how to construct such HashMaps wrapped in LazyLock.
-rw-r--r--library/std/src/collections/hash/map.rs26
1 files changed, 19 insertions, 7 deletions
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index daba918af82..2487f5a2a50 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -208,20 +208,32 @@ use crate::ops::Index;
 /// # 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. **A `HashMap` constructed this
-/// way is not resistant against HashDoS!**
+/// which means that `HashMap::new` normally cannot be used in a `const` or `static` initializer.
 ///
+/// However, if you need to use a `HashMap` in a `const` or `static` initializer while retaining
+/// random seed generation, you can wrap the `HashMap` in [`LazyLock`].
+///
+/// Alternatively, you can construct a `HashMap` in a `const` or `static` initializer using a different
+/// hasher that does not rely on a random seed. **Be aware that a `HashMap` created this way is not
+/// resistant to HashDoS attacks!**
+///
+/// [`LazyLock`]: crate::sync::LazyLock
 /// ```rust
 /// use std::collections::HashMap;
 /// use std::hash::{BuildHasherDefault, DefaultHasher};
-/// use std::sync::Mutex;
+/// use std::sync::{LazyLock, Mutex};
 ///
-/// const EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> =
+/// // HashMaps with a fixed, non-random hasher
+/// const NONRANDOM_EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> =
 ///     HashMap::with_hasher(BuildHasherDefault::new());
-/// static MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> =
+/// static NONRANDOM_MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> =
 ///     Mutex::new(HashMap::with_hasher(BuildHasherDefault::new()));
+///
+/// // HashMaps using LazyLock to retain random seeding
+/// const RANDOM_EMPTY_MAP: LazyLock<HashMap<String, Vec<i32>>> =
+///     LazyLock::new(HashMap::new);
+/// static RANDOM_MAP: LazyLock<Mutex<HashMap<String, Vec<i32>>>> =
+///     LazyLock::new(|| Mutex::new(HashMap::new()));
 /// ```
 
 #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")]