Skip to content

Commit

Permalink
Remove use of slice_ptr_get unstable feature
Browse files Browse the repository at this point in the history
**Description**
Replace use of `NonNull::<[T]>::get_unchecked_mut` function call with
a copy from the standard library.

This function is used to index into a pointer to a slice (`*const [T]`)
and return a pointer to an element (`*const T`) without doing bounds
checking.

**Motivation**
This change is a partial solution towards issue #20. The only remaining
unstable feature used is `hasher_prefixfree_extras`.

**Testing Done**
 - `cargo test`
 - `cargo miri test`
 - `cargo fmt`
 - `cargo clippy`
  • Loading branch information
Declan Kelly committed Nov 21, 2022
1 parent 044d058 commit 6e879e8
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO(#20): Use rust stable distribution, remove usage of nightly features
#![feature(slice_ptr_get, hasher_prefixfree_extras)]
#![feature(hasher_prefixfree_extras)]
#![allow(unstable_name_collisions)]
#![deny(
missing_docs,
Expand Down
18 changes: 18 additions & 0 deletions src/nightly_rust_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,21 @@ pub fn non_null_slice_from_raw_parts<T>(data: NonNull<T>, len: usize) -> NonNull
// SAFETY: `data` is a `NonNull` pointer which is necessarily non-null
unsafe { NonNull::<[T]>::new_unchecked(slice_from_raw_parts_mut(data.as_ptr(), len)) }
}

/// Returns a raw pointer to an element, without doing bounds checking.
///
/// Calling this method with an out-of-bounds index or when `data` is not
/// dereferenceable is *[undefined behavior]* even if the resulting pointer is
/// not used.
///
/// **This is a unstable API copied from the Rust standard library, tracking
/// issue is [#74265][issue-74265]**
///
/// [issue-74265]: https://github.com/rust-lang/rust/issues/74265
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
pub unsafe fn non_null_get_unchecked_mut<T>(data: NonNull<[T]>, index: usize) -> NonNull<T> {
// SAFETY: the caller ensures that `self` is dereferenceable and `index`
// in-bounds. As a consequence, the resulting pointer cannot be null.

unsafe { NonNull::new_unchecked(data.as_ptr().cast::<T>().add(index)) }
}
20 changes: 12 additions & 8 deletions src/nodes/representation/iterators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,10 +568,12 @@ impl<V> Iterator for InnerNode48Iter<V> {
// `initialized_child_pointers`, which returns the initialized portion of
// the `child_pointers` array.
let child_pointer = unsafe {
self.child_pointers_ptr
.get_unchecked_mut(usize::from(u8::from(next_index)))
.as_ptr()
.read()
crate::nightly_rust_apis::non_null_get_unchecked_mut(
self.child_pointers_ptr,
usize::from(u8::from(next_index)),
)
.as_ptr()
.read()
};

// SAFETY:
Expand Down Expand Up @@ -642,10 +644,12 @@ impl<V> DoubleEndedIterator for InnerNode48Iter<V> {
// `initialized_child_pointers`, which returns the initialized portion of
// the `child_pointers` array.
let child_pointer = unsafe {
self.child_pointers_ptr
.get_unchecked_mut(usize::from(u8::from(next_index)))
.as_ptr()
.read()
crate::nightly_rust_apis::non_null_get_unchecked_mut(
self.child_pointers_ptr,
usize::from(u8::from(next_index)),
)
.as_ptr()
.read()
};

// SAFETY:
Expand Down

0 comments on commit 6e879e8

Please sign in to comment.