about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-06-14 18:10:28 +0200
committerGitHub <noreply@github.com>2023-06-14 18:10:28 +0200
commitd54bb505d01ec8be7d549892db8500f37040cfe4 (patch)
tree1d631b34ca155c0c0411bfc7e4d6e676378d99a4
parent4efdb5c0015561bdaa6c00a79090a2080ef2c964 (diff)
parente800d5a0ec18e8296980737665880e97ad97db9a (diff)
downloadrust-d54bb505d01ec8be7d549892db8500f37040cfe4.tar.gz
rust-d54bb505d01ec8be7d549892db8500f37040cfe4.zip
Rollup merge of #107619 - stepancheg:hash-set-insert, r=Amanieu
Specify behavior of HashSet::insert

`HashSet::insert` does not replace the value with equal value.

Fixes #107581.
-rw-r--r--library/std/src/collections/hash/set.rs4
-rw-r--r--library/std/src/collections/hash/set/tests.rs20
2 files changed, 23 insertions, 1 deletions
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index ac906e682d5..99620610d1c 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -868,7 +868,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
     ///
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
index 941a0450cc7..022ca68ffcf 100644
--- a/library/std/src/collections/hash/set/tests.rs
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -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() {
@@ -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"
+    );
+}