bevy_reflect: streamline generated FromReflect::from_reflect (#19906)

# Objective

Generated `from_reflect` methods use closures in a weird way, e.g.:
```rust
    x: (|| {
        <f32 as ::bevy::reflect::FromReflect>::from_reflect(
            ::bevy::reflect::Struct::field(__ref_struct, "x")?,
        )   
    })()?,
```
The reason for this is because when `#[reflect(Default)]` is used, you
instead get stuff like this:
```rust
    if let ::core::option::Option::Some(__field) = (|| {
        <f32 as ::bevy::reflect::FromReflect>::from_reflect(
            ::bevy::reflect::Struct::field(__ref_struct, "x")?,
        )   
    })() {
        __this.x = __field;
    } 
```
and the closure is necessary to contain the scope of the `?`. But the
first case is more common.

Helps with #19873.

## Solution

Avoid the closure in the common case.

## Testing

I used cargo expand to confirm the closures are no longer produced in
the common case.

`-Zmacro-stats` output tells me this reduces the size of the `Reflect`
code produced for `bevy_ui` by 0.5%.
This commit is contained in:
Nicholas Nethercote 2025-07-03 00:59:20 +10:00 committed by GitHub
parent f95f42b44a
commit 1b4cf02fc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -146,7 +146,8 @@ fn impl_struct_internal(
quote! {
let mut #__this = <#reflect_ty as #FQDefault>::default();
#(
if let #fqoption::Some(__field) = #active_values() {
// The closure catches any failing `?` within `active_values`.
if let #fqoption::Some(__field) = (|| #active_values)() {
// Iff field exists -> use its value
#__this.#active_members = __field;
}
@ -158,7 +159,7 @@ fn impl_struct_internal(
quote! {
let #__this = #constructor {
#(#active_members: #active_values()?,)*
#(#active_members: #active_values?,)*
#(#ignored_members: #ignored_values,)*
};
#FQOption::Some(#retval)
@ -274,13 +275,11 @@ fn get_active_fields(
<#ty as #bevy_reflect_path::FromReflect>::from_reflect(field)
});
quote! {
(||
if let #FQOption::Some(field) = #get_field {
#value
} else {
#FQOption::Some(#path())
}
)
if let #FQOption::Some(field) = #get_field {
#value
} else {
#FQOption::Some(#path())
}
}
}
DefaultBehavior::Default => {
@ -288,13 +287,11 @@ fn get_active_fields(
<#ty as #bevy_reflect_path::FromReflect>::from_reflect(field)
});
quote! {
(||
if let #FQOption::Some(field) = #get_field {
#value
} else {
#FQOption::Some(#FQDefault::default())
}
)
if let #FQOption::Some(field) = #get_field {
#value
} else {
#FQOption::Some(#FQDefault::default())
}
}
}
DefaultBehavior::Required => {
@ -302,7 +299,7 @@ fn get_active_fields(
<#ty as #bevy_reflect_path::FromReflect>::from_reflect(#get_field?)
});
quote! {
(|| #value)
#value
}
}
};