From 2773b538b8944fa0744cd3da5a430bfe6df2c520 Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Fri, 15 Jan 2021 21:49:32 -0800 Subject: [PATCH 1/6] `get_unchecked` isn't unchecked This can be seen in the assembly generated by the `get_unchecked` function. Although there is no bounds checking on the array, it still checks whether the entry is occupied and so there is a branch and panic handling code due to the use of `unreachable!()`. I think that logically, both kinds of checking are the same type of error (you accessed an invalid index), so it makes sense for `get_unchecked` to do no branches at all, only address arithmetic. The only open question is whether the documentation should be adjusted to use a term other than "bounds checking" here since the set of valid slab indices is not an interval. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f267969..fb2e747 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -686,7 +686,7 @@ impl Slab { pub unsafe fn get_unchecked(&self, key: usize) -> &T { match *self.entries.get_unchecked(key) { Entry::Occupied(ref val) => val, - _ => unreachable!(), + _ => std::hint::unreachable_unchecked(), } } @@ -712,7 +712,7 @@ impl Slab { pub unsafe fn get_unchecked_mut(&mut self, key: usize) -> &mut T { match *self.entries.get_unchecked_mut(key) { Entry::Occupied(ref mut val) => val, - _ => unreachable!(), + _ => std::hint::unreachable_unchecked(), } } From 851fbcb55200ab69964f5844d242b2766be7e8ff Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sat, 30 Jan 2021 08:10:03 -0800 Subject: [PATCH 2/6] Update MSRV --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bc2955e..f533ddf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ matrix: env: RUSTFMT=1 # Minimum supported Rust version - - rust: 1.6.0 + - rust: 1.27.0 script: - cargo build From 8d022161e91f6fa97568e56598adc59a4c37c20f Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sat, 30 Jan 2021 15:19:37 -0800 Subject: [PATCH 3/6] fix for no_std --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3e4ac4c..322eb65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -750,7 +750,7 @@ impl Slab { pub unsafe fn get_unchecked(&self, key: usize) -> &T { match *self.entries.get_unchecked(key) { Entry::Occupied(ref val) => val, - _ => std::hint::unreachable_unchecked(), + _ => core::hint::unreachable_unchecked(), } } @@ -776,7 +776,7 @@ impl Slab { pub unsafe fn get_unchecked_mut(&mut self, key: usize) -> &mut T { match *self.entries.get_unchecked_mut(key) { Entry::Occupied(ref mut val) => val, - _ => std::hint::unreachable_unchecked(), + _ => core::hint::unreachable_unchecked(), } } From a3b40c4c1fe190f7025fdb17f2f95a5fcf2b75bf Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sat, 30 Jan 2021 18:31:39 -0500 Subject: [PATCH 4/6] fix for std/no_std hybrid --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 322eb65..45d5d57 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,13 +116,13 @@ use alloc::vec; use core::iter::FromIterator; #[cfg(not(feature = "std"))] -use core::{fmt, mem, ops, slice}; +use core::{fmt, mem, ops, slice, hint}; #[cfg(feature = "std")] use std::iter::FromIterator; #[cfg(feature = "std")] -use std::{fmt, mem, ops, slice, vec}; +use std::{fmt, mem, ops, slice, vec, hint}; /// Pre-allocated storage for a uniform data type /// @@ -750,7 +750,7 @@ impl Slab { pub unsafe fn get_unchecked(&self, key: usize) -> &T { match *self.entries.get_unchecked(key) { Entry::Occupied(ref val) => val, - _ => core::hint::unreachable_unchecked(), + _ => hint::unreachable_unchecked(), } } @@ -776,7 +776,7 @@ impl Slab { pub unsafe fn get_unchecked_mut(&mut self, key: usize) -> &mut T { match *self.entries.get_unchecked_mut(key) { Entry::Occupied(ref mut val) => val, - _ => core::hint::unreachable_unchecked(), + _ => hint::unreachable_unchecked(), } } From 1c4839b87361147971cb9a8f5aafe2c4672d14ae Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sat, 30 Jan 2021 18:33:26 -0500 Subject: [PATCH 5/6] rustfmt --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 45d5d57..293d5eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,13 +116,13 @@ use alloc::vec; use core::iter::FromIterator; #[cfg(not(feature = "std"))] -use core::{fmt, mem, ops, slice, hint}; +use core::{fmt, hint, mem, ops, slice}; #[cfg(feature = "std")] use std::iter::FromIterator; #[cfg(feature = "std")] -use std::{fmt, mem, ops, slice, vec, hint}; +use std::{fmt, hint, mem, ops, slice, vec}; /// Pre-allocated storage for a uniform data type /// From 44c276e7b4eba0abcc337d078df2b28d139e47de Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sun, 31 Jan 2021 04:10:22 -0500 Subject: [PATCH 6/6] add docs from fd1f687 --- src/lib.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 293d5eb..b72f76c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -732,9 +732,12 @@ impl Slab { } /// Return a reference to the value associated with the given key without - /// performing bounds checking. + /// without checking that there is an element associated with that key. /// - /// This function should be used with care. + /// # Safety + /// + /// * The key must be within bounds + /// * There must be a value present at the slot the key refers to /// /// # Examples /// @@ -755,9 +758,12 @@ impl Slab { } /// Return a mutable reference to the value associated with the given key - /// without performing bounds checking. + /// without checking that there is an element associated with that key. /// - /// This function should be used with care. + /// # Safety + /// + /// * The key must be within bounds + /// * There must be a value present at the slot the key refers to /// /// # Examples ///