Skip to content

Commit ca70543

Browse files
committed
map_try_insert changes
1 parent 9620eae commit ca70543

6 files changed

Lines changed: 48 additions & 53 deletions

File tree

library/Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ dependencies = [
125125

126126
[[package]]
127127
name = "hashbrown"
128-
version = "0.17.0"
128+
version = "0.17.1"
129129
source = "registry+https://github.com/rust-lang/crates.io-index"
130-
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
130+
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
131131
dependencies = [
132132
"foldhash",
133133
"rustc-std-workspace-alloc",

library/alloc/src/collections/btree/map.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
10591059
/// a mutable reference to the value in the entry.
10601060
///
10611061
/// If the map already had this key present, nothing is updated, and
1062-
/// an error containing the occupied entry and the value is returned.
1062+
/// an error containing the occupied entry, key, and the value is returned.
10631063
///
10641064
/// # Examples
10651065
///
@@ -1074,17 +1074,38 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
10741074
/// let err = map.try_insert(37, "b").unwrap_err();
10751075
/// assert_eq!(err.entry.key(), &37);
10761076
/// assert_eq!(err.entry.get(), &"a");
1077+
/// assert_eq!(err.key, 37);
10771078
/// assert_eq!(err.value, "b");
10781079
/// ```
10791080
#[unstable(feature = "map_try_insert", issue = "82766")]
10801081
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, A>>
10811082
where
10821083
K: Ord,
10831084
{
1084-
match self.entry(key) {
1085-
Occupied(entry) => Err(OccupiedError { entry, value }),
1086-
Vacant(entry) => Ok(entry.insert(value)),
1087-
}
1085+
let (map, dormant_map) = DormantMutRef::new(self);
1086+
let handle = match map.root {
1087+
Some(ref mut root) => match root.borrow_mut().search_tree(&key) {
1088+
Found(handle) => {
1089+
let entry = OccupiedEntry {
1090+
handle,
1091+
dormant_map,
1092+
alloc: (*map.alloc).clone(),
1093+
_marker: PhantomData,
1094+
};
1095+
return Err(OccupiedError { entry, key, value });
1096+
}
1097+
GoDown(handle) => Some(handle),
1098+
},
1099+
None => None,
1100+
};
1101+
let entry = VacantEntry {
1102+
key,
1103+
handle,
1104+
dormant_map,
1105+
alloc: (*map.alloc).clone(),
1106+
_marker: PhantomData,
1107+
};
1108+
Ok(entry.insert(value))
10881109
}
10891110

10901111
/// Removes a key from the map, returning the value at the key if the key

library/alloc/src/collections/btree/map/entry.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedEntry<'_,
9797

9898
/// The error returned by [`try_insert`](BTreeMap::try_insert) when the key already exists.
9999
///
100-
/// Contains the occupied entry, and the value that was not inserted.
100+
/// Contains the occupied entry, key, and the value that was not inserted.
101101
#[unstable(feature = "map_try_insert", issue = "82766")]
102+
#[non_exhaustive]
102103
pub struct OccupiedError<
103104
'a,
104105
K: 'a,
@@ -107,6 +108,8 @@ pub struct OccupiedError<
107108
> {
108109
/// The entry in the map that was already occupied.
109110
pub entry: OccupiedEntry<'a, K, V, A>,
111+
/// The key which was not inserted, because the entry was already occupied.
112+
pub key: K,
110113
/// The value which was not inserted, because the entry was already occupied.
111114
pub value: V,
112115
}
@@ -116,33 +119,13 @@ impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedError<'_,
116119
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117120
f.debug_struct("OccupiedError")
118121
.field("key", self.entry.key())
122+
.field("uninserted_key", &self.key)
119123
.field("old_value", self.entry.get())
120124
.field("new_value", &self.value)
121125
.finish()
122126
}
123127
}
124128

125-
#[unstable(feature = "map_try_insert", issue = "82766")]
126-
impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
127-
for OccupiedError<'a, K, V, A>
128-
{
129-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130-
write!(
131-
f,
132-
"failed to insert {:?}, key {:?} already exists with value {:?}",
133-
self.value,
134-
self.entry.key(),
135-
self.entry.get(),
136-
)
137-
}
138-
}
139-
140-
#[unstable(feature = "map_try_insert", issue = "82766")]
141-
impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
142-
for crate::collections::btree_map::OccupiedError<'a, K, V>
143-
{
144-
}
145-
146129
impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
147130
/// Ensures a value is in the entry by inserting the default if empty, and returns
148131
/// a mutable reference to the value in the entry.

library/alloc/src/collections/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod vec_deque;
1919
pub mod btree_map {
2020
//! An ordered map based on a B-Tree.
2121
#[stable(feature = "rust1", since = "1.0.0")]
22+
#[cfg(not(test))]
2223
pub use super::btree::map::*;
2324
}
2425

library/std/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
2020
panic_abort = { path = "../panic_abort" }
2121
core = { path = "../core", public = true }
2222
unwind = { path = "../unwind" }
23-
hashbrown = { version = "0.17.0", default-features = false, features = [
23+
hashbrown = { version = "0.17.1", default-features = false, features = [
2424
'rustc-dep-of-std',
2525
] }
2626
std_detect = { path = "../std_detect", public = true }

library/std/src/collections/hash/map.rs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
#[cfg(test)]
22
mod tests;
33

4-
use hashbrown::hash_map as base;
4+
use hashbrown::hash_map::{self as base, RustcOccupiedError};
55

66
use self::Entry::*;
77
use crate::alloc::{Allocator, Global};
88
use crate::borrow::Borrow;
99
use crate::collections::{TryReserveError, TryReserveErrorKind};
10-
use crate::error::Error;
1110
use crate::fmt::{self, Debug};
1211
use crate::hash::{BuildHasher, Hash, RandomState};
1312
use crate::iter::FusedIterator;
@@ -1333,7 +1332,7 @@ where
13331332
/// a mutable reference to the value in the entry.
13341333
///
13351334
/// If the map already had this key present, nothing is updated, and
1336-
/// an error containing the occupied entry and the value is returned.
1335+
/// an error containing the occupied entry, key, and the value is returned.
13371336
///
13381337
/// # Examples
13391338
///
@@ -1350,13 +1349,16 @@ where
13501349
/// let err = map.try_insert(37, "b").unwrap_err();
13511350
/// assert_eq!(err.entry.key(), &37);
13521351
/// assert_eq!(err.entry.get(), &"a");
1352+
/// assert_eq!(err.key, 37);
13531353
/// assert_eq!(err.value, "b");
13541354
/// ```
13551355
#[unstable(feature = "map_try_insert", issue = "82766")]
13561356
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, A>> {
1357-
match self.entry(key) {
1358-
Occupied(entry) => Err(OccupiedError { entry, value }),
1359-
Vacant(entry) => Ok(entry.insert(value)),
1357+
match self.base.rustc_try_insert(key, value) {
1358+
Result::Ok(value) => Ok(value),
1359+
Result::Err(RustcOccupiedError { entry, key, value, .. }) => {
1360+
Err(OccupiedError { entry: OccupiedEntry { base: entry }, key, value })
1361+
}
13601362
}
13611363
}
13621364

@@ -2007,8 +2009,9 @@ impl<K: Debug, V, A: Allocator> Debug for VacantEntry<'_, K, V, A> {
20072009

20082010
/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
20092011
///
2010-
/// Contains the occupied entry, and the value that was not inserted.
2012+
/// Contains the occupied entry, key, and the value that was not inserted.
20112013
#[unstable(feature = "map_try_insert", issue = "82766")]
2014+
#[non_exhaustive]
20122015
pub struct OccupiedError<
20132016
'a,
20142017
K: 'a,
@@ -2017,6 +2020,8 @@ pub struct OccupiedError<
20172020
> {
20182021
/// The entry in the map that was already occupied.
20192022
pub entry: OccupiedEntry<'a, K, V, A>,
2023+
/// The key which was not inserted, because the entry was already occupied.
2024+
pub key: K,
20202025
/// The value which was not inserted, because the entry was already occupied.
20212026
pub value: V,
20222027
}
@@ -2026,28 +2031,13 @@ impl<K: Debug, V: Debug, A: Allocator> Debug for OccupiedError<'_, K, V, A> {
20262031
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20272032
f.debug_struct("OccupiedError")
20282033
.field("key", self.entry.key())
2034+
.field("uninserted_key", &self.key)
20292035
.field("old_value", self.entry.get())
20302036
.field("new_value", &self.value)
20312037
.finish_non_exhaustive()
20322038
}
20332039
}
20342040

2035-
#[unstable(feature = "map_try_insert", issue = "82766")]
2036-
impl<'a, K: Debug, V: Debug, A: Allocator> fmt::Display for OccupiedError<'a, K, V, A> {
2037-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2038-
write!(
2039-
f,
2040-
"failed to insert {:?}, key {:?} already exists with value {:?}",
2041-
self.value,
2042-
self.entry.key(),
2043-
self.entry.get(),
2044-
)
2045-
}
2046-
}
2047-
2048-
#[unstable(feature = "map_try_insert", issue = "82766")]
2049-
impl<'a, K: Debug, V: Debug, A: Allocator> Error for OccupiedError<'a, K, V, A> {}
2050-
20512041
#[stable(feature = "rust1", since = "1.0.0")]
20522042
impl<'a, K, V, S, A: Allocator> IntoIterator for &'a HashMap<K, V, S, A> {
20532043
type Item = (&'a K, &'a V);

0 commit comments

Comments
 (0)