Now informing the compiler of certain invariants in AsciiStrArr::len.

Removed certain impossible debug asserts.
This commit is contained in:
2020-10-21 00:35:33 +01:00
parent 9324f88a96
commit 00a527744c
3 changed files with 8 additions and 7 deletions

View File

@@ -24,8 +24,7 @@ pub struct AsciiStrArr<const N: usize> {
chars: [MaybeUninit<AsciiChar>; N],
/// Size
// Invariant `self.len <= N`
// Note: On all methods except `Self::len()`, one should call `self.len()` instead of using `self.len`.
// Invariant: `self.len <= N`
len: usize,
}
@@ -49,6 +48,9 @@ impl<const N: usize> AsciiStrArr<N> {
/// Returns the length of this string
#[must_use]
pub const fn len(&self) -> usize {
// Guarantee to the compiler len's invariant
// SAFETY: We guarantee this through a field invariant.
unsafe { std::intrinsics::assume(self.len <= N) };
self.len
}
@@ -87,7 +89,6 @@ impl<const N: usize> AsciiStrArr<N> {
// Then get a reference to them
// SAFETY: The first `self.len` elements are initialized
let chars = unsafe { MaybeUninit::slice_assume_init_ref(chars) };
debug_assert!(chars.len() == self.len());
<&AsciiStr>::from(chars)
}
@@ -103,7 +104,6 @@ impl<const N: usize> AsciiStrArr<N> {
// Then get a mutable reference to them
// SAFETY: The first `self.len` elements are initialized
let chars = unsafe { MaybeUninit::slice_assume_init_mut(chars) };
debug_assert!(chars.len() == len);
<&mut AsciiStr>::from(chars)
}

View File

@@ -45,7 +45,9 @@
maybe_uninit_uninit_array,
maybe_uninit_slice,
array_map,
const_mut_refs
const_mut_refs,
core_intrinsics,
const_assume
)]
// Lints
#![warn(clippy::restriction, clippy::pedantic, clippy::nursery)]

View File

@@ -42,10 +42,9 @@ macro impl_null_ascii_string($($N:expr),* $(,)?) {
#[allow(unused_comparisons)] // With N = 0 this function does nothing
fn write_string(&mut self, input: &AsciiStrArr<$N>) {
// Copy everything over and set the last byte to 0
// SAFETY: We guarantee `len <= N`.
// Note: No need to override the remaining bytes
// SAFETY: We guarantee `len <= N`.
let len = input.len();
debug_assert!(len <= $N);
unsafe { std::intrinsics::copy_nonoverlapping::<u8>(input.as_bytes().as_ptr(), self.as_mut_ptr(), len) };
*unsafe { self.get_unchecked_mut(len) } = 0;
}