Skip to content

Commit

Permalink
Always check bounds on inserting, no UB necessary fixed yegor256#193
Browse files Browse the repository at this point in the history
  • Loading branch information
FlareFlo committed May 20, 2024
1 parent 56c0187 commit 51a9d86
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 16 deletions.
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ use core::mem::MaybeUninit;
///
/// It is also faster because it doesn't grow in size. When a [`Map`] is created,
/// its size is fixed on stack. If an attempt is made to insert too many keys
/// into it, it simply panics. Moreover, in the "release" mode it doesn't panic,
/// but its behaviour is undefined. In the "release" mode all boundary checks
/// are disabled, for the sake of higher performance.
/// into it, it simply panics.
pub struct Map<K: PartialEq, V, const N: usize> {
/// The next available pair in the array.
len: usize,
Expand Down
8 changes: 2 additions & 6 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,7 @@ impl<K: PartialEq, V, const N: usize> Map<K, V, N> {
///
/// # Panics
///
/// It may panic if there are too many pairs in the map already. Pay attention,
/// it panics only in the "debug" mode. In the "release" mode, you are going to get
/// undefined behavior. This is done for the sake of performance, in order to
/// avoid a repetitive check for the boundary condition on every `insert()`.
/// It may panic if there are too many pairs in the map already.
#[inline]
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
let (_, existing_value) = self.insert_i(k, v);
Expand All @@ -168,8 +165,7 @@ impl<K: PartialEq, V, const N: usize> Map<K, V, N> {
let mut existing_value = None;
loop {
if i == self.len {
#[cfg(feature = "std")]
debug_assert!(target < N, "No more keys available in the map");
assert!(target < N, "No more keys available in the map");
break;
}
let p = self.item_ref(i);
Expand Down
5 changes: 1 addition & 4 deletions src/set/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ impl<T: PartialEq, const N: usize> Set<T, N> {
///
/// # Panics
///
/// It may panic if there are too many pairs in the set already. Pay attention,
/// it panics only in the "debug" mode. In the "release" mode, you are going to get
/// undefined behavior. This is done for the sake of performance, in order to
/// avoid a repetitive check for the boundary condition on every `insert()`.
/// It may panic if there are too many pairs in the set already.
#[inline]
pub fn insert(&mut self, k: T) -> bool {
self.map.insert(k, ()).is_none()
Expand Down
4 changes: 1 addition & 3 deletions src/set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ use crate::Map;
///
/// It is also faster because it doesn't grow in size. When a [`Set`] is created,
/// its size is fixed on stack. If an attempt is made to insert too many keys
/// into it, it simply panics. Moreover, in the "release" mode it doesn't panic,
/// but its behaviour is undefined. In the "release" mode all boundary checks
/// are disabled, for the sake of higher performance.
/// into it, it simply panics.
#[repr(transparent)]
pub struct Set<T: PartialEq, const N: usize> {
map: Map<T, (), N>,
Expand Down

0 comments on commit 51a9d86

Please sign in to comment.