diff options
| author | Jacob Pratt <jacob@jhpratt.dev> | 2025-03-14 01:37:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-14 01:37:30 -0400 |
| commit | 936e51ee12359d763529d2986324d4b671e6cdf1 (patch) | |
| tree | ffc2b45486adb89c87bbdfe0d9724f6fe32b1161 | |
| parent | 6ae5c8df1d29dd763000d5b769e8a71181af7056 (diff) | |
| parent | 4e703f582528aa17301090925e4ead6dae841099 (diff) | |
| download | rust-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.rs | 26 |
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")] |
