Skip to content

Commit c1a4e29

Browse files
authored
Replace pointer castings (as) by their API equivalent (#11818)
# Objective Since rust `1.76`, [`ptr::from_ref`](https://doc.rust-lang.org/stable/std/ptr/fn.from_ref.html) and [`ptr::from_mut`](https://doc.rust-lang.org/stable/std/ptr/fn.from_mut.html) are stable. This PR replaces code that use `as` casting by one of `ptr::from_ref`, `ptr::from_mut`, `cast_mut`, `cast_const`, or `cast` methods, which are less error-prone. ## Solution - Bump MSRV to `1.76.0` - Enables the following clippy lints: - [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#/ptr_as_ptr) - [`ptr_cast_constness`](https://rust-lang.github.io/rust-clippy/master/index.html#/ptr_cast_constness) - [`ref_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#/ref_as_ptr) (I fix all warnings for this one, but it requires rust 1.77 to be enabled) - Fix the lints mentioned above
1 parent 94ab84e commit c1a4e29

File tree

7 files changed

+21
-12
lines changed

7 files changed

+21
-12
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
1111
readme = "README.md"
1212
repository = "https://github.com/bevyengine/bevy"
1313
documentation = "https://docs.rs/bevy"
14-
rust-version = "1.74.0"
14+
rust-version = "1.76.0"
1515

1616
[workspace]
1717
exclude = [
@@ -40,6 +40,11 @@ match_same_arms = "warn"
4040
semicolon_if_nothing_returned = "warn"
4141
map_flatten = "warn"
4242

43+
ptr_as_ptr = "warn"
44+
ptr_cast_constness = "warn"
45+
#TODO(rust 1.77): enable `ref_as_ptr`
46+
# ref_as_ptr = "warn"
47+
4348
[workspace.lints.rust]
4449
unsafe_op_in_unsafe_fn = "warn"
4550
missing_docs = "warn"

crates/bevy_ecs/src/query/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
#[cfg(feature = "trace")]
1515
use bevy_utils::tracing::Span;
1616
use fixedbitset::FixedBitSet;
17-
use std::{any::TypeId, borrow::Borrow, fmt, mem::MaybeUninit};
17+
use std::{any::TypeId, borrow::Borrow, fmt, mem::MaybeUninit, ptr};
1818

1919
use super::{
2020
NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter,
@@ -93,7 +93,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
9393
>(
9494
&self,
9595
) -> &QueryState<NewD, NewF> {
96-
&*(self as *const QueryState<D, F> as *const QueryState<NewD, NewF>)
96+
&*ptr::from_ref(self).cast::<QueryState<NewD, NewF>>()
9797
}
9898

9999
/// Returns the archetype components accessed by this query.

crates/bevy_ecs/src/world/unsafe_world_cell.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
system::{Res, Resource},
1818
};
1919
use bevy_ptr::Ptr;
20-
use std::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData};
20+
use std::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr};
2121

2222
/// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid
2323
/// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule.
@@ -85,13 +85,13 @@ impl<'w> UnsafeWorldCell<'w> {
8585
/// Creates a [`UnsafeWorldCell`] that can be used to access everything immutably
8686
#[inline]
8787
pub(crate) fn new_readonly(world: &'w World) -> Self {
88-
UnsafeWorldCell(world as *const World as *mut World, PhantomData)
88+
Self(ptr::from_ref(world).cast_mut(), PhantomData)
8989
}
9090

9191
/// Creates [`UnsafeWorldCell`] that can be used to access everything mutably
9292
#[inline]
9393
pub(crate) fn new_mutable(world: &'w mut World) -> Self {
94-
Self(world as *mut World, PhantomData)
94+
Self(ptr::from_mut(world), PhantomData)
9595
}
9696

9797
/// Gets a mutable reference to the [`World`] this [`UnsafeWorldCell`] belongs to.

crates/bevy_mikktspace/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#![allow(
22
unsafe_op_in_unsafe_fn,
33
clippy::all,
4-
clippy::undocumented_unsafe_blocks
4+
clippy::undocumented_unsafe_blocks,
5+
clippy::ptr_cast_constness
56
)]
67
// FIXME(3492): remove once docs are ready
78
#![allow(missing_docs)]

crates/bevy_ptr/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
393393
impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
394394
#[inline]
395395
fn from(slice: &'a [T]) -> Self {
396-
let ptr = slice.as_ptr() as *mut T;
396+
let ptr = slice.as_ptr().cast_mut();
397397
Self {
398398
// SAFETY: a reference can never be null
399399
ptr: unsafe { NonNull::new_unchecked(ptr.debug_ensure_aligned()) },

crates/bevy_utils/src/synccell.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//!
33
//! [`std::sync::Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
44
5+
use std::ptr;
6+
57
/// See [`Exclusive`](https://github.com/rust-lang/rust/issues/98407) for stdlib's upcoming implementation,
68
/// which should replace this one entirely.
79
///
@@ -41,7 +43,7 @@ impl<T: ?Sized> SyncCell<T> {
4143
/// to its inner value, to skip constructing with [`new()`](SyncCell::new()).
4244
pub fn from_mut(r: &'_ mut T) -> &'_ mut SyncCell<T> {
4345
// SAFETY: repr is transparent, so refs have the same layout; and `SyncCell` properties are `&mut`-agnostic
44-
unsafe { &mut *(r as *mut T as *mut SyncCell<T>) }
46+
unsafe { &mut *(ptr::from_mut(r) as *mut SyncCell<T>) }
4547
}
4648
}
4749

crates/bevy_utils/src/syncunsafecell.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! [`std::cell::SyncUnsafeCell`]: https://doc.rust-lang.org/nightly/std/cell/struct.SyncUnsafeCell.html
44
55
pub use core::cell::UnsafeCell;
6+
use core::ptr;
67

78
/// [`UnsafeCell`], but [`Sync`].
89
///
@@ -72,13 +73,13 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
7273
// We can just cast the pointer from `SyncUnsafeCell<T>` to `T` because
7374
// of #[repr(transparent)] on both SyncUnsafeCell and UnsafeCell.
7475
// See UnsafeCell::raw_get.
75-
this as *const T as *mut T
76+
(this as *const T).cast_mut()
7677
}
7778

7879
#[inline]
7980
/// Returns a `&mut SyncUnsafeCell<T>` from a `&mut T`.
8081
pub fn from_mut(t: &mut T) -> &mut SyncUnsafeCell<T> {
81-
let ptr = t as *mut T as *mut SyncUnsafeCell<T>;
82+
let ptr = ptr::from_mut(t) as *mut SyncUnsafeCell<T>;
8283
// SAFETY: `ptr` must be safe to mutably dereference, since it was originally
8384
// obtained from a mutable reference. `SyncUnsafeCell` has the same representation
8485
// as the original type `T`, since the former is annotated with #[repr(transparent)].
@@ -105,7 +106,7 @@ impl<T> SyncUnsafeCell<[T]> {
105106
// - `SyncUnsafeCell<T>` has the same layout as `T`
106107
// - `SyncUnsafeCell<[T]>` has the same layout as `[T]`
107108
// - `SyncUnsafeCell<[T]>` has the same layout as `[SyncUnsafeCell<T>]`
108-
unsafe { &*(self as *const SyncUnsafeCell<[T]> as *const [SyncUnsafeCell<T>]) }
109+
unsafe { &*(ptr::from_ref(self) as *const [SyncUnsafeCell<T>]) }
109110
}
110111
}
111112

0 commit comments

Comments
 (0)