Skip to content

Commit

Permalink
Specify behavior of HashSet::insert
Browse files Browse the repository at this point in the history
`HashSet::insert` does not replace the value with equal value.

Fixes #107581.
  • Loading branch information
stepancheg committed Feb 3, 2023
1 parent f312650 commit e800d5a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
4 changes: 3 additions & 1 deletion library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,9 @@ where
/// Returns whether the value was newly inserted. That is:
///
/// - If the set did not previously contain this value, `true` is returned.
/// - If the set already contained this value, `false` is returned.
/// - If the set already contained this value, `false` is returned,
/// and the set is not modified: original value is not replaced,
/// and the value passed as argument is dropped.
///
/// # Examples
///
Expand Down
20 changes: 20 additions & 0 deletions library/std/src/collections/hash/set/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::HashSet;

use crate::panic::{catch_unwind, AssertUnwindSafe};
use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sync::Arc;

#[test]
fn test_zero_capacities() {
Expand Down Expand Up @@ -502,3 +503,22 @@ fn const_with_hasher() {
const X: HashSet<(), ()> = HashSet::with_hasher(());
assert_eq!(X.len(), 0);
}

#[test]
fn test_insert_does_not_overwrite_the_value() {
let first_value = Arc::new(17);
let second_value = Arc::new(17);

let mut set = HashSet::new();
let inserted = set.insert(first_value.clone());
assert!(inserted);

let inserted = set.insert(second_value);
assert!(!inserted);

assert!(
Arc::ptr_eq(set.iter().next().unwrap(), &first_value),
"Insert must not overwrite the value, so the contained value pointer \
must be the same as first value pointer we inserted"
);
}

0 comments on commit e800d5a

Please sign in to comment.