From b66f2fd7c40ab376bda8615a1c0bcdd70e091003 Mon Sep 17 00:00:00 2001 From: Tristan Guichaoua <33934311+tguichaoua@users.noreply.github.com> Date: Wed, 31 Jan 2024 00:37:29 +0100 Subject: [PATCH] bevy_ptr: fix `unsafe_op_in_unsafe_fn` lint (#11610) # Objective - Part of #11590 ## Solution Fix `unsafe_op_in_unsafe_fn` for `bevy_ptr`. --- crates/bevy_ptr/src/lib.rs | 46 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 8551f78e5c02e..861219155e252 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -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::{ @@ -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, ) } @@ -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, ) } @@ -176,7 +176,9 @@ impl<'a, A: IsAligned> Ptr<'a, A> { /// for the pointee type `T`. #[inline] pub unsafe fn deref(self) -> &'a T { - &*self.as_ptr().cast::().debug_ensure_aligned() + let ptr = self.as_ptr().cast::().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. @@ -230,7 +232,9 @@ impl<'a, A: IsAligned> PtrMut<'a, A> { /// for the pointee type `T`. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { - &mut *self.as_ptr().cast::().debug_ensure_aligned() + let ptr = self.as_ptr().cast::().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. @@ -299,7 +303,9 @@ impl<'a, A: IsAligned> OwningPtr<'a, A> { /// for the pointee type `T`. #[inline] pub unsafe fn read(self) -> T { - self.as_ptr().cast::().debug_ensure_aligned().read() + let ptr = self.as_ptr().cast::().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`. @@ -310,10 +316,11 @@ impl<'a, A: IsAligned> OwningPtr<'a, A> { /// for the pointee type `T`. #[inline] pub unsafe fn drop_as(self) { - self.as_ptr() - .cast::() - .debug_ensure_aligned() - .drop_in_place(); + let ptr = self.as_ptr().cast::().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. @@ -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(self) -> T { - self.as_ptr().cast::().read_unaligned() + let ptr = self.as_ptr().cast::(); + // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`. + unsafe { ptr.read_unaligned() } } } @@ -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) } } } @@ -435,11 +446,13 @@ pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell { impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell { #[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] @@ -447,7 +460,8 @@ impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell { where T: Copy, { - self.get().read() + // SAFETY: The caller upholds the alias rules. + unsafe { self.get().read() } } }