map_try_insert changes

This commit is contained in:
malezjaa
2026-04-15 23:13:54 +02:00
parent 9620eae30a
commit ca70543ca4
6 changed files with 48 additions and 53 deletions
+2 -2
View File
@@ -125,9 +125,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.17.0"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
dependencies = [
"foldhash",
"rustc-std-workspace-alloc",
+26 -5
View File
@@ -1059,7 +1059,7 @@ pub fn insert(&mut self, key: K, value: V) -> Option<V>
/// a mutable reference to the value in the entry.
///
/// If the map already had this key present, nothing is updated, and
/// an error containing the occupied entry and the value is returned.
/// an error containing the occupied entry, key, and the value is returned.
///
/// # Examples
///
@@ -1074,6 +1074,7 @@ pub fn insert(&mut self, key: K, value: V) -> Option<V>
/// let err = map.try_insert(37, "b").unwrap_err();
/// assert_eq!(err.entry.key(), &37);
/// assert_eq!(err.entry.get(), &"a");
/// assert_eq!(err.key, 37);
/// assert_eq!(err.value, "b");
/// ```
#[unstable(feature = "map_try_insert", issue = "82766")]
@@ -1081,10 +1082,30 @@ pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'
where
K: Ord,
{
match self.entry(key) {
Occupied(entry) => Err(OccupiedError { entry, value }),
Vacant(entry) => Ok(entry.insert(value)),
}
let (map, dormant_map) = DormantMutRef::new(self);
let handle = match map.root {
Some(ref mut root) => match root.borrow_mut().search_tree(&key) {
Found(handle) => {
let entry = OccupiedEntry {
handle,
dormant_map,
alloc: (*map.alloc).clone(),
_marker: PhantomData,
};
return Err(OccupiedError { entry, key, value });
}
GoDown(handle) => Some(handle),
},
None => None,
};
let entry = VacantEntry {
key,
handle,
dormant_map,
alloc: (*map.alloc).clone(),
_marker: PhantomData,
};
Ok(entry.insert(value))
}
/// Removes a key from the map, returning the value at the key if the key
@@ -97,8 +97,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// The error returned by [`try_insert`](BTreeMap::try_insert) when the key already exists.
///
/// Contains the occupied entry, and the value that was not inserted.
/// Contains the occupied entry, key, and the value that was not inserted.
#[unstable(feature = "map_try_insert", issue = "82766")]
#[non_exhaustive]
pub struct OccupiedError<
'a,
K: 'a,
@@ -107,6 +108,8 @@ pub struct OccupiedError<
> {
/// The entry in the map that was already occupied.
pub entry: OccupiedEntry<'a, K, V, A>,
/// The key which was not inserted, because the entry was already occupied.
pub key: K,
/// The value which was not inserted, because the entry was already occupied.
pub value: V,
}
@@ -116,33 +119,13 @@ impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedError<'_,
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedError")
.field("key", self.entry.key())
.field("uninserted_key", &self.key)
.field("old_value", self.entry.get())
.field("new_value", &self.value)
.finish()
}
}
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
for OccupiedError<'a, K, V, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to insert {:?}, key {:?} already exists with value {:?}",
self.value,
self.entry.key(),
self.entry.get(),
)
}
}
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
for crate::collections::btree_map::OccupiedError<'a, K, V>
{
}
impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
+1
View File
@@ -19,6 +19,7 @@
pub mod btree_map {
//! An ordered map based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(test))]
pub use super::btree::map::*;
}
+1 -1
View File
@@ -20,7 +20,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.17.0", default-features = false, features = [
hashbrown = { version = "0.17.1", default-features = false, features = [
'rustc-dep-of-std',
] }
std_detect = { path = "../std_detect", public = true }
+13 -23
View File
@@ -1,13 +1,12 @@
#[cfg(test)]
mod tests;
use hashbrown::hash_map as base;
use hashbrown::hash_map::{self as base, RustcOccupiedError};
use self::Entry::*;
use crate::alloc::{Allocator, Global};
use crate::borrow::Borrow;
use crate::collections::{TryReserveError, TryReserveErrorKind};
use crate::error::Error;
use crate::fmt::{self, Debug};
use crate::hash::{BuildHasher, Hash, RandomState};
use crate::iter::FusedIterator;
@@ -1333,7 +1332,7 @@ pub fn insert(&mut self, k: K, v: V) -> Option<V> {
/// a mutable reference to the value in the entry.
///
/// If the map already had this key present, nothing is updated, and
/// an error containing the occupied entry and the value is returned.
/// an error containing the occupied entry, key, and the value is returned.
///
/// # Examples
///
@@ -1350,13 +1349,16 @@ pub fn insert(&mut self, k: K, v: V) -> Option<V> {
/// let err = map.try_insert(37, "b").unwrap_err();
/// assert_eq!(err.entry.key(), &37);
/// assert_eq!(err.entry.get(), &"a");
/// assert_eq!(err.key, 37);
/// assert_eq!(err.value, "b");
/// ```
#[unstable(feature = "map_try_insert", issue = "82766")]
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, A>> {
match self.entry(key) {
Occupied(entry) => Err(OccupiedError { entry, value }),
Vacant(entry) => Ok(entry.insert(value)),
match self.base.rustc_try_insert(key, value) {
Result::Ok(value) => Ok(value),
Result::Err(RustcOccupiedError { entry, key, value, .. }) => {
Err(OccupiedError { entry: OccupiedEntry { base: entry }, key, value })
}
}
}
@@ -2007,8 +2009,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
///
/// Contains the occupied entry, and the value that was not inserted.
/// Contains the occupied entry, key, and the value that was not inserted.
#[unstable(feature = "map_try_insert", issue = "82766")]
#[non_exhaustive]
pub struct OccupiedError<
'a,
K: 'a,
@@ -2017,6 +2020,8 @@ pub struct OccupiedError<
> {
/// The entry in the map that was already occupied.
pub entry: OccupiedEntry<'a, K, V, A>,
/// The key which was not inserted, because the entry was already occupied.
pub key: K,
/// The value which was not inserted, because the entry was already occupied.
pub value: V,
}
@@ -2026,28 +2031,13 @@ impl<K: Debug, V: Debug, A: Allocator> Debug for OccupiedError<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedError")
.field("key", self.entry.key())
.field("uninserted_key", &self.key)
.field("old_value", self.entry.get())
.field("new_value", &self.value)
.finish_non_exhaustive()
}
}
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug, V: Debug, A: Allocator> fmt::Display for OccupiedError<'a, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to insert {:?}, key {:?} already exists with value {:?}",
self.value,
self.entry.key(),
self.entry.get(),
)
}
}
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug, V: Debug, A: Allocator> Error for OccupiedError<'a, K, V, A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V, S, A: Allocator> IntoIterator for &'a HashMap<K, V, S, A> {
type Item = (&'a K, &'a V);