Skip to content

Commit 1854f15

Browse files
Adapt code to the removal of const_compare_raw_pointers
1 parent c7578cb commit 1854f15

File tree

4 files changed

+21
-84
lines changed

4 files changed

+21
-84
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ repository = "https://github.com/slightlyoutofphase/staticvec"
55
documentation = "https://docs.rs/staticvec/"
66
license = "MIT OR Apache-2.0"
77
readme = "README.md"
8-
version = "0.10.0"
8+
version = "0.10.1"
99
authors = ["SlightlyOutOfPhase <[email protected]>"]
1010
keywords = ["vec", "array", "no_std", "vector", "stack"]
1111
categories = ["data-structures", "no-std"]

src/iterators.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use core::marker::{PhantomData, Send, Sync};
55
use core::mem::MaybeUninit;
66
use core::ptr;
77

8-
use crate::utils::{
9-
distance_between, is_null_const, is_null_mut, slice_from_raw_parts, slice_from_raw_parts_mut,
10-
};
8+
use crate::utils::{distance_between, slice_from_raw_parts, slice_from_raw_parts_mut};
119
use crate::StaticVec;
1210

1311
#[cfg(feature = "std")]
@@ -92,9 +90,9 @@ impl<'a, T: 'a, const N: usize> Iterator for StaticVecIterConst<'a, T, N> {
9290
// Safety: `self.start` and `self.end` are never null if `T` is not a ZST,
9391
// and the possibility that `self.end` specifically is null if `T` *is* a ZST
9492
// is accounted for.
95-
intrinsics::assume(!is_null_const(self.start));
93+
intrinsics::assume(!self.start.is_null());
9694
if intrinsics::size_of::<T>() != 0 {
97-
intrinsics::assume(!is_null_const(self.end));
95+
intrinsics::assume(!self.end.is_null());
9896
}
9997
match distance_between(self.end, self.start) {
10098
0 => None,
@@ -156,9 +154,9 @@ impl<'a, T: 'a, const N: usize> DoubleEndedIterator for StaticVecIterConst<'a, T
156154
// Safety: `self.start` and `self.end` are never null if `T` is not a ZST,
157155
// and the possibility that `self.end` specifically is null if `T` *is* a ZST
158156
// is accounted for.
159-
intrinsics::assume(!is_null_const(self.start));
157+
intrinsics::assume(!self.start.is_null());
160158
if intrinsics::size_of::<T>() != 0 {
161-
intrinsics::assume(!is_null_const(self.end));
159+
intrinsics::assume(!self.end.is_null());
162160
}
163161
match distance_between(self.end, self.start) {
164162
0 => None,
@@ -268,9 +266,9 @@ impl<'a, T: 'a, const N: usize> Iterator for StaticVecIterMut<'a, T, N> {
268266
// Safety: `self.start` and `self.end` are never null if `T` is not a ZST,
269267
// and the possibility that `self.end` specifically is null if `T` *is* a ZST
270268
// is accounted for.
271-
intrinsics::assume(!is_null_mut(self.start));
269+
intrinsics::assume(!self.start.is_null());
272270
if intrinsics::size_of::<T>() != 0 {
273-
intrinsics::assume(!is_null_mut(self.end));
271+
intrinsics::assume(!self.end.is_null());
274272
}
275273
match distance_between(self.end, self.start) {
276274
0 => None,
@@ -332,9 +330,9 @@ impl<'a, T: 'a, const N: usize> DoubleEndedIterator for StaticVecIterMut<'a, T,
332330
// Safety: `self.start` and `self.end` are never null if `T` is not a ZST,
333331
// and the possibility that `self.end` specifically is null if `T` *is* a ZST
334332
// is accounted for.
335-
intrinsics::assume(!is_null_mut(self.start));
333+
intrinsics::assume(!self.start.is_null());
336334
if intrinsics::size_of::<T>() != 0 {
337-
intrinsics::assume(!is_null_mut(self.end));
335+
intrinsics::assume(!self.end.is_null());
338336
}
339337
match distance_between(self.end, self.start) {
340338
0 => None,

src/lib.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
incomplete_features
2929
)]
3030
#![feature(
31-
const_compare_raw_pointers,
3231
const_fn,
3332
const_fn_union,
3433
const_generics,
@@ -74,8 +73,7 @@ pub use crate::iterators::{
7473
};
7574
pub use crate::string::{string_utils, StaticString, StringError};
7675
use crate::utils::{
77-
is_null_const, is_null_mut, quicksort_internal, reverse_copy, slice_from_raw_parts,
78-
slice_from_raw_parts_mut,
76+
quicksort_internal, reverse_copy, slice_from_raw_parts, slice_from_raw_parts_mut,
7977
};
8078

8179
#[cfg(any(feature = "std", rustdoc))]
@@ -1109,7 +1107,7 @@ impl<T, const N: usize> StaticVec<T, N> {
11091107
let start_ptr = self.as_ptr();
11101108
unsafe {
11111109
// `start_ptr` will never be null, so this is a safe assumption to give the optimizer.
1112-
intrinsics::assume(!is_null_const(start_ptr));
1110+
intrinsics::assume(!start_ptr.is_null());
11131111
StaticVecIterConst {
11141112
start: start_ptr,
11151113
end: match intrinsics::size_of::<T>() {
@@ -1138,7 +1136,7 @@ impl<T, const N: usize> StaticVec<T, N> {
11381136
let start_ptr = self.as_mut_ptr();
11391137
unsafe {
11401138
// `start_ptr` will never be null, so this is a safe assumption to give the optimizer.
1141-
intrinsics::assume(!is_null_mut(start_ptr));
1139+
intrinsics::assume(!start_ptr.is_null());
11421140
StaticVecIterMut {
11431141
start: start_ptr,
11441142
end: match intrinsics::size_of::<T>() {
@@ -1267,7 +1265,7 @@ impl<T, const N: usize> StaticVec<T, N> {
12671265
}
12681266
let self_ptr = self.as_mut_ptr();
12691267
// We know self_ptr will never be null, so this is a safe hint to give the optimizer.
1270-
unsafe { intrinsics::assume(!is_null_mut(self_ptr)) };
1268+
unsafe { intrinsics::assume(!self_ptr.is_null()) };
12711269
quicksort_internal(self_ptr, 0, (length - 1) as isize);
12721270
}
12731271

@@ -1778,7 +1776,7 @@ impl<T, const N: usize> StaticVec<T, N> {
17781776
let start_ptr = self.ptr_at_unchecked(start);
17791777
// `start_ptr` will never be null, so this is a safe assumption to give to
17801778
// the optimizer.
1781-
intrinsics::assume(!is_null_const(start_ptr));
1779+
intrinsics::assume(!start_ptr.is_null());
17821780
// Create the StaticVecDrain from the specified range.
17831781
StaticVecDrain {
17841782
start: end,

src/utils.rs

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use core::cmp::{Ordering, PartialOrd};
22
use core::intrinsics;
33
use core::mem::MaybeUninit;
4-
use core::ptr;
54

65
use crate::StaticVec;
76

@@ -35,8 +34,11 @@ where
3534
// function is called from, so these are safe hints to give to the
3635
// optimizer.
3736
unsafe {
38-
intrinsics::assume(!is_null_const(src));
39-
intrinsics::assume(!is_null_mut(dest));
37+
intrinsics::assume(!src.is_null());
38+
// Curiously, the explicit typecast to `*mut T` on the next line
39+
// is necessary to get it to compile. Without the typecast, `rustc` can't figure out
40+
// what the type is supposed to be for some reason.
41+
intrinsics::assume(!(dest as *mut T).is_null());
4042
}
4143
while i > 0 {
4244
unsafe {
@@ -103,7 +105,7 @@ pub(crate) fn quicksort_internal<T: Copy + PartialOrd>(
103105
// We call this function from exactly one place where `low` and `high` are known to be within an
104106
// appropriate range before getting passed into it, so there's no need to check them again here.
105107
// We also know that `values` will never be null, so we can safely give an optimizer hint here.
106-
unsafe { intrinsics::assume(!is_null_mut(values)) };
108+
unsafe { intrinsics::assume(!values.is_null()) };
107109
loop {
108110
let mut i = low;
109111
let mut j = high;
@@ -164,65 +166,9 @@ pub(crate) union Repr<T> {
164166
pub(crate) raw: FatPtr<T>,
165167
}
166168

167-
/// A local `const fn` version of `ptr.is_null()`.
168-
#[allow(clippy::cmp_null)]
169-
#[inline(always)]
170-
pub(crate) const fn is_null_const<T>(p: *const T) -> bool {
171-
// Same code as in the original.
172-
unsafe { (p as *const u8) == ptr::null() }
173-
}
174-
175-
/// A local `const fn` version of `ptr.is_null()`.
176-
#[allow(clippy::cmp_null)]
177-
#[inline(always)]
178-
pub(crate) const fn is_null_mut<T>(p: *mut T) -> bool {
179-
// Same code as in the original.
180-
unsafe { (p as *mut u8) == ptr::null_mut() }
181-
}
182-
183-
/// A local `const fn` version of the (private) `core::intrinsics::is_aligned_and_not_null` utility
184-
/// function, recreated here for the sake of wanting to be able to do exactly the same debug
185-
/// assertions in the slice methods below.
186-
#[inline(always)]
187-
pub(crate) const fn is_aligned_and_not_null_const<T>(_ptr: *const T) -> bool {
188-
// Same code as in the original, just using our local `const` function to do the null check.
189-
// unsafe { !is_null_const(ptr) && ptr as usize % core::mem::align_of::<T>() == 0 }
190-
191-
// Currently, the above code is not allowed in const contexts by the compiler even though we
192-
// have the appropriate feature flags set, so for the time being this function is a pass-through.
193-
//
194-
// IMO, this is perfectly justifiable as we only actually call the below slice methods internally
195-
// with pointers we already know are valid, and as such keeping the general-purpose debug
196-
// assertions from the original source at all is arguably completely unnecessary in the first
197-
// place.
198-
true
199-
}
200-
201-
/// A `mut` version of the above. Of course, you can pass `mut` pointers to functions taking `const`
202-
/// ones, but what the heck, it feels more symmetrical this way.
203-
#[inline(always)]
204-
pub(crate) const fn is_aligned_and_not_null_mut<T>(_ptr: *mut T) -> bool {
205-
// Same code as in the original, just using our local `const` function to do the null check.
206-
// unsafe { !is_null_mut(ptr) && ptr as usize % core::mem::align_of::<T>() == 0 }
207-
208-
// Currently, the above code is not allowed in const contexts by the compiler even though we
209-
// have the appropriate feature flags set, so for the time being this function is a pass-through.
210-
//
211-
// IMO, this is perfectly justifiable as we only actually call the below slice methods internally
212-
// with pointers we already know are valid, and as such keeping the general-purpose debug
213-
// assertions from the original source at all is arguably completely unnecessary in the first
214-
// place.
215-
true
216-
}
217-
218169
/// A local `const fn` version of `ptr::slice_from_raw_parts`.
219170
#[inline(always)]
220171
pub(crate) const fn ptr_slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
221-
// Same code as in the original, just using our local `const` functions where necessary.
222-
debug_assert!(
223-
is_aligned_and_not_null_const(data),
224-
"A null or unaligned pointer was passed to `staticvec::utils::ptr_slice_from_raw_parts`!"
225-
);
226172
debug_assert!(
227173
core::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
228174
"Attempted to create a slice covering at least half the address space!"
@@ -238,11 +184,6 @@ pub(crate) const fn ptr_slice_from_raw_parts<T>(data: *const T, len: usize) -> *
238184
/// A local `const fn` version of `ptr::slice_from_raw_parts_mut`.
239185
#[inline(always)]
240186
pub(crate) const fn ptr_slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
241-
// Same code as in the original, just using our local `const` functions where necessary.
242-
debug_assert!(
243-
is_aligned_and_not_null_mut(data),
244-
"A null or unaligned pointer was passed to `staticvec::utils::ptr_slice_from_raw_parts_mut`!"
245-
);
246187
debug_assert!(
247188
core::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
248189
"Attempted to create a slice covering at least half the address space!"

0 commit comments

Comments
 (0)