mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-22 18:15:07 +03:00
map_try_insert changes
This commit is contained in:
+2
-2
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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::*;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user