Remove upcasting methods + Cleanup interned label code (#18984)
Hiya! # Objective - Remove upcasting methods that are no longer necessary since Rust 1.86. - Cleanup the interned label code. ## Notes - I didn't try to remove the upcasting methods from `bevy_reflect`, as there appears to be some complexity related to remote type reflection. - There are likely some other upcasting methods floating around. ## Testing I ran the `breakout` example to check that the hashing/eq implementations of the labels are still correct. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
93b8f9a303
commit
4924cf5828
@ -10,7 +10,7 @@ keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/bevyengine/bevy"
|
||||
documentation = "https://docs.rs/bevy"
|
||||
rust-version = "1.85.0"
|
||||
rust-version = "1.86.0"
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
|
@ -205,8 +205,6 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream {
|
||||
pub fn derive_app_label(input: TokenStream) -> TokenStream {
|
||||
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||
let mut trait_path = BevyManifest::shared().get_path("bevy_app");
|
||||
let mut dyn_eq_path = trait_path.clone();
|
||||
trait_path.segments.push(format_ident!("AppLabel").into());
|
||||
dyn_eq_path.segments.push(format_ident!("DynEq").into());
|
||||
derive_label(input, "AppLabel", &trait_path, &dyn_eq_path)
|
||||
derive_label(input, "AppLabel", &trait_path)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ repository = "https://github.com/bevyengine/bevy"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["ecs", "game", "bevy"]
|
||||
categories = ["game-engines", "data-structures"]
|
||||
rust-version = "1.85.0"
|
||||
rust-version = "1.86.0"
|
||||
|
||||
[features]
|
||||
default = ["std", "bevy_reflect", "async_executor", "backtrace"]
|
||||
|
@ -503,12 +503,10 @@ pub fn derive_schedule_label(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let mut trait_path = bevy_ecs_path();
|
||||
trait_path.segments.push(format_ident!("schedule").into());
|
||||
let mut dyn_eq_path = trait_path.clone();
|
||||
trait_path
|
||||
.segments
|
||||
.push(format_ident!("ScheduleLabel").into());
|
||||
dyn_eq_path.segments.push(format_ident!("DynEq").into());
|
||||
derive_label(input, "ScheduleLabel", &trait_path, &dyn_eq_path)
|
||||
derive_label(input, "ScheduleLabel", &trait_path)
|
||||
}
|
||||
|
||||
/// Derive macro generating an impl of the trait `SystemSet`.
|
||||
@ -519,10 +517,8 @@ pub fn derive_system_set(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let mut trait_path = bevy_ecs_path();
|
||||
trait_path.segments.push(format_ident!("schedule").into());
|
||||
let mut dyn_eq_path = trait_path.clone();
|
||||
trait_path.segments.push(format_ident!("SystemSet").into());
|
||||
dyn_eq_path.segments.push(format_ident!("DynEq").into());
|
||||
derive_label(input, "SystemSet", &trait_path, &dyn_eq_path)
|
||||
derive_label(input, "SystemSet", &trait_path)
|
||||
}
|
||||
|
||||
pub(crate) fn bevy_ecs_path() -> syn::Path {
|
||||
|
@ -12,9 +12,6 @@ pub use alloc::boxed::Box;
|
||||
/// An object safe version of [`Eq`]. This trait is automatically implemented
|
||||
/// for any `'static` type that implements `Eq`.
|
||||
pub trait DynEq: Any {
|
||||
/// Casts the type to `dyn Any`.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
/// This method tests for `self` and `other` values to be equal.
|
||||
///
|
||||
/// Implementers should avoid returning `true` when the underlying types are
|
||||
@ -29,12 +26,8 @@ impl<T> DynEq for T
|
||||
where
|
||||
T: Any + Eq,
|
||||
{
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_eq(&self, other: &dyn DynEq) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<T>() {
|
||||
if let Some(other) = (other as &dyn Any).downcast_ref::<T>() {
|
||||
return self == other;
|
||||
}
|
||||
false
|
||||
@ -44,9 +37,6 @@ where
|
||||
/// An object safe version of [`Hash`]. This trait is automatically implemented
|
||||
/// for any `'static` type that implements `Hash`.
|
||||
pub trait DynHash: DynEq {
|
||||
/// Casts the type to `dyn Any`.
|
||||
fn as_dyn_eq(&self) -> &dyn DynEq;
|
||||
|
||||
/// Feeds this value into the given [`Hasher`].
|
||||
fn dyn_hash(&self, state: &mut dyn Hasher);
|
||||
}
|
||||
@ -58,10 +48,6 @@ impl<T> DynHash for T
|
||||
where
|
||||
T: DynEq + Hash,
|
||||
{
|
||||
fn as_dyn_eq(&self) -> &dyn DynEq {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
|
||||
T::hash(self, &mut state);
|
||||
self.type_id().hash(&mut state);
|
||||
@ -120,7 +106,7 @@ macro_rules! define_label {
|
||||
) => {
|
||||
|
||||
$(#[$label_attr])*
|
||||
pub trait $label_trait_name: 'static + Send + Sync + ::core::fmt::Debug {
|
||||
pub trait $label_trait_name: Send + Sync + ::core::fmt::Debug + $crate::label::DynEq + $crate::label::DynHash {
|
||||
|
||||
$($trait_extra_methods)*
|
||||
|
||||
@ -129,12 +115,6 @@ macro_rules! define_label {
|
||||
///`.
|
||||
fn dyn_clone(&self) -> $crate::label::Box<dyn $label_trait_name>;
|
||||
|
||||
/// Casts this value to a form where it can be compared with other type-erased values.
|
||||
fn as_dyn_eq(&self) -> &dyn $crate::label::DynEq;
|
||||
|
||||
/// Feeds this value into the given [`Hasher`].
|
||||
fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher);
|
||||
|
||||
/// Returns an [`Interned`] value corresponding to `self`.
|
||||
fn intern(&self) -> $crate::intern::Interned<dyn $label_trait_name>
|
||||
where Self: Sized {
|
||||
@ -151,15 +131,6 @@ macro_rules! define_label {
|
||||
(**self).dyn_clone()
|
||||
}
|
||||
|
||||
/// Casts this value to a form where it can be compared with other type-erased values.
|
||||
fn as_dyn_eq(&self) -> &dyn $crate::label::DynEq {
|
||||
(**self).as_dyn_eq()
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher) {
|
||||
(**self).dyn_hash(state);
|
||||
}
|
||||
|
||||
fn intern(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
@ -167,7 +138,7 @@ macro_rules! define_label {
|
||||
|
||||
impl PartialEq for dyn $label_trait_name {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_dyn_eq().dyn_eq(other.as_dyn_eq())
|
||||
self.dyn_eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +159,7 @@ macro_rules! define_label {
|
||||
use ::core::ptr;
|
||||
|
||||
// Test that both the type id and pointer address are equivalent.
|
||||
self.as_dyn_eq().type_id() == other.as_dyn_eq().type_id()
|
||||
self.type_id() == other.type_id()
|
||||
&& ptr::addr_eq(ptr::from_ref::<Self>(self), ptr::from_ref::<Self>(other))
|
||||
}
|
||||
|
||||
@ -196,7 +167,7 @@ macro_rules! define_label {
|
||||
use ::core::{hash::Hash, ptr};
|
||||
|
||||
// Hash the type id...
|
||||
self.as_dyn_eq().type_id().hash(state);
|
||||
self.type_id().hash(state);
|
||||
|
||||
// ...and the pointer address.
|
||||
// Cast to a unit `()` first to discard any pointer metadata.
|
||||
|
@ -147,15 +147,6 @@ impl<T> SystemSet for SystemTypeSet<T> {
|
||||
fn dyn_clone(&self) -> Box<dyn SystemSet> {
|
||||
Box::new(*self)
|
||||
}
|
||||
|
||||
fn as_dyn_eq(&self) -> &dyn DynEq {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
|
||||
TypeId::of::<Self>().hash(&mut state);
|
||||
self.hash(&mut state);
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`SystemSet`] implicitly created when using
|
||||
@ -178,15 +169,6 @@ impl SystemSet for AnonymousSet {
|
||||
fn dyn_clone(&self) -> Box<dyn SystemSet> {
|
||||
Box::new(*self)
|
||||
}
|
||||
|
||||
fn as_dyn_eq(&self) -> &dyn DynEq {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
|
||||
TypeId::of::<Self>().hash(&mut state);
|
||||
self.hash(&mut state);
|
||||
}
|
||||
}
|
||||
|
||||
/// Types that can be converted into a [`SystemSet`].
|
||||
|
@ -2510,10 +2510,7 @@ impl DynSystemParamState {
|
||||
}
|
||||
|
||||
/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
|
||||
trait DynParamState: Sync + Send {
|
||||
/// Casts the underlying `ParamState<T>` to an `Any` so it can be downcast.
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
|
||||
trait DynParamState: Sync + Send + Any {
|
||||
/// For the specified [`Archetype`], registers the components accessed by this [`SystemParam`] (if applicable).a
|
||||
///
|
||||
/// # Safety
|
||||
@ -2544,10 +2541,6 @@ trait DynParamState: Sync + Send {
|
||||
struct ParamState<T: SystemParam>(T::State);
|
||||
|
||||
impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
|
||||
// SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
|
||||
unsafe { T::new_archetype(&mut self.0, archetype, system_meta) };
|
||||
@ -2597,18 +2590,11 @@ unsafe impl SystemParam for DynSystemParam<'_, '_> {
|
||||
change_tick: Tick,
|
||||
) -> Self::Item<'world, 'state> {
|
||||
// SAFETY:
|
||||
// - `state.0` is a boxed `ParamState<T>`, and its implementation of `as_any_mut` returns `self`.
|
||||
// - `state.0` is a boxed `ParamState<T>`.
|
||||
// - The state was obtained from `SystemParamBuilder::build()`, which registers all [`World`] accesses used
|
||||
// by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
|
||||
// - The caller ensures that the provided world is the same and has the required access.
|
||||
unsafe {
|
||||
DynSystemParam::new(
|
||||
state.0.as_any_mut(),
|
||||
world,
|
||||
system_meta.clone(),
|
||||
change_tick,
|
||||
)
|
||||
}
|
||||
unsafe { DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick) }
|
||||
}
|
||||
|
||||
unsafe fn new_archetype(
|
||||
|
@ -58,7 +58,6 @@ pub fn derive_label(
|
||||
input: syn::DeriveInput,
|
||||
trait_name: &str,
|
||||
trait_path: &syn::Path,
|
||||
dyn_eq_path: &syn::Path,
|
||||
) -> TokenStream {
|
||||
if let syn::Data::Union(_) = &input.data {
|
||||
let message = format!("Cannot derive {trait_name} for unions.");
|
||||
@ -89,16 +88,6 @@ pub fn derive_label(
|
||||
fn dyn_clone(&self) -> alloc::boxed::Box<dyn #trait_path> {
|
||||
alloc::boxed::Box::new(::core::clone::Clone::clone(self))
|
||||
}
|
||||
|
||||
fn as_dyn_eq(&self) -> &dyn #dyn_eq_path {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) {
|
||||
let ty_id = ::core::any::TypeId::of::<Self>();
|
||||
::core::hash::Hash::hash(&ty_id, &mut state);
|
||||
::core::hash::Hash::hash(self, &mut state);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -80,12 +80,10 @@ pub fn derive_render_label(input: TokenStream) -> TokenStream {
|
||||
trait_path
|
||||
.segments
|
||||
.push(format_ident!("render_graph").into());
|
||||
let mut dyn_eq_path = trait_path.clone();
|
||||
trait_path
|
||||
.segments
|
||||
.push(format_ident!("RenderLabel").into());
|
||||
dyn_eq_path.segments.push(format_ident!("DynEq").into());
|
||||
derive_label(input, "RenderLabel", &trait_path, &dyn_eq_path)
|
||||
derive_label(input, "RenderLabel", &trait_path)
|
||||
}
|
||||
|
||||
/// Derive macro generating an impl of the trait `RenderSubGraph`.
|
||||
@ -98,10 +96,8 @@ pub fn derive_render_sub_graph(input: TokenStream) -> TokenStream {
|
||||
trait_path
|
||||
.segments
|
||||
.push(format_ident!("render_graph").into());
|
||||
let mut dyn_eq_path = trait_path.clone();
|
||||
trait_path
|
||||
.segments
|
||||
.push(format_ident!("RenderSubGraph").into());
|
||||
dyn_eq_path.segments.push(format_ident!("DynEq").into());
|
||||
derive_label(input, "RenderSubGraph", &trait_path, &dyn_eq_path)
|
||||
derive_label(input, "RenderSubGraph", &trait_path)
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Interned labels cleanup
|
||||
pull_requests: [18984]
|
||||
---
|
||||
|
||||
- `DynEq::as_any` has been removed. Use `&value as &dyn Any` instead.
|
||||
- `DynHash::as_dyn_eq` has been removed. Use `&value as &dyn DynEq` instead.
|
||||
- `as_dyn_eq` has been removed from 'label' types such as `ScheduleLabel` and `SystemSet`. Call `DynEq::dyn_eq` directly on the label instead.
|
Loading…
Reference in New Issue
Block a user