Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stabilize const_collections_with_hasher and build_hasher_default_const_new #133696

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
24 changes: 23 additions & 1 deletion library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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. **A `HashMap` constructed this
/// way is 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")]
Expand Down Expand Up @@ -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) }
}
Expand Down
24 changes: 23 additions & 1 deletion library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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. **A `HashSet` constructed this
/// way is 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> {
Expand Down Expand Up @@ -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) }
}
Expand Down
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading