On Wed, Apr 16, 2025 at 01:36:05PM -0400, Tamir Duberstein wrote: > In Rust 1.51.0, Clippy introduced the `ptr_as_ptr` lint [1]: > > > Though `as` casts between raw pointers are not terrible, > > `pointer::cast` is safer because it cannot accidentally change the > > pointer's mutability, nor cast the pointer to other types like `usize`. > > There are a few classes of changes required: > - Modules generated by bindgen are marked > `#[allow(clippy::ptr_as_ptr)]`. > - Inferred casts (` as _`) are replaced with `.cast()`. > - Ascribed casts (` as *... T`) are replaced with `.cast::<T>()`. > - Multistep casts from references (` as *const _ as *const T`) are > replaced with `core::ptr::from_ref(&x).cast()` with or without `::<T>` > according to the previous rules. The `core::ptr::from_ref` call is > required because `(x as *const _).cast::<T>()` results in inference > failure. > - Native literal C strings are replaced with `c_str!().as_char_ptr()`. > - `*mut *mut T as _` is replaced with `let *mut *const T = (*mut *mut > T)`.cast();` since pointer to pointer can be confusing. > > Apply these changes and enable the lint -- no functional change > intended. > > Link: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr [1] > Reviewed-by: Benno Lossin <benno.los...@proton.me> > Signed-off-by: Tamir Duberstein <tam...@gmail.com>
Reviewed-by: Boqun Feng <boqun.f...@gmail.com> A few nits below though... > --- > Makefile | 1 + > rust/bindings/lib.rs | 1 + > rust/kernel/alloc/allocator_test.rs | 2 +- > rust/kernel/alloc/kvec.rs | 4 ++-- > rust/kernel/device.rs | 4 ++-- > rust/kernel/devres.rs | 2 +- > rust/kernel/dma.rs | 4 ++-- > rust/kernel/error.rs | 2 +- > rust/kernel/firmware.rs | 3 ++- > rust/kernel/fs/file.rs | 2 +- > rust/kernel/kunit.rs | 11 +++++++---- > rust/kernel/list/impl_list_item_mod.rs | 2 +- > rust/kernel/pci.rs | 2 +- > rust/kernel/platform.rs | 4 +++- > rust/kernel/print.rs | 6 +++--- > rust/kernel/seq_file.rs | 2 +- > rust/kernel/str.rs | 2 +- > rust/kernel/sync/poll.rs | 2 +- > rust/kernel/time/hrtimer/pin.rs | 2 +- > rust/kernel/time/hrtimer/pin_mut.rs | 2 +- > rust/kernel/workqueue.rs | 10 +++++----- > rust/uapi/lib.rs | 1 + > 22 files changed, 40 insertions(+), 31 deletions(-) > [...] > diff --git a/rust/kernel/list/impl_list_item_mod.rs > b/rust/kernel/list/impl_list_item_mod.rs > index a0438537cee1..1f9498c1458f 100644 > --- a/rust/kernel/list/impl_list_item_mod.rs > +++ b/rust/kernel/list/impl_list_item_mod.rs > @@ -34,7 +34,7 @@ pub unsafe trait HasListLinks<const ID: u64 = 0> { > unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut ListLinks<ID> { > // SAFETY: The caller promises that the pointer is valid. The > implementer promises that the > // `OFFSET` constant is correct. > - unsafe { (ptr as *mut u8).add(Self::OFFSET) as *mut ListLinks<ID> } > + unsafe { ptr.cast::<u8>().add(Self::OFFSET).cast() } I think we better do: unsafe { ptr.byte_add(Self::OFFSET).cast() } here, similar for a few instances below. Maybe in a follow-up patch? byte_add() is way more clear about what is done here. Regards, Boqun > } > } > [...] > @@ -457,7 +457,7 @@ fn get_work_offset(&self) -> usize { > #[inline] > unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID> { > // SAFETY: The caller promises that the pointer is valid. > - unsafe { (ptr as *mut u8).add(Self::OFFSET) as *mut Work<T, ID> } > + unsafe { ptr.cast::<u8>().add(Self::OFFSET).cast::<Work<T, ID>>() } > } > > /// Returns a pointer to the struct containing the [`Work<T, ID>`] field. > @@ -472,7 +472,7 @@ unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> > *mut Self > { > // SAFETY: The caller promises that the pointer points at a field of > the right type in the > // right kind of struct. > - unsafe { (ptr as *mut u8).sub(Self::OFFSET) as *mut Self } > + unsafe { ptr.cast::<u8>().sub(Self::OFFSET).cast::<Self>() } > } > } > [...]