Streamline GetOwnership/FromArg/IntoReturn (#20126)
# Objective Three impls are generated for each of these traits when the `reflect_functions` feature is enabled. Helps with #19873. ## Solution Two of the three (the `&T` and `&mut T` ones) can be avoided by instead providing blanket impls. The impl for `T` remains. ## Testing I checked the output via `cargo expand`. According to `-Zmacro-stats`, the size of the `Reflect` code generate for `bevy_ui` drops by 10.4%.
This commit is contained in:
parent
2a5e9c1150
commit
b8072864aa
@ -13,23 +13,11 @@ pub(crate) fn impl_from_arg(where_clause_options: &WhereClauseOptions) -> proc_m
|
||||
quote! {
|
||||
impl #impl_generics #bevy_reflect::func::args::FromArg for #type_path #ty_generics #where_reflect_clause {
|
||||
type This<'from_arg> = #type_path #ty_generics;
|
||||
fn from_arg(arg: #bevy_reflect::func::args::Arg) -> #FQResult<Self::This<'_>, #bevy_reflect::func::args::ArgError> {
|
||||
fn from_arg(arg: #bevy_reflect::func::args::Arg) ->
|
||||
#FQResult<Self::This<'_>, #bevy_reflect::func::args::ArgError>
|
||||
{
|
||||
arg.take_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::args::FromArg for &'static #type_path #ty_generics #where_reflect_clause {
|
||||
type This<'from_arg> = &'from_arg #type_path #ty_generics;
|
||||
fn from_arg(arg: #bevy_reflect::func::args::Arg) -> #FQResult<Self::This<'_>, #bevy_reflect::func::args::ArgError> {
|
||||
arg.take_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::args::FromArg for &'static mut #type_path #ty_generics #where_reflect_clause {
|
||||
type This<'from_arg> = &'from_arg mut #type_path #ty_generics;
|
||||
fn from_arg(arg: #bevy_reflect::func::args::Arg) -> #FQResult<Self::This<'_>, #bevy_reflect::func::args::ArgError> {
|
||||
arg.take_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,17 +17,5 @@ pub(crate) fn impl_get_ownership(
|
||||
#bevy_reflect::func::args::Ownership::Owned
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::args::GetOwnership for &'_ #type_path #ty_generics #where_reflect_clause {
|
||||
fn ownership() -> #bevy_reflect::func::args::Ownership {
|
||||
#bevy_reflect::func::args::Ownership::Ref
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::args::GetOwnership for &'_ mut #type_path #ty_generics #where_reflect_clause {
|
||||
fn ownership() -> #bevy_reflect::func::args::Ownership {
|
||||
#bevy_reflect::func::args::Ownership::Mut
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,21 +13,11 @@ pub(crate) fn impl_into_return(
|
||||
|
||||
quote! {
|
||||
impl #impl_generics #bevy_reflect::func::IntoReturn for #type_path #ty_generics #where_reflect_clause {
|
||||
fn into_return<'into_return>(self) -> #bevy_reflect::func::Return<'into_return> where Self: 'into_return {
|
||||
fn into_return<'into_return>(self) -> #bevy_reflect::func::Return<'into_return>
|
||||
where Self: 'into_return
|
||||
{
|
||||
#bevy_reflect::func::Return::Owned(#bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::IntoReturn for &#type_path #ty_generics #where_reflect_clause {
|
||||
fn into_return<'into_return>(self) -> #bevy_reflect::func::Return<'into_return> where Self: 'into_return {
|
||||
#bevy_reflect::func::Return::Ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_reflect::func::IntoReturn for &mut #type_path #ty_generics #where_reflect_clause {
|
||||
fn into_return<'into_return>(self) -> #bevy_reflect::func::Return<'into_return> where Self: 'into_return {
|
||||
#bevy_reflect::func::Return::Mut(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
use crate::func::args::{Arg, ArgError};
|
||||
use crate::{Reflect, TypePath};
|
||||
|
||||
/// A trait for types that can be created from an [`Arg`].
|
||||
///
|
||||
/// This trait exists so that types can be automatically converted into an [`Arg`]
|
||||
/// so they can be put into an [`ArgList`] and passed to a [`DynamicFunction`] or [`DynamicFunctionMut`].
|
||||
/// so they can be put into an [`ArgList`] and passed to a [`DynamicFunction`] or
|
||||
/// [`DynamicFunctionMut`].
|
||||
///
|
||||
/// This trait is used instead of a blanket [`From`] implementation due to coherence issues:
|
||||
/// we can't implement `From<T>` for both `T` and `&T`/`&mut T`.
|
||||
///
|
||||
/// This trait is automatically implemented when using the `Reflect` [derive macro].
|
||||
/// This trait is automatically implemented for non-reference types when using the `Reflect`
|
||||
/// [derive macro]. Blanket impls cover `&T` and `&mut T`.
|
||||
///
|
||||
/// [`ArgList`]: crate::func::args::ArgList
|
||||
/// [`DynamicFunction`]: crate::func::DynamicFunction
|
||||
@ -29,6 +32,22 @@ pub trait FromArg {
|
||||
fn from_arg(arg: Arg) -> Result<Self::This<'_>, ArgError>;
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T: Reflect + TypePath> FromArg for &'static T {
|
||||
type This<'a> = &'a T;
|
||||
fn from_arg(arg: Arg) -> Result<Self::This<'_>, ArgError> {
|
||||
arg.take_ref()
|
||||
}
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T: Reflect + TypePath> FromArg for &'static mut T {
|
||||
type This<'a> = &'a mut T;
|
||||
fn from_arg(arg: Arg) -> Result<Self::This<'_>, ArgError> {
|
||||
arg.take_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements the [`FromArg`] trait for the given type.
|
||||
///
|
||||
/// This will implement it for `$ty`, `&$ty`, and `&mut $ty`.
|
||||
@ -40,18 +59,13 @@ macro_rules! impl_from_arg {
|
||||
(
|
||||
$ty: ty
|
||||
$(;
|
||||
<
|
||||
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
|
||||
>
|
||||
< $($T: ident $(: $T1: tt $(+ $T2: tt)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N: ident : $size: ident),*
|
||||
]
|
||||
[ $(const $N: ident : $size: ident),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
where $($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
)?
|
||||
) => {
|
||||
impl <
|
||||
@ -59,45 +73,16 @@ macro_rules! impl_from_arg {
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::FromArg for $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
type This<'from_arg> = $ty;
|
||||
fn from_arg(arg: $crate::func::args::Arg) -> Result<Self::This<'_>, $crate::func::args::ArgError> {
|
||||
fn from_arg(arg: $crate::func::args::Arg) ->
|
||||
Result<Self::This<'_>, $crate::func::args::ArgError>
|
||||
{
|
||||
arg.take_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::FromArg for &'static $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
type This<'from_arg> = &'from_arg $ty;
|
||||
fn from_arg(arg: $crate::func::args::Arg) -> Result<Self::This<'_>, $crate::func::args::ArgError> {
|
||||
arg.take_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::FromArg for &'static mut $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
type This<'from_arg> = &'from_arg mut $ty;
|
||||
fn from_arg(arg: $crate::func::args::Arg) -> Result<Self::This<'_>, $crate::func::args::ArgError> {
|
||||
arg.take_mut()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,21 +1,5 @@
|
||||
use core::fmt::{Display, Formatter};
|
||||
|
||||
/// A trait for getting the ownership of a type.
|
||||
///
|
||||
/// This trait exists so that [`TypedFunction`] can automatically generate
|
||||
/// [`FunctionInfo`] containing the proper [`Ownership`] for its [argument] types.
|
||||
///
|
||||
/// This trait is automatically implemented when using the `Reflect` [derive macro].
|
||||
///
|
||||
/// [`TypedFunction`]: crate::func::TypedFunction
|
||||
/// [`FunctionInfo`]: crate::func::FunctionInfo
|
||||
/// [argument]: crate::func::args::Arg
|
||||
/// [derive macro]: derive@crate::Reflect
|
||||
pub trait GetOwnership {
|
||||
/// Returns the ownership of [`Self`].
|
||||
fn ownership() -> Ownership;
|
||||
}
|
||||
|
||||
/// The ownership of a type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Ownership {
|
||||
@ -37,6 +21,39 @@ impl Display for Ownership {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for getting the ownership of a type.
|
||||
///
|
||||
/// This trait exists so that [`TypedFunction`] can automatically generate
|
||||
/// [`FunctionInfo`] containing the proper [`Ownership`] for its [argument] types.
|
||||
///
|
||||
/// This trait is automatically implemented for non-reference types when using the `Reflect`
|
||||
/// [derive macro]. Blanket impls cover `&T` and `&mut T`.
|
||||
///
|
||||
/// [`TypedFunction`]: crate::func::TypedFunction
|
||||
/// [`FunctionInfo`]: crate::func::FunctionInfo
|
||||
/// [argument]: crate::func::args::Arg
|
||||
/// [derive macro]: derive@crate::Reflect
|
||||
pub trait GetOwnership {
|
||||
/// Returns the ownership of [`Self`].
|
||||
fn ownership() -> Ownership {
|
||||
Ownership::Owned
|
||||
}
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T> GetOwnership for &'_ T {
|
||||
fn ownership() -> Ownership {
|
||||
Ownership::Ref
|
||||
}
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T> GetOwnership for &'_ mut T {
|
||||
fn ownership() -> Ownership {
|
||||
Ownership::Mut
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements the [`GetOwnership`] trait for the given type.
|
||||
///
|
||||
/// This will implement it for `$ty`, `&$ty`, and `&mut $ty`.
|
||||
@ -48,18 +65,13 @@ macro_rules! impl_get_ownership {
|
||||
(
|
||||
$ty: ty
|
||||
$(;
|
||||
<
|
||||
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
|
||||
>
|
||||
< $($T: ident $(: $T1: tt $(+ $T2: tt)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N: ident : $size: ident),*
|
||||
]
|
||||
[ $(const $N: ident : $size: ident),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
where $($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
)?
|
||||
) => {
|
||||
impl <
|
||||
@ -67,42 +79,9 @@ macro_rules! impl_get_ownership {
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::GetOwnership for $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn ownership() -> $crate::func::args::Ownership {
|
||||
$crate::func::args::Ownership::Owned
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::GetOwnership for &'_ $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn ownership() -> $crate::func::args::Ownership {
|
||||
$crate::func::args::Ownership::Ref
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::args::GetOwnership for &'_ mut $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn ownership() -> $crate::func::args::Ownership {
|
||||
$crate::func::args::Ownership::Mut
|
||||
}
|
||||
}
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -28,69 +28,49 @@ macro_rules! impl_function_traits {
|
||||
(
|
||||
$ty: ty
|
||||
$(;
|
||||
<
|
||||
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
|
||||
>
|
||||
< $($T: ident $(: $T1: tt $(+ $T2: tt)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N: ident : $size: ident),*
|
||||
]
|
||||
[ $(const $N: ident : $size: ident),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
where $($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
)?
|
||||
) => {
|
||||
$crate::func::args::impl_get_ownership!(
|
||||
$ty
|
||||
$(;
|
||||
<
|
||||
$($T $(: $T1 $(+ $T2)*)?),*
|
||||
>
|
||||
< $($T $(: $T1 $(+ $T2)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N : $size),*
|
||||
]
|
||||
[ $(const $N : $size),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
);
|
||||
$crate::func::args::impl_from_arg!(
|
||||
$ty
|
||||
$(;
|
||||
<
|
||||
$($T $(: $T1 $(+ $T2)*)?),*
|
||||
>
|
||||
< $($T $(: $T1 $(+ $T2)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N : $size),*
|
||||
]
|
||||
[ $(const $N : $size),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
);
|
||||
$crate::func::impl_into_return!(
|
||||
$ty
|
||||
$(;
|
||||
<
|
||||
$($T $(: $T1 $(+ $T2)*)?),*
|
||||
>
|
||||
< $($T $(: $T1 $(+ $T2)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N : $size),*
|
||||
]
|
||||
[ $(const $N : $size),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
);
|
||||
};
|
||||
|
||||
@ -76,7 +76,8 @@ impl<'a> Return<'a> {
|
||||
/// This trait is used instead of a blanket [`Into`] implementation due to coherence issues:
|
||||
/// we can't implement `Into<Return>` for both `T` and `&T`/`&mut T`.
|
||||
///
|
||||
/// This trait is automatically implemented when using the `Reflect` [derive macro].
|
||||
/// This trait is automatically implemented for non-reference types when using the `Reflect`
|
||||
/// [derive macro]. Blanket impls cover `&T` and `&mut T`.
|
||||
///
|
||||
/// [`ReflectFn`]: crate::func::ReflectFn
|
||||
/// [`ReflectFnMut`]: crate::func::ReflectFnMut
|
||||
@ -88,6 +89,26 @@ pub trait IntoReturn {
|
||||
Self: 'a;
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T: PartialReflect> IntoReturn for &'_ T {
|
||||
fn into_return<'a>(self) -> Return<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
Return::Ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
// Blanket impl.
|
||||
impl<T: PartialReflect> IntoReturn for &'_ mut T {
|
||||
fn into_return<'a>(self) -> Return<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
Return::Mut(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoReturn for () {
|
||||
fn into_return<'a>(self) -> Return<'a> {
|
||||
Return::unit()
|
||||
@ -105,18 +126,13 @@ macro_rules! impl_into_return {
|
||||
(
|
||||
$ty: ty
|
||||
$(;
|
||||
<
|
||||
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
|
||||
>
|
||||
< $($T: ident $(: $T1: tt $(+ $T2: tt)*)?),* >
|
||||
)?
|
||||
$(
|
||||
[
|
||||
$(const $N: ident : $size: ident),*
|
||||
]
|
||||
[ $(const $N: ident : $size: ident),* ]
|
||||
)?
|
||||
$(
|
||||
where
|
||||
$($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
where $($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
|
||||
)?
|
||||
) => {
|
||||
impl <
|
||||
@ -124,42 +140,15 @@ macro_rules! impl_into_return {
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::IntoReturn for $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
where $($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn into_return<'into_return>(self) -> $crate::func::Return<'into_return> where Self: 'into_return {
|
||||
fn into_return<'into_return>(self) -> $crate::func::Return<'into_return>
|
||||
where Self: 'into_return
|
||||
{
|
||||
$crate::func::Return::Owned(bevy_platform::prelude::Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::IntoReturn for &'static $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn into_return<'into_return>(self) -> $crate::func::Return<'into_return> where Self: 'into_return {
|
||||
$crate::func::Return::Ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl <
|
||||
$($($T $(: $T1 $(+ $T2)*)?),*)?
|
||||
$(, $(const $N : $size),*)?
|
||||
> $crate::func::IntoReturn for &'static mut $ty
|
||||
$(
|
||||
where
|
||||
$($U $(: $U1 $(+ $U2)*)?),*
|
||||
)?
|
||||
{
|
||||
fn into_return<'into_return>(self) -> $crate::func::Return<'into_return> where Self: 'into_return {
|
||||
$crate::func::Return::Mut(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -153,6 +153,3 @@ impl FromReflect for &'static Location<'static> {
|
||||
reflect.try_downcast_ref::<Self>().copied()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "functions")]
|
||||
crate::func::macros::impl_function_traits!(&'static Location<'static>);
|
||||
|
||||
@ -293,9 +293,6 @@ impl FromReflect for &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "functions")]
|
||||
crate::func::macros::impl_function_traits!(&'static str);
|
||||
|
||||
impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> Array for [T; N] {
|
||||
#[inline]
|
||||
fn get(&self, index: usize) -> Option<&dyn PartialReflect> {
|
||||
|
||||
@ -160,9 +160,6 @@ impl FromReflect for &'static Path {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "functions")]
|
||||
crate::func::macros::impl_function_traits!(&'static Path);
|
||||
|
||||
impl PartialReflect for Cow<'static, Path> {
|
||||
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
|
||||
Some(<Self as Typed>::type_info())
|
||||
|
||||
Loading…
Reference in New Issue
Block a user