Skip to content

Commit

Permalink
bevy_ptr: fix unsafe_op_in_unsafe_fn lint (bevyengine#11610)
Browse files Browse the repository at this point in the history
# Objective

- Part of bevyengine#11590

## Solution

Fix `unsafe_op_in_unsafe_fn` for `bevy_ptr`.
  • Loading branch information
tguichaoua authored and tjamaan committed Feb 6, 2024
1 parent 012ab55 commit 870b364
Showing 1 changed file with 30 additions and 16 deletions.
46 changes: 30 additions & 16 deletions crates/bevy_ptr/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#![doc = include_str!("../README.md")]
#![no_std]
#![warn(missing_docs)]
// FIXME(11590): remove this once the lint is fixed
#![allow(unsafe_op_in_unsafe_fn)]

use core::fmt::{self, Formatter, Pointer};
use core::{
Expand Down Expand Up @@ -106,7 +104,8 @@ macro_rules! impl_ptr {
#[inline]
pub unsafe fn byte_offset(self, count: isize) -> Self {
Self(
NonNull::new_unchecked(self.as_ptr().offset(count)),
// SAFETY: The caller upholds safety for `offset` and ensures the result is not null.
unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
PhantomData,
)
}
Expand All @@ -126,7 +125,8 @@ macro_rules! impl_ptr {
#[inline]
pub unsafe fn byte_add(self, count: usize) -> Self {
Self(
NonNull::new_unchecked(self.as_ptr().add(count)),
// SAFETY: The caller upholds safety for `add` and ensures the result is not null.
unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
PhantomData,
)
}
Expand Down Expand Up @@ -176,7 +176,9 @@ impl<'a, A: IsAligned> Ptr<'a, A> {
/// for the pointee type `T`.
#[inline]
pub unsafe fn deref<T>(self) -> &'a T {
&*self.as_ptr().cast::<T>().debug_ensure_aligned()
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
unsafe { &*ptr }
}

/// Gets the underlying pointer, erasing the associated lifetime.
Expand Down Expand Up @@ -230,7 +232,9 @@ impl<'a, A: IsAligned> PtrMut<'a, A> {
/// for the pointee type `T`.
#[inline]
pub unsafe fn deref_mut<T>(self) -> &'a mut T {
&mut *self.as_ptr().cast::<T>().debug_ensure_aligned()
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
unsafe { &mut *ptr }
}

/// Gets the underlying pointer, erasing the associated lifetime.
Expand Down Expand Up @@ -299,7 +303,9 @@ impl<'a, A: IsAligned> OwningPtr<'a, A> {
/// for the pointee type `T`.
#[inline]
pub unsafe fn read<T>(self) -> T {
self.as_ptr().cast::<T>().debug_ensure_aligned().read()
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
unsafe { ptr.read() }
}

/// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
Expand All @@ -310,10 +316,11 @@ impl<'a, A: IsAligned> OwningPtr<'a, A> {
/// for the pointee type `T`.
#[inline]
pub unsafe fn drop_as<T>(self) {
self.as_ptr()
.cast::<T>()
.debug_ensure_aligned()
.drop_in_place();
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
unsafe {
ptr.drop_in_place();
}
}

/// Gets the underlying pointer, erasing the associated lifetime.
Expand Down Expand Up @@ -346,7 +353,9 @@ impl<'a> OwningPtr<'a, Unaligned> {
/// # Safety
/// - `T` must be the erased pointee type for this [`OwningPtr`].
pub unsafe fn read_unaligned<T>(self) -> T {
self.as_ptr().cast::<T>().read_unaligned()
let ptr = self.as_ptr().cast::<T>();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
unsafe { ptr.read_unaligned() }
}
}

Expand All @@ -368,7 +377,9 @@ impl<'a, T> ThinSlicePtr<'a, T> {
#[cfg(debug_assertions)]
debug_assert!(index < self.len);

&*self.ptr.as_ptr().add(index)
let ptr = self.ptr.as_ptr();
// SAFETY: `index` is in-bounds so the resulting pointer is valid to dereference.
unsafe { &*ptr.add(index) }
}
}

Expand Down Expand Up @@ -435,19 +446,22 @@ pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
#[inline]
unsafe fn deref_mut(self) -> &'a mut T {
&mut *self.get()
// SAFETY: The caller upholds the alias rules.
unsafe { &mut *self.get() }
}
#[inline]
unsafe fn deref(self) -> &'a T {
&*self.get()
// SAFETY: The caller upholds the alias rules.
unsafe { &*self.get() }
}

#[inline]
unsafe fn read(self) -> T
where
T: Copy,
{
self.get().read()
// SAFETY: The caller upholds the alias rules.
unsafe { self.get().read() }
}
}

Expand Down

0 comments on commit 870b364

Please sign in to comment.