Skip to content

Commit

Permalink
Add an assertion to HashSet::get_or_insert_with
Browse files Browse the repository at this point in the history
Since the Rust libs-api team considers it problematic for `HashSet<T>`
to be unreliable with well-behaved `T` (not user-controlled), we should
not allow mismatches to be inserted through `get_or_insert_with`.
  • Loading branch information
cuviper committed Apr 9, 2024
1 parent 97c2140 commit 03f5a41
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,10 @@ where
/// Inserts a value computed from `f` into the set if the given `value` is
/// not present, then returns a reference to the value in the set.
///
/// # Panics
///
/// Will panic if `f`'s return value is not equivalent to the query `value`.
///
/// # Examples
///
/// ```
Expand All @@ -970,6 +974,13 @@ where
/// }
/// assert_eq!(set.len(), 4); // a new "fish" was inserted
/// ```
///
/// The following example will panic because the new value doesn't match.
///
/// ```should_panic
/// let mut set = hashbrown::HashSet::new();
/// set.get_or_insert_with("rust", |_| String::new());
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
where
Expand All @@ -981,7 +992,11 @@ where
self.map
.raw_entry_mut()
.from_key(value)
.or_insert_with(|| (f(value), ()))
.or_insert_with(|| {
let new = f(value);
assert!(value.equivalent(&new), "new value is not equivalent");
(new, ())
})
.0
}

Expand Down

0 comments on commit 03f5a41

Please sign in to comment.