Skip to content

Commit e518c05

Browse files
committed
Auto merge of #27894 - steveklabnik:gh26888, r=alexcrichton
{BTree,Hash}{Map,Set} will not update their key if it already exists, which can matter with more complex keys. This behavior is now documented. Fixes #26888
2 parents 414d68e + e8e3c6f commit e518c05

File tree

5 files changed

+78
-8
lines changed

5 files changed

+78
-8
lines changed

src/libcollections/btree/map.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,14 @@ impl<K: Ord, V> BTreeMap<K, V> {
315315
// 2) While ODS may potentially return the pair we *just* inserted after
316316
// the split, we will never do this. Again, this shouldn't effect the analysis.
317317

318-
/// Inserts a key-value pair into the map. If the key already had a value
319-
/// present in the map, that value is returned. Otherwise, `None` is returned.
318+
/// Inserts a key-value pair into the map.
319+
///
320+
/// If the map did not have this key present, `None` is returned.
321+
///
322+
/// If the map did have this key present, that value is returned, and the
323+
/// entry is not updated. See the [module-level documentation] for more.
324+
///
325+
/// [module-level documentation]: index.html#insert-and-complex-keys
320326
///
321327
/// # Examples
322328
///

src/libcollections/btree/set.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,14 @@ impl<T: Ord> BTreeSet<T> {
430430
other.is_subset(self)
431431
}
432432

433-
/// Adds a value to the set. Returns `true` if the value was not already
434-
/// present in the set.
433+
/// Adds a value to the set.
434+
///
435+
/// If the set did not have a value present, `true` is returned.
436+
///
437+
/// If the set did have this key present, that value is returned, and the
438+
/// entry is not updated. See the [module-level documentation] for more.
439+
///
440+
/// [module-level documentation]: index.html#insert-and-complex-keys
435441
///
436442
/// # Examples
437443
///

src/libstd/collections/hash/map.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,8 +1101,14 @@ impl<K, V, S> HashMap<K, V, S>
11011101
self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
11021102
}
11031103

1104-
/// Inserts a key-value pair into the map. If the key already had a value
1105-
/// present in the map, that value is returned. Otherwise, `None` is returned.
1104+
/// Inserts a key-value pair into the map.
1105+
///
1106+
/// If the map did not have this key present, `None` is returned.
1107+
///
1108+
/// If the map did have this key present, that value is returned, and the
1109+
/// entry is not updated. See the [module-level documentation] for more.
1110+
///
1111+
/// [module-level documentation]: index.html#insert-and-complex-keys
11061112
///
11071113
/// # Examples
11081114
///

src/libstd/collections/hash/set.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,14 @@ impl<T, S> HashSet<T, S>
540540
other.is_subset(self)
541541
}
542542

543-
/// Adds a value to the set. Returns `true` if the value was not already
544-
/// present in the set.
543+
/// Adds a value to the set.
544+
///
545+
/// If the set did not have a value present, `true` is returned.
546+
///
547+
/// If the set did have this key present, that value is returned, and the
548+
/// entry is not updated. See the [module-level documentation] for more.
549+
///
550+
/// [module-level documentation]: index.html#insert-and-complex-keys
545551
///
546552
/// # Examples
547553
///

src/libstd/collections/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,52 @@
359359
//! }
360360
//! }
361361
//! ```
362+
//!
363+
//! # Insert and complex keys
364+
//!
365+
//! If we have a more complex key, calls to `insert()` will
366+
//! not update the value of the key. For example:
367+
//!
368+
//! ```
369+
//! use std::cmp::Ordering;
370+
//! use std::collections::BTreeMap;
371+
//! use std::hash::{Hash, Hasher};
372+
//!
373+
//! #[derive(Debug)]
374+
//! struct Foo {
375+
//! a: u32,
376+
//! b: &'static str,
377+
//! }
378+
//!
379+
//! // we will compare `Foo`s by their `a` value only.
380+
//! impl PartialEq for Foo {
381+
//! fn eq(&self, other: &Self) -> bool { self.a == other.a }
382+
//! }
383+
//!
384+
//! impl Eq for Foo {}
385+
//!
386+
//! // we will hash `Foo`s by their `a` value only.
387+
//! impl Hash for Foo {
388+
//! fn hash<H: Hasher>(&self, h: &mut H) { self.a.hash(h); }
389+
//! }
390+
//!
391+
//! impl PartialOrd for Foo {
392+
//! fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.a.partial_cmp(&other.a) }
393+
//! }
394+
//!
395+
//! impl Ord for Foo {
396+
//! fn cmp(&self, other: &Self) -> Ordering { self.a.cmp(&other.a) }
397+
//! }
398+
//!
399+
//! let mut map = BTreeMap::new();
400+
//! map.insert(Foo { a: 1, b: "baz" }, ());
401+
//!
402+
//! // We already have a Foo with an a of 1, so this will be updating the value.
403+
//! map.insert(Foo { a: 1, b: "xyz" }, ());
404+
//!
405+
//! // ... but the key hasn't changed. b is still "baz", not "xyz"
406+
//! assert_eq!(map.keys().next().unwrap().b, "baz");
407+
//! ```
362408
363409
#![stable(feature = "rust1", since = "1.0.0")]
364410

0 commit comments

Comments
 (0)