diff --git a/Cargo.toml b/Cargo.toml
index b8ffd42..57364cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,8 +8,8 @@ repository = "https://github.com/Licenser/halfbrown"
 version = "0.2.5"
 
 [dependencies]
-hashbrown = "0.14"
-rustc-hash = { version = "1.1", optional = true }
+hashbrown = "0.15"
+rustc-hash = { version = "2.1", optional = true }
 serde = { version = "1", default-features = false, optional = true }
 arrayvec = { version = "0.7", optional = true }
 [dev-dependencies]
diff --git a/benches/compare.rs b/benches/compare.rs
index 2fd8d72..6fac128 100644
--- a/benches/compare.rs
+++ b/benches/compare.rs
@@ -230,7 +230,7 @@ fn bench_group(b: &mut Criterion, name: &str, bench_input: BenchInput) {
             |data| {
                 let mut m = halfbrown::HashMap::with_capacity(bench_input.initial_cap);
                 for e in data {
-                    m.insert_nocheck(e, e);
+                    unsafe { m.insert_nocheck(e, e) };
                 }
             },
             BatchSize::SmallInput,
diff --git a/src/entry.rs b/src/entry.rs
index 1554baa..e4679fa 100644
--- a/src/entry.rs
+++ b/src/entry.rs
@@ -438,57 +438,57 @@ impl<'a, K, V, const N: usize, S> OccupiedEntry<'a, K, V, N, S> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::hash_map::{Entry, HashMap};
+    /// use halfbrown::{Entry, HashMap};
     /// use std::rc::Rc;
     ///
-    /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
-    /// map.insert(Rc::new("Stringthing".to_string()), 15);
-    ///
-    /// let my_key = Rc::new("Stringthing".to_string());
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.insert("poneyland", 42);
+    ///
+    /// let entry = match map.entry("poneyland") {
+    ///     Entry::Occupied(e) => {
+    ///         e.replace_entry_with(|k, v| {
+    ///             assert_eq!(k, &"poneyland");
+    ///             assert_eq!(v, 42);
+    ///             Some(v + 1)
+    ///         })
+    ///     }
+    ///     Entry::Vacant(_) => panic!(),
+    /// };
     ///
-    /// if let Entry::Occupied(entry) = map.entry(my_key) {
-    ///     // Also replace the key with a handle to our other key.
-    ///     let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
+    /// match entry {
+    ///     Entry::Occupied(e) => {
+    ///         assert_eq!(e.key(), &"poneyland");
+    ///         assert_eq!(e.get(), &43);
+    ///     }
+    ///     Entry::Vacant(_) => panic!(),
     /// }
     ///
-    /// ```
-    #[inline]
-    pub fn replace_entry(self, value: V) -> (K, V) {
-        match self.0 {
-            OccupiedEntryInt::Map(m) => m.replace_entry(value),
-            OccupiedEntryInt::Vec(m) => m.replace_entry(value),
-        }
-    }
-
-    /// Replaces the key in the hash map with the key used to create this entry.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use hashbrown::hash_map::{Entry, HashMap};
-    /// use std::rc::Rc;
-    ///
-    /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
-    /// let mut known_strings: Vec<Rc<String>> = Vec::new();
-    ///
-    /// // Initialise known strings, run program, etc.
+    /// assert_eq!(map["poneyland"], 43);
     ///
-    /// reclaim_memory(&mut map, &known_strings);
+    /// let entry = match map.entry("poneyland") {
+    ///     Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
+    ///     Entry::Vacant(_) => panic!(),
+    /// };
     ///
-    /// fn reclaim_memory(map: &mut HashMap<Rc<String>, u32>, known_strings: &[Rc<String>] ) {
-    ///     for s in known_strings {
-    ///         if let Entry::Occupied(entry) = map.entry(s.clone()) {
-    ///             // Replaces the entry's key with our version of it in `known_strings`.
-    ///             entry.replace_key();
-    ///         }
+    /// match entry {
+    ///     Entry::Vacant(e) => {
+    ///         assert_eq!(e.key(), &"poneyland");
     ///     }
+    ///     Entry::Occupied(_) => panic!(),
     /// }
+    ///
+    /// assert!(!map.contains_key("poneyland"));
+    ///
     /// ```
     #[inline]
-    pub fn replace_key(self) -> K {
+    pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, N, S>
+    where
+        F: FnOnce(&K, V) -> Option<V>,
+        V: Clone,
+    {
         match self.0 {
-            OccupiedEntryInt::Map(m) => m.replace_key(),
-            OccupiedEntryInt::Vec(m) => m.replace_key(),
+            OccupiedEntryInt::Map(m) => m.replace_entry_with(f).into(),
+            OccupiedEntryInt::Vec(m) => m.replace_entry_with(f).into(),
         }
     }
 }
diff --git a/src/iter.rs b/src/iter.rs
index d95a4c1..e8acd08 100644
--- a/src/iter.rs
+++ b/src/iter.rs
@@ -8,7 +8,7 @@ use std::iter::{FromIterator, FusedIterator, IntoIterator};
 pub struct Iter<'a, K, V>(IterInt<'a, K, V>);
 
 /// Manual implementation so that `Clone` isn't required for `K` nor `V`
-impl<'a, K, V> Clone for Iter<'a, K, V> {
+impl<K, V> Clone for Iter<'_, K, V> {
     fn clone(&self) -> Self {
         Iter(self.0.clone())
     }
@@ -27,7 +27,7 @@ pub(crate) enum IterInt<'a, K, V> {
 }
 
 /// Manual implementation so that `Clone` isn't required for `K` nor `V`
-impl<'a, K, V> Clone for IterInt<'a, K, V> {
+impl<K, V> Clone for IterInt<'_, K, V> {
     fn clone(&self) -> Self {
         match self {
             IterInt::Map(i) => IterInt::Map(i.clone()),
@@ -60,7 +60,7 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     }
 }
 
-impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
+impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
     #[inline]
     fn len(&self) -> usize {
         match &self.0 {
@@ -70,7 +70,7 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
     }
 }
 
-impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
+impl<K, V> FusedIterator for Iter<'_, K, V> {}
 
 /// Into iterator for a Halfbrown map
 pub struct IntoIter<K, V, const N: usize>(IntoIterInt<K, V, N>);
@@ -149,6 +149,16 @@ impl<'a, K, V, S, const N: usize> IntoIterator for &'a SizedHashMap<K, V, S, N>
     }
 }
 
+impl<'a, K, V, S, const N: usize> IntoIterator for &'a mut SizedHashMap<K, V, S, N> {
+    type Item = (&'a K, &'a V);
+    type IntoIter = Iter<'a, K, V>;
+
+    #[inline]
+    fn into_iter(self) -> Iter<'a, K, V> {
+        self.iter()
+    }
+}
+
 impl<K, V, S, const N: usize> FromIterator<(K, V)> for SizedHashMap<K, V, S, N>
 where
     K: Eq + Hash,
@@ -198,7 +208,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     }
 }
 
-impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
+impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
     #[inline]
     fn len(&self) -> usize {
         match &self.0 {
@@ -208,4 +218,4 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
     }
 }
 
-impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
+impl<K, V> FusedIterator for IterMut<'_, K, V> {}
diff --git a/src/lib.rs b/src/lib.rs
index c95a30b..920f9e6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,17 +19,14 @@
 //! their copyright.
 
 #![warn(unused_extern_crates)]
-#![cfg_attr(
-feature = "cargo-clippy",
-deny(
-clippy::all,
-clippy::unwrap_used,
-clippy::unnecessary_unwrap,
-clippy::pedantic
-),
-// We might want to revisit inline_always
-allow(clippy::module_name_repetitions, clippy::inline_always)
+#![deny(
+    clippy::all,
+    clippy::unwrap_used,
+    clippy::unnecessary_unwrap,
+    clippy::pedantic
 )]
+// We might want to revisit inline_always
+#![allow(clippy::module_name_repetitions, clippy::inline_always)]
 #![deny(missing_docs)]
 
 mod entry;
@@ -58,7 +55,7 @@ pub type DefaultHashBuilder = core::hash::BuildHasherDefault<rustc_hash::FxHashe
 
 use crate::vectypes::VecDrain;
 #[cfg(not(feature = "fxhash"))]
-pub use hashbrown::hash_map::DefaultHashBuilder;
+pub use hashbrown::DefaultHashBuilder;
 
 /// `SizedHashMap` implementation that alternates between a vector
 /// and a hashmap to improve performance for low key counts.
@@ -67,7 +64,6 @@ pub type HashMap<K, V, S = DefaultHashBuilder> = SizedHashMap<K, V, S, 32>;
 
 /// Maximum nymber of elements before the representaiton is swapped from
 /// Vec to `HashMap`
-
 /// `SizedHashMap` implementation that alternates between a vector
 /// and a hashmap to improve performance for low key counts. With a configurable upper vector limit
 #[derive(Clone)]
@@ -172,8 +168,8 @@ impl<K, V, S, const VEC_LIMIT_UPPER: usize> SizedHashMap<K, V, S, VEC_LIMIT_UPPE
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::DefaultHashBuilder;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::DefaultHashBuilder;
     ///
     /// let s = DefaultHashBuilder::default();
     /// let mut map = HashMap::with_hasher(s);
@@ -198,8 +194,8 @@ impl<K, V, S, const VEC_LIMIT_UPPER: usize> SizedHashMap<K, V, S, VEC_LIMIT_UPPE
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::DefaultHashBuilder;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::DefaultHashBuilder;
     ///
     /// let s = DefaultHashBuilder::default();
     /// let mut map = HashMap::with_capacity_and_hasher(10, s);
@@ -221,8 +217,8 @@ impl<K, V, S, const VEC_LIMIT_UPPER: usize> SizedHashMap<K, V, S, VEC_LIMIT_UPPE
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::DefaultHashBuilder;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::DefaultHashBuilder;
     ///
     /// let hasher = DefaultHashBuilder::default();
     /// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
@@ -830,8 +826,13 @@ where
     /// Inserts element, this ignores check in the vector
     /// map if keys are present - it's a fast way to build
     /// a new map when uniqueness is known ahead of time.
+    ///
+    /// # Safety
+    ///
+    /// Used for building new hashmaps wher eit is known that
+    /// the keys are unique.
     #[inline]
-    pub fn insert_nocheck(&mut self, k: K, v: V)
+    pub unsafe fn insert_nocheck(&mut self, k: K, v: V)
     where
         S: Default,
     {
@@ -1054,7 +1055,7 @@ enum DrainInt<'a, K, V, const N: usize> {
     Vec(VecDrain<'a, (K, V), N>),
 }
 
-impl<'a, K, V, const N: usize> Iterator for Drain<'a, K, V, N> {
+impl<K, V, const N: usize> Iterator for Drain<'_, K, V, N> {
     type Item = (K, V);
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
@@ -1108,7 +1109,7 @@ mod tests {
     fn scale_up_via_no_check() {
         let mut v = SizedHashMap::<_, _, _, TEST_SIZE>::new();
         for i in 1..TEST_SIZE + 2 {
-            v.insert_nocheck(i, i);
+            unsafe { v.insert_nocheck(i, i) };
         }
     }
 
@@ -1119,7 +1120,7 @@ mod tests {
         let mut v = SizedHashMap::<_, _, _, TEST_SIZE>::new();
         for i in 1..TEST_SIZE + 1 {
             v.insert(3 * i, i);
-            v.insert_nocheck(3 * i + 1, i);
+            unsafe { v.insert_nocheck(3 * i + 1, i) };
             v.entry(3 * i + 2).or_insert(i);
         }
     }
diff --git a/src/raw_entry.rs b/src/raw_entry.rs
index e48b13e..a69efb6 100644
--- a/src/raw_entry.rs
+++ b/src/raw_entry.rs
@@ -301,7 +301,7 @@ where
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// let entry = map.raw_entry_mut().from_key("horseyland").insert("horseyland", 37);
@@ -339,7 +339,7 @@ where
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     ///
@@ -367,7 +367,7 @@ where
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, String> = HashMap::new();
     ///
@@ -399,7 +399,7 @@ where
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     ///
diff --git a/src/vecmap/entry.rs b/src/vecmap/entry.rs
index b850d98..50e4f27 100644
--- a/src/vecmap/entry.rs
+++ b/src/vecmap/entry.rs
@@ -187,7 +187,7 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -203,8 +203,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -226,8 +226,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -251,8 +251,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -283,8 +283,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -306,8 +306,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -330,8 +330,8 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// map.entry("poneyland").or_insert(12);
@@ -353,60 +353,66 @@ impl<'a, K, V, S, const N: usize> OccupiedEntry<'a, K, V, S, N> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::hash_map::{Entry, HashMap};
+    /// use halfbrown::{Entry, HashMap};
     /// use std::rc::Rc;
     ///
-    /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
-    /// map.insert(Rc::new("Stringthing".to_string()), 15);
-    ///
-    /// let my_key = Rc::new("Stringthing".to_string());
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.insert("poneyland", 42);
+    ///
+    /// let entry = match map.entry("poneyland") {
+    ///     Entry::Occupied(e) => {
+    ///         e.replace_entry_with(|k, v| {
+    ///             assert_eq!(k, &"poneyland");
+    ///             assert_eq!(v, 42);
+    ///             Some(v + 1)
+    ///         })
+    ///     }
+    ///     Entry::Vacant(_) => panic!(),
+    /// };
     ///
-    /// if let Entry::Occupied(entry) = map.entry(my_key) {
-    ///     // Also replace the key with a handle to our other key.
-    ///     let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
+    /// match entry {
+    ///     Entry::Occupied(e) => {
+    ///         assert_eq!(e.key(), &"poneyland");
+    ///         assert_eq!(e.get(), &43);
+    ///     }
+    ///     Entry::Vacant(_) => panic!(),
     /// }
     ///
-    /// ```
-    #[inline]
-    #[allow(clippy::unwrap_used)]
-    pub fn replace_entry(self, value: V) -> (K, V) {
-        let entry = unsafe { self.map.v.get_unchecked_mut(self.idx) };
-
-        let old_key = mem::replace(&mut entry.0, self.key.unwrap());
-        let old_value = mem::replace(&mut entry.1, value);
-
-        (old_key, old_value)
-    }
-
-    /// Replaces the key in the hash map with the key used to create this entry.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use hashbrown::hash_map::{Entry, HashMap};
-    /// use std::rc::Rc;
-    ///
-    /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
-    /// let mut known_strings: Vec<Rc<String>> = Vec::new();
-    ///
-    /// // Initialise known strings, run program, etc.
+    /// assert_eq!(map["poneyland"], 43);
     ///
-    /// reclaim_memory(&mut map, &known_strings);
+    /// let entry = match map.entry("poneyland") {
+    ///     Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
+    ///     Entry::Vacant(_) => panic!(),
+    /// };
     ///
-    /// fn reclaim_memory(map: &mut HashMap<Rc<String>, u32>, known_strings: &[Rc<String>] ) {
-    ///     for s in known_strings {
-    ///         if let Entry::Occupied(entry) = map.entry(s.clone()) {
-    ///             // Replaces the entry's key with our version of it in `known_strings`.
-    ///             entry.replace_key();
-    ///         }
+    /// match entry {
+    ///     Entry::Vacant(e) => {
+    ///         assert_eq!(e.key(), &"poneyland");
     ///     }
+    ///     Entry::Occupied(_) => panic!(),
     /// }
+    ///
+    /// assert!(!map.contains_key("poneyland"));
+    ///
     /// ```
     #[inline]
     #[allow(clippy::unwrap_used)]
-    pub fn replace_key(self) -> K {
-        let entry = unsafe { self.map.v.get_unchecked_mut(self.idx) };
-        mem::replace(&mut entry.0, self.key.unwrap())
+    pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, N, S>
+    where
+        F: FnOnce(&K, V) -> Option<V>,
+    {
+        let (key, value) = unsafe { self.map.remove_idx(self.idx) };
+
+        if let Some(v) = f(&key, value) {
+            let idx = self.map.insert_idx(key, v);
+            Entry::Occupied(OccupiedEntry {
+                idx,
+                key: self.key,
+                map: self.map,
+            })
+        } else {
+            Entry::Vacant(VacantEntry { key, map: self.map })
+        }
     }
 }
 
@@ -435,7 +441,7 @@ impl<'a, K, V, const N: usize, S> VacantEntry<'a, K, V, N, S> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
+    /// use halfbrown::HashMap;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
@@ -450,8 +456,8 @@ impl<'a, K, V, const N: usize, S> VacantEntry<'a, K, V, N, S> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     ///
@@ -470,8 +476,8 @@ impl<'a, K, V, const N: usize, S> VacantEntry<'a, K, V, N, S> {
     /// # Examples
     ///
     /// ```
-    /// use hashbrown::HashMap;
-    /// use hashbrown::hash_map::Entry;
+    /// use halfbrown::HashMap;
+    /// use halfbrown::Entry;
     ///
     /// let mut map: HashMap<&str, u32> = HashMap::new();
     ///