diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 738bb5e8b19..b26f98769c1 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -7,8 +7,7 @@ use rustc_hir::def_id::DefId;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::abi;
 use std::borrow::Cow;
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
 use std::path::PathBuf;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f745bc390ca..add40b83d21 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3178,9 +3178,8 @@ pub(crate) mod dep_tracking {
     use rustc_target::spec::{
         RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
     };
-    use std::collections::hash_map::DefaultHasher;
     use std::collections::BTreeMap;
-    use std::hash::Hash;
+    use std::hash::{DefaultHasher, Hash};
     use std::num::NonZeroUsize;
     use std::path::PathBuf;
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index ed00851b468..76d69646f1d 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -19,8 +19,7 @@ use rustc_span::SourceFileHashAlgorithm;
 
 use std::collections::BTreeMap;
 
-use std::collections::hash_map::DefaultHasher;
-use std::hash::Hasher;
+use std::hash::{DefaultHasher, Hasher};
 use std::num::{IntErrorKind, NonZeroUsize};
 use std::path::PathBuf;
 use std::str;
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f04799482c8..d8dd4ae2286 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -3503,7 +3503,7 @@ impl TargetTriple {
     /// If this target is a path, a hash of the path is appended to the triple returned
     /// by `triple()`.
     pub fn debug_triple(&self) -> String {
-        use std::collections::hash_map::DefaultHasher;
+        use std::hash::DefaultHasher;
 
         match self {
             TargetTriple::TargetTriple(triple) => triple.to_owned(),
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index d33c4418e1b..f07c76232eb 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -270,7 +270,7 @@ pub(crate) mod test_helpers {
     /// seed not being the same for every RNG invocation too.
     pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
         use std::hash::{BuildHasher, Hash, Hasher};
-        let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
+        let mut hasher = std::hash::RandomState::new().build_hasher();
         std::panic::Location::caller().hash(&mut hasher);
         let hc64 = hasher.finish();
         let seed_vec =
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 6c78d65f1c9..ea7d6f6f4a6 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2706,7 +2706,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
 /// ```
 /// use std::hash::BuildHasher;
 ///
-/// let b = std::collections::hash_map::RandomState::new();
+/// let b = std::hash::RandomState::new();
 /// let v: Vec<u8> = vec![0xa8, 0x3c, 0x09];
 /// let s: &[u8] = &[0xa8, 0x3c, 0x09];
 /// assert_eq!(b.hash_one(v), b.hash_one(s));
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index aa7a331b368..6d5c17ef023 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -43,8 +43,7 @@
 #![deny(fuzzy_provenance_casts)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
 
 mod arc;
 mod autotraits;
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index ebd4a8c05fe..9c8d7bbd999 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -297,7 +297,7 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
 /// ```
 /// use std::hash::BuildHasher;
 ///
-/// let b = std::collections::hash_map::RandomState::new();
+/// let b = std::hash::RandomState::new();
 /// let a: [u8; 3] = [0xa8, 0x3c, 0x09];
 /// let s: &[u8] = &[0xa8, 0x3c, 0x09];
 /// assert_eq!(b.hash_one(a), b.hash_one(s));
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 35b757dc1ee..153971a59c5 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -12,8 +12,7 @@
 //! # Examples
 //!
 //! ```rust
-//! use std::collections::hash_map::DefaultHasher;
-//! use std::hash::{Hash, Hasher};
+//! use std::hash::{DefaultHasher, Hash, Hasher};
 //!
 //! #[derive(Hash)]
 //! struct Person {
@@ -46,8 +45,7 @@
 //! the [`Hash`] trait:
 //!
 //! ```rust
-//! use std::collections::hash_map::DefaultHasher;
-//! use std::hash::{Hash, Hasher};
+//! use std::hash::{DefaultHasher, Hash, Hasher};
 //!
 //! struct Person {
 //!     id: u32,
@@ -194,8 +192,7 @@ pub trait Hash {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::hash_map::DefaultHasher;
-    /// use std::hash::{Hash, Hasher};
+    /// use std::hash::{DefaultHasher, Hash, Hasher};
     ///
     /// let mut hasher = DefaultHasher::new();
     /// 7920.hash(&mut hasher);
@@ -224,8 +221,7 @@ pub trait Hash {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::hash_map::DefaultHasher;
-    /// use std::hash::{Hash, Hasher};
+    /// use std::hash::{DefaultHasher, Hash, Hasher};
     ///
     /// let mut hasher = DefaultHasher::new();
     /// let numbers = [6, 28, 496, 8128];
@@ -300,8 +296,7 @@ pub use macros::Hash;
 /// # Examples
 ///
 /// ```
-/// use std::collections::hash_map::DefaultHasher;
-/// use std::hash::Hasher;
+/// use std::hash::{DefaultHasher, Hasher};
 ///
 /// let mut hasher = DefaultHasher::new();
 ///
@@ -329,8 +324,7 @@ pub trait Hasher {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::hash_map::DefaultHasher;
-    /// use std::hash::Hasher;
+    /// use std::hash::{DefaultHasher, Hasher};
     ///
     /// let mut hasher = DefaultHasher::new();
     /// hasher.write(b"Cool!");
@@ -347,8 +341,7 @@ pub trait Hasher {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::hash_map::DefaultHasher;
-    /// use std::hash::Hasher;
+    /// use std::hash::{DefaultHasher, Hasher};
     ///
     /// let mut hasher = DefaultHasher::new();
     /// let data = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
@@ -627,8 +620,7 @@ impl<H: Hasher + ?Sized> Hasher for &mut H {
 /// # Examples
 ///
 /// ```
-/// use std::collections::hash_map::RandomState;
-/// use std::hash::{BuildHasher, Hasher};
+/// use std::hash::{BuildHasher, Hasher, RandomState};
 ///
 /// let s = RandomState::new();
 /// let mut hasher_1 = s.build_hasher();
@@ -656,8 +648,7 @@ pub trait BuildHasher {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::hash_map::RandomState;
-    /// use std::hash::BuildHasher;
+    /// use std::hash::{BuildHasher, RandomState};
     ///
     /// let s = RandomState::new();
     /// let new_s = s.build_hasher();
@@ -690,7 +681,7 @@ pub trait BuildHasher {
     /// }
     ///
     /// // Then later, in a `#[test]` for the type...
-    /// let bh = std::collections::hash_map::RandomState::new();
+    /// let bh = std::hash::RandomState::new();
     /// assert_eq!(
     ///     bh.hash_one(OrderAmbivalentPair(1, 2)),
     ///     bh.hash_one(OrderAmbivalentPair(2, 1))
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 6b9f2e84257..78a232faaf8 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -14,7 +14,7 @@ use crate::ptr;
 ///
 /// See: <https://131002.net/siphash>
 #[unstable(feature = "hashmap_internals", issue = "none")]
-#[deprecated(since = "1.13.0", note = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
 #[derive(Debug, Clone, Default)]
 #[doc(hidden)]
 pub struct SipHasher13 {
@@ -25,7 +25,7 @@ pub struct SipHasher13 {
 ///
 /// See: <https://131002.net/siphash/>
 #[unstable(feature = "hashmap_internals", issue = "none")]
-#[deprecated(since = "1.13.0", note = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
 #[derive(Debug, Clone, Default)]
 struct SipHasher24 {
     hasher: Hasher<Sip24Rounds>,
@@ -44,7 +44,7 @@ struct SipHasher24 {
 /// it is not intended for cryptographic purposes. As such, all
 /// cryptographic uses of this implementation are _strongly discouraged_.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.13.0", note = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
 #[derive(Debug, Clone, Default)]
 pub struct SipHasher(SipHasher24);
 
@@ -147,10 +147,7 @@ impl SipHasher {
     /// Creates a new `SipHasher` with the two initial keys set to 0.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(
-        since = "1.13.0",
-        note = "use `std::collections::hash_map::DefaultHasher` instead"
-    )]
+    #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
     #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     #[must_use]
     pub const fn new() -> SipHasher {
@@ -160,10 +157,7 @@ impl SipHasher {
     /// Creates a `SipHasher` that is keyed off the provided keys.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(
-        since = "1.13.0",
-        note = "use `std::collections::hash_map::DefaultHasher` instead"
-    )]
+    #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
     #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     #[must_use]
     pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
@@ -175,10 +169,7 @@ impl SipHasher13 {
     /// Creates a new `SipHasher13` with the two initial keys set to 0.
     #[inline]
     #[unstable(feature = "hashmap_internals", issue = "none")]
-    #[deprecated(
-        since = "1.13.0",
-        note = "use `std::collections::hash_map::DefaultHasher` instead"
-    )]
+    #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
     #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     pub const fn new() -> SipHasher13 {
         SipHasher13::new_with_keys(0, 0)
@@ -187,10 +178,7 @@ impl SipHasher13 {
     /// Creates a `SipHasher13` that is keyed off the provided keys.
     #[inline]
     #[unstable(feature = "hashmap_internals", issue = "none")]
-    #[deprecated(
-        since = "1.13.0",
-        note = "use `std::collections::hash_map::DefaultHasher` instead"
-    )]
+    #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")]
     #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
         SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d71079dd09c..fc4943c2aa9 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1921,8 +1921,7 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
 /// # Examples
 ///
 /// ```
-/// use std::collections::hash_map::DefaultHasher;
-/// use std::hash::{Hash, Hasher};
+/// use std::hash::{DefaultHasher, Hash, Hasher};
 /// use std::ptr;
 ///
 /// let five = 5;
diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs
index 033bd1ed6ed..5268f32c031 100644
--- a/library/core/tests/hash/mod.rs
+++ b/library/core/tests/hash/mod.rs
@@ -167,7 +167,7 @@ fn test_indirect_hasher() {
 
 #[test]
 fn test_build_hasher_object_safe() {
-    use std::collections::hash_map::{DefaultHasher, RandomState};
+    use std::hash::{DefaultHasher, RandomState};
 
     let _: &dyn BuildHasher<Hasher = DefaultHasher> = &RandomState::new();
 }
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 168b47dc99c..c167240ba24 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -169,7 +169,7 @@ mod waker;
 #[allow(dead_code)] // Not used in all configurations.
 pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
     use core::hash::{BuildHasher, Hash, Hasher};
-    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
+    let mut hasher = std::hash::RandomState::new().build_hasher();
     core::panic::Location::caller().hash(&mut hasher);
     let hc64 = hasher.finish();
     let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 4d109285d16..39e94902cfe 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -6,16 +6,13 @@ use self::Entry::*;
 use hashbrown::hash_map as base;
 
 use crate::borrow::Borrow;
-use crate::cell::Cell;
 use crate::collections::TryReserveError;
 use crate::collections::TryReserveErrorKind;
 use crate::error::Error;
 use crate::fmt::{self, Debug};
-#[allow(deprecated)]
-use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
+use crate::hash::{BuildHasher, Hash, RandomState};
 use crate::iter::FusedIterator;
 use crate::ops::Index;
-use crate::sys;
 
 /// A [hash map] implemented with quadratic probing and SIMD lookup.
 ///
@@ -274,7 +271,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let s = RandomState::new();
     /// let mut map = HashMap::with_hasher(s);
@@ -306,7 +303,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let s = RandomState::new();
     /// let mut map = HashMap::with_capacity_and_hasher(10, s);
@@ -717,7 +714,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let hasher = RandomState::new();
     /// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
@@ -3072,152 +3069,6 @@ where
     }
 }
 
-/// `RandomState` is the default state for [`HashMap`] types.
-///
-/// A particular instance `RandomState` will create the same instances of
-/// [`Hasher`], but the hashers created by two different `RandomState`
-/// instances are unlikely to produce the same result for the same values.
-///
-/// # Examples
-///
-/// ```
-/// use std::collections::HashMap;
-/// use std::collections::hash_map::RandomState;
-///
-/// let s = RandomState::new();
-/// let mut map = HashMap::with_hasher(s);
-/// map.insert(1, 2);
-/// ```
-#[derive(Clone)]
-#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-pub struct RandomState {
-    k0: u64,
-    k1: u64,
-}
-
-impl RandomState {
-    /// Constructs a new `RandomState` that is initialized with random keys.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// ```
-    #[inline]
-    #[allow(deprecated)]
-    // rand
-    #[must_use]
-    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn new() -> RandomState {
-        // Historically this function did not cache keys from the OS and instead
-        // simply always called `rand::thread_rng().gen()` twice. In #31356 it
-        // was discovered, however, that because we re-seed the thread-local RNG
-        // from the OS periodically that this can cause excessive slowdown when
-        // many hash maps are created on a thread. To solve this performance
-        // trap we cache the first set of randomly generated keys per-thread.
-        //
-        // Later in #36481 it was discovered that exposing a deterministic
-        // iteration order allows a form of DOS attack. To counter that we
-        // increment one of the seeds on every RandomState creation, giving
-        // every corresponding HashMap a different iteration order.
-        thread_local!(static KEYS: Cell<(u64, u64)> = {
-            Cell::new(sys::hashmap_random_keys())
-        });
-
-        KEYS.with(|keys| {
-            let (k0, k1) = keys.get();
-            keys.set((k0.wrapping_add(1), k1));
-            RandomState { k0, k1 }
-        })
-    }
-}
-
-#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-impl BuildHasher for RandomState {
-    type Hasher = DefaultHasher;
-    #[inline]
-    #[allow(deprecated)]
-    fn build_hasher(&self) -> DefaultHasher {
-        DefaultHasher(SipHasher13::new_with_keys(self.k0, self.k1))
-    }
-}
-
-/// The default [`Hasher`] used by [`RandomState`].
-///
-/// The internal algorithm is not specified, and so it and its hashes should
-/// not be relied upon over releases.
-#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-#[allow(deprecated)]
-#[derive(Clone, Debug)]
-pub struct DefaultHasher(SipHasher13);
-
-impl DefaultHasher {
-    /// Creates a new `DefaultHasher`.
-    ///
-    /// This hasher is not guaranteed to be the same as all other
-    /// `DefaultHasher` instances, but is the same as all other `DefaultHasher`
-    /// instances created through `new` or `default`.
-    #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-    #[inline]
-    #[allow(deprecated)]
-    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
-    #[must_use]
-    pub const fn new() -> DefaultHasher {
-        DefaultHasher(SipHasher13::new_with_keys(0, 0))
-    }
-}
-
-#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-impl Default for DefaultHasher {
-    /// Creates a new `DefaultHasher` using [`new`].
-    /// See its documentation for more.
-    ///
-    /// [`new`]: DefaultHasher::new
-    #[inline]
-    fn default() -> DefaultHasher {
-        DefaultHasher::new()
-    }
-}
-
-#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-impl Hasher for DefaultHasher {
-    // The underlying `SipHasher13` doesn't override the other
-    // `write_*` methods, so it's ok not to forward them here.
-
-    #[inline]
-    fn write(&mut self, msg: &[u8]) {
-        self.0.write(msg)
-    }
-
-    #[inline]
-    fn write_str(&mut self, s: &str) {
-        self.0.write_str(s);
-    }
-
-    #[inline]
-    fn finish(&self) -> u64 {
-        self.0.finish()
-    }
-}
-
-#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-impl Default for RandomState {
-    /// Constructs a new `RandomState`.
-    #[inline]
-    fn default() -> RandomState {
-        RandomState::new()
-    }
-}
-
-#[stable(feature = "std_debug", since = "1.16.0")]
-impl fmt::Debug for RandomState {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("RandomState").finish_non_exhaustive()
-    }
-}
-
 #[inline]
 fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K, V> {
     match raw {
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 91a3776e7be..8585376abc1 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -1,8 +1,8 @@
 use super::Entry::{Occupied, Vacant};
 use super::HashMap;
-use super::RandomState;
 use crate::assert_matches::assert_matches;
 use crate::cell::RefCell;
+use crate::hash::RandomState;
 use crate::test_helpers::test_rng;
 use rand::Rng;
 use realstd::collections::TryReserveErrorKind::*;
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 6a87f6e5f2d..8bc59608290 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -6,11 +6,11 @@ use hashbrown::hash_set as base;
 use crate::borrow::Borrow;
 use crate::collections::TryReserveError;
 use crate::fmt;
-use crate::hash::{BuildHasher, Hash};
+use crate::hash::{BuildHasher, Hash, RandomState};
 use crate::iter::{Chain, FusedIterator};
 use crate::ops::{BitAnd, BitOr, BitXor, Sub};
 
-use super::map::{map_try_reserve_error, RandomState};
+use super::map::map_try_reserve_error;
 
 /// A [hash set] implemented as a `HashMap` where the value is `()`.
 ///
@@ -361,7 +361,7 @@ impl<T, S> HashSet<T, S> {
     ///
     /// ```
     /// use std::collections::HashSet;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let s = RandomState::new();
     /// let mut set = HashSet::with_hasher(s);
@@ -393,7 +393,7 @@ impl<T, S> HashSet<T, S> {
     ///
     /// ```
     /// use std::collections::HashSet;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let s = RandomState::new();
     /// let mut set = HashSet::with_capacity_and_hasher(10, s);
@@ -411,7 +411,7 @@ impl<T, S> HashSet<T, S> {
     ///
     /// ```
     /// use std::collections::HashSet;
-    /// use std::collections::hash_map::RandomState;
+    /// use std::hash::RandomState;
     ///
     /// let hasher = RandomState::new();
     /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
index e0cd80b44f8..208f61e755c 100644
--- a/library/std/src/collections/hash/set/tests.rs
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -1,6 +1,6 @@
-use super::super::map::RandomState;
 use super::HashSet;
 
+use crate::hash::RandomState;
 use crate::panic::{catch_unwind, AssertUnwindSafe};
 use crate::sync::atomic::{AtomicU32, Ordering};
 use crate::sync::Arc;
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index 42f738acb9f..1389d24a8c5 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -439,6 +439,11 @@ pub mod hash_map {
     //! A hash map implemented with quadratic probing and SIMD lookup.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::hash::map::*;
+
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub use crate::hash::random::DefaultHasher;
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub use crate::hash::random::RandomState;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/hash/mod.rs b/library/std/src/hash/mod.rs
new file mode 100644
index 00000000000..bd9bbf29875
--- /dev/null
+++ b/library/std/src/hash/mod.rs
@@ -0,0 +1,91 @@
+//! Generic hashing support.
+//!
+//! This module provides a generic way to compute the [hash] of a value.
+//! Hashes are most commonly used with [`HashMap`] and [`HashSet`].
+//!
+//! [hash]: https://en.wikipedia.org/wiki/Hash_function
+//! [`HashMap`]: ../../std/collections/struct.HashMap.html
+//! [`HashSet`]: ../../std/collections/struct.HashSet.html
+//!
+//! The simplest way to make a type hashable is to use `#[derive(Hash)]`:
+//!
+//! # Examples
+//!
+//! ```rust
+//! use std::hash::{DefaultHasher, Hash, Hasher};
+//!
+//! #[derive(Hash)]
+//! struct Person {
+//!     id: u32,
+//!     name: String,
+//!     phone: u64,
+//! }
+//!
+//! let person1 = Person {
+//!     id: 5,
+//!     name: "Janet".to_string(),
+//!     phone: 555_666_7777,
+//! };
+//! let person2 = Person {
+//!     id: 5,
+//!     name: "Bob".to_string(),
+//!     phone: 555_666_7777,
+//! };
+//!
+//! assert!(calculate_hash(&person1) != calculate_hash(&person2));
+//!
+//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
+//!     let mut s = DefaultHasher::new();
+//!     t.hash(&mut s);
+//!     s.finish()
+//! }
+//! ```
+//!
+//! If you need more control over how a value is hashed, you need to implement
+//! the [`Hash`] trait:
+//!
+//! ```rust
+//! use std::hash::{DefaultHasher, Hash, Hasher};
+//!
+//! struct Person {
+//!     id: u32,
+//!     # #[allow(dead_code)]
+//!     name: String,
+//!     phone: u64,
+//! }
+//!
+//! impl Hash for Person {
+//!     fn hash<H: Hasher>(&self, state: &mut H) {
+//!         self.id.hash(state);
+//!         self.phone.hash(state);
+//!     }
+//! }
+//!
+//! let person1 = Person {
+//!     id: 5,
+//!     name: "Janet".to_string(),
+//!     phone: 555_666_7777,
+//! };
+//! let person2 = Person {
+//!     id: 5,
+//!     name: "Bob".to_string(),
+//!     phone: 555_666_7777,
+//! };
+//!
+//! assert_eq!(calculate_hash(&person1), calculate_hash(&person2));
+//!
+//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
+//!     let mut s = DefaultHasher::new();
+//!     t.hash(&mut s);
+//!     s.finish()
+//! }
+//! ```
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub(crate) mod random;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::hash::*;
+
+#[stable(feature = "std_hash_exports", since = "CURRENT_RUSTC_VERSION")]
+pub use self::random::{DefaultHasher, RandomState};
diff --git a/library/std/src/hash/random.rs b/library/std/src/hash/random.rs
new file mode 100644
index 00000000000..a1ccbb25369
--- /dev/null
+++ b/library/std/src/hash/random.rs
@@ -0,0 +1,161 @@
+//! This module exists to isolate [`RandomState`] and [`DefaultHasher`] outside of the
+//! [`collections`] module without actually publicly exporting them, so that parts of that
+//! implementation can more easily be moved to the [`alloc`] crate.
+//!
+//! Although its items are public and contain stability attributes, they can't actually be accessed
+//! outside this crate.
+//!
+//! [`collections`]: crate::collections
+#[allow(deprecated)]
+use super::{BuildHasher, Hasher, SipHasher13};
+use crate::cell::Cell;
+use crate::fmt;
+use crate::sys;
+
+/// `RandomState` is the default state for [`HashMap`] types.
+///
+/// A particular instance `RandomState` will create the same instances of
+/// [`Hasher`], but the hashers created by two different `RandomState`
+/// instances are unlikely to produce the same result for the same values.
+///
+/// [`HashMap`]: crate::collections::HashMap
+///
+/// # Examples
+///
+/// ```
+/// use std::collections::HashMap;
+/// use std::hash::RandomState;
+///
+/// let s = RandomState::new();
+/// let mut map = HashMap::with_hasher(s);
+/// map.insert(1, 2);
+/// ```
+#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+#[derive(Clone)]
+pub struct RandomState {
+    k0: u64,
+    k1: u64,
+}
+
+impl RandomState {
+    /// Constructs a new `RandomState` that is initialized with random keys.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::hash::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// ```
+    #[inline]
+    #[allow(deprecated)]
+    // rand
+    #[must_use]
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub fn new() -> RandomState {
+        // Historically this function did not cache keys from the OS and instead
+        // simply always called `rand::thread_rng().gen()` twice. In #31356 it
+        // was discovered, however, that because we re-seed the thread-local RNG
+        // from the OS periodically that this can cause excessive slowdown when
+        // many hash maps are created on a thread. To solve this performance
+        // trap we cache the first set of randomly generated keys per-thread.
+        //
+        // Later in #36481 it was discovered that exposing a deterministic
+        // iteration order allows a form of DOS attack. To counter that we
+        // increment one of the seeds on every RandomState creation, giving
+        // every corresponding HashMap a different iteration order.
+        thread_local!(static KEYS: Cell<(u64, u64)> = {
+            Cell::new(sys::hashmap_random_keys())
+        });
+
+        KEYS.with(|keys| {
+            let (k0, k1) = keys.get();
+            keys.set((k0.wrapping_add(1), k1));
+            RandomState { k0, k1 }
+        })
+    }
+}
+
+#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+impl BuildHasher for RandomState {
+    type Hasher = DefaultHasher;
+    #[inline]
+    #[allow(deprecated)]
+    fn build_hasher(&self) -> DefaultHasher {
+        DefaultHasher(SipHasher13::new_with_keys(self.k0, self.k1))
+    }
+}
+
+/// The default [`Hasher`] used by [`RandomState`].
+///
+/// The internal algorithm is not specified, and so it and its hashes should
+/// not be relied upon over releases.
+#[allow(deprecated)]
+#[derive(Clone, Debug)]
+#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+pub struct DefaultHasher(SipHasher13);
+
+impl DefaultHasher {
+    /// Creates a new `DefaultHasher`.
+    ///
+    /// This hasher is not guaranteed to be the same as all other
+    /// `DefaultHasher` instances, but is the same as all other `DefaultHasher`
+    /// instances created through `new` or `default`.
+    #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
+    #[inline]
+    #[allow(deprecated)]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+    #[must_use]
+    pub const fn new() -> DefaultHasher {
+        DefaultHasher(SipHasher13::new_with_keys(0, 0))
+    }
+}
+
+#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
+impl Default for DefaultHasher {
+    /// Creates a new `DefaultHasher` using [`new`].
+    /// See its documentation for more.
+    ///
+    /// [`new`]: DefaultHasher::new
+    #[inline]
+    fn default() -> DefaultHasher {
+        DefaultHasher::new()
+    }
+}
+
+#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
+impl Hasher for DefaultHasher {
+    // The underlying `SipHasher13` doesn't override the other
+    // `write_*` methods, so it's ok not to forward them here.
+
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.0.write(msg)
+    }
+
+    #[inline]
+    fn write_str(&mut self, s: &str) {
+        self.0.write_str(s);
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.0.finish()
+    }
+}
+
+#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+impl Default for RandomState {
+    /// Constructs a new `RandomState`.
+    #[inline]
+    fn default() -> RandomState {
+        RandomState::new()
+    }
+}
+
+#[stable(feature = "std_debug", since = "1.16.0")]
+impl fmt::Debug for RandomState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("RandomState").finish_non_exhaustive()
+    }
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 42589012257..f716c0fe922 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -494,8 +494,6 @@ pub use core::convert;
 pub use core::default;
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub use core::future;
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::hash;
 #[stable(feature = "core_hint", since = "1.27.0")]
 pub use core::hint;
 #[stable(feature = "i128", since = "1.26.0")]
@@ -565,6 +563,7 @@ pub mod env;
 pub mod error;
 pub mod ffi;
 pub mod fs;
+pub mod hash;
 pub mod io;
 pub mod net;
 pub mod num;
@@ -716,7 +715,7 @@ pub(crate) mod test_helpers {
     #[track_caller]
     pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
         use core::hash::{BuildHasher, Hash, Hasher};
-        let mut hasher = crate::collections::hash_map::RandomState::new().build_hasher();
+        let mut hasher = crate::hash::RandomState::new().build_hasher();
         core::panic::Location::caller().hash(&mut hasher);
         let hc64 = hasher.finish();
         let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index f12ffbf2e01..dbc0f7d9df3 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1,8 +1,7 @@
 use super::*;
 
-use crate::collections::hash_map::DefaultHasher;
 use crate::collections::{BTreeSet, HashSet};
-use crate::hash::Hasher;
+use crate::hash::{DefaultHasher, Hasher};
 use crate::rc::Rc;
 use crate::sync::Arc;
 use core::hint::black_box;
@@ -1461,8 +1460,7 @@ fn test_eq_receivers() {
 
 #[test]
 pub fn test_compare() {
-    use crate::collections::hash_map::DefaultHasher;
-    use crate::hash::{Hash, Hasher};
+    use crate::hash::{DefaultHasher, Hash, Hasher};
 
     fn hash<T: Hash>(t: T) -> u64 {
         let mut s = DefaultHasher::new();
diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs
index 358c2c3f9b2..1aad6549e76 100644
--- a/library/std/tests/common/mod.rs
+++ b/library/std/tests/common/mod.rs
@@ -1,17 +1,17 @@
 #![allow(unused)]
 
+use rand::RngCore;
 use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
 use std::thread;
-use rand::RngCore;
 
 /// Copied from `std::test_helpers::test_rng`, since these tests rely on the
 /// seed not being the same for every RNG invocation too.
 #[track_caller]
 pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
     use core::hash::{BuildHasher, Hash, Hasher};
-    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
+    let mut hasher = std::hash::RandomState::new().build_hasher();
     core::panic::Location::caller().hash(&mut hasher);
     let hc64 = hasher.finish();
     let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
diff --git a/library/test/src/helpers/shuffle.rs b/library/test/src/helpers/shuffle.rs
index ca503106c55..2ac3bfbd4d6 100644
--- a/library/test/src/helpers/shuffle.rs
+++ b/library/test/src/helpers/shuffle.rs
@@ -1,7 +1,6 @@
 use crate::cli::TestOpts;
 use crate::types::{TestDescAndFn, TestId, TestName};
-use std::collections::hash_map::DefaultHasher;
-use std::hash::Hasher;
+use std::hash::{DefaultHasher, Hasher};
 use std::time::{SystemTime, UNIX_EPOCH};
 
 pub fn get_shuffle_seed(opts: &TestOpts) -> Option<u64> {
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index bddf75dffbb..f92ffa94e99 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -264,8 +264,8 @@ pub fn run_tests<F>(
 where
     F: FnMut(TestEvent) -> io::Result<()>,
 {
-    use std::collections::{self, HashMap};
-    use std::hash::BuildHasherDefault;
+    use std::collections::HashMap;
+    use std::hash::{BuildHasherDefault, DefaultHasher};
     use std::sync::mpsc::RecvTimeoutError;
 
     struct RunningTest {
@@ -286,8 +286,7 @@ where
     }
 
     // Use a deterministic hasher
-    type TestMap =
-        HashMap<TestId, RunningTest, BuildHasherDefault<collections::hash_map::DefaultHasher>>;
+    type TestMap = HashMap<TestId, RunningTest, BuildHasherDefault<DefaultHasher>>;
 
     struct TimeoutEntry {
         id: TestId,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 63e8ba7c79f..8854908c430 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -20,12 +20,11 @@ use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
 
 use std::borrow::Cow;
-use std::collections::hash_map::DefaultHasher;
 use std::collections::{HashMap, HashSet};
 use std::env;
 use std::ffi::{OsStr, OsString};
 use std::fs::{self, create_dir_all, File, OpenOptions};
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
 use std::io::prelude::*;
 use std::io::{self, BufReader};
 use std::iter;
diff --git a/tests/ui/suggestions/import-trait-for-method-call.rs b/tests/ui/suggestions/import-trait-for-method-call.rs
index 4dbadbdf982..feb2c7e84f1 100644
--- a/tests/ui/suggestions/import-trait-for-method-call.rs
+++ b/tests/ui/suggestions/import-trait-for-method-call.rs
@@ -1,7 +1,7 @@
 use std::hash::BuildHasher;
 
 fn next_u64() -> u64 {
-    let bh = std::collections::hash_map::RandomState::new();
+    let bh = std::hash::RandomState::new();
     let h = bh.build_hasher();
     h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
 }