Remove uses of Option::unwrap_unchecked as a safety precaution (#2310)

This commit is contained in:
marc0246 2023-08-26 17:13:40 +02:00 committed by GitHub
parent 04d22e8052
commit 4ee8aa5f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 5 deletions

View File

@ -129,11 +129,9 @@ impl<T: ?Sized> Subbuffer<T> {
/// [`MappingState::slice`]: crate::memory::MappingState::slice
pub fn mapped_slice(&self) -> Result<NonNull<[u8]>, HostAccessError> {
match self.buffer().memory() {
BufferMemory::Normal(a) => {
let opt = a.mapped_slice(self.range());
BufferMemory::Normal(allocation) => {
// SAFETY: `self.range()` is in bounds of the allocation.
unsafe { opt.unwrap_unchecked() }
unsafe { allocation.mapped_slice_unchecked(self.range()) }
}
BufferMemory::Sparse => unreachable!(),
}
@ -510,7 +508,7 @@ impl<T> Subbuffer<[T]> {
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn slice_unchecked(mut self, range: impl RangeBounds<DeviceSize>) -> Subbuffer<[T]> {
let Range { start, end } = memory::range(range, ..self.len()).unwrap_unchecked();
let Range { start, end } = memory::range_unchecked(range, ..self.len());
self.offset += start * size_of::<T>() as DeviceSize;
self.size = (end - start) * size_of::<T>() as DeviceSize;

View File

@ -157,6 +157,23 @@ impl MemoryAlloc {
Some(res)
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn mapped_slice_unchecked(
&self,
range: impl RangeBounds<DeviceSize>,
) -> Result<NonNull<[u8]>, HostAccessError> {
let mut range = memory::range_unchecked(range, ..self.size());
range.start += self.offset();
range.end += self.offset();
if let Some(state) = self.device_memory().mapping_state() {
state.slice(range).ok_or(HostAccessError::OutOfMappedRange)
} else {
Err(HostAccessError::NotHostMapped)
}
}
pub(crate) fn atom_size(&self) -> Option<DeviceAlignment> {
self.atom_size
}

View File

@ -590,3 +590,27 @@ pub(crate) fn range(
(start <= end && end <= len).then_some(Range { start, end })
}
/// Converts a `RangeBounds` into a `Range` without doing any bounds checking.
pub(crate) fn range_unchecked(
range: impl RangeBounds<DeviceSize>,
bounds: RangeTo<DeviceSize>,
) -> Range<DeviceSize> {
let len = bounds.end;
let start = match range.start_bound() {
Bound::Included(&start) => start,
Bound::Excluded(start) => start + 1,
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(end) => end + 1,
Bound::Excluded(&end) => end,
Bound::Unbounded => len,
};
debug_assert!(start <= end && end <= len);
Range { start, end }
}