From b20e23dd415b379ca2d91f1a9832c11087d42a15 Mon Sep 17 00:00:00 2001 From: mgi388 <135186256+mgi388@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:30:54 +1100 Subject: [PATCH] Add compile-time dyn compatible checks for `DynEq`, `DynHash` (#17254) # Objective - Shrink `bevy_utils` more. - Refs #11478 ## Solution - Removes `assert_object_safe` from `bevy_utils` by using a compile time check instead. ## Testing - CI. --- ## Migration Guide `assert_object_safe` is no longer exported by `bevy_utils`. Instead, you can write a compile time check that your trait is "dyn compatible": ```rust /// Assert MyTrait is dyn compatible const _: Option> = None; ``` --------- Co-authored-by: Alice Cecile --- crates/bevy_ecs/src/label.rs | 22 ++++++-------------- crates/bevy_utils/src/lib.rs | 2 -- crates/bevy_utils/src/object_safe.rs | 30 ---------------------------- 3 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 crates/bevy_utils/src/object_safe.rs diff --git a/crates/bevy_ecs/src/label.rs b/crates/bevy_ecs/src/label.rs index e3f5078b22f71..10a23cfb898c3 100644 --- a/crates/bevy_ecs/src/label.rs +++ b/crates/bevy_ecs/src/label.rs @@ -22,6 +22,9 @@ pub trait DynEq: Any { fn dyn_eq(&self, other: &dyn DynEq) -> bool; } +// Tests that this trait is dyn-compatible +const _: Option> = None; + impl DynEq for T where T: Any + Eq, @@ -48,6 +51,9 @@ pub trait DynHash: DynEq { fn dyn_hash(&self, state: &mut dyn Hasher); } +// Tests that this trait is dyn-compatible +const _: Option> = None; + impl DynHash for T where T: DynEq + Hash, @@ -201,19 +207,3 @@ macro_rules! define_label { $crate::intern::Interner::new(); }; } - -#[cfg(test)] -mod tests { - use super::{DynEq, DynHash}; - use bevy_utils::assert_object_safe; - - #[test] - fn dyn_eq_object_safe() { - assert_object_safe::(); - } - - #[test] - fn dyn_hash_object_safe() { - assert_object_safe::(); - } -} diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 73d12f319754b..0fd3fa6a7e0f3 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -26,8 +26,6 @@ pub mod synccell; pub mod syncunsafecell; mod default; -mod object_safe; -pub use object_safe::assert_object_safe; mod once; #[cfg(feature = "std")] mod parallel_queue; diff --git a/crates/bevy_utils/src/object_safe.rs b/crates/bevy_utils/src/object_safe.rs deleted file mode 100644 index 6e74d5ef82908..0000000000000 --- a/crates/bevy_utils/src/object_safe.rs +++ /dev/null @@ -1,30 +0,0 @@ -/// Assert that a given `T` is [object safe](https://doc.rust-lang.org/reference/items/traits.html#object-safety). -/// Will fail to compile if that is not the case. -/// -/// # Examples -/// -/// ```rust -/// # use bevy_utils::assert_object_safe; -/// // Concrete types are always object safe -/// struct MyStruct; -/// assert_object_safe::(); -/// -/// // Trait objects are where that safety comes into question. -/// // This trait is object safe... -/// trait ObjectSafe { } -/// assert_object_safe::(); -/// ``` -/// -/// ```compile_fail -/// # use bevy_utils::assert_object_safe; -/// // ...but this trait is not. -/// trait NotObjectSafe { -/// const VALUE: usize; -/// } -/// assert_object_safe::(); -/// // Error: the trait `NotObjectSafe` cannot be made into an object -/// ``` -pub fn assert_object_safe() { - // This space is left intentionally blank. The type parameter T is sufficient to induce a compiler - // error without a function body. -}