Repository: bevyengine/bevy
File: crates/bevy_reflect/derive/src/impls/structs.rs (Rust)

Code before:
                }
            }

            fn field_at(&self, index: usize) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {
                match index {
                    #(#field_indices => #fqoption::Some(#fields_ref),)*
                    _ => #FQOption::None,
                }
            }

            fn field_at_mut(&mut self, index: usize) -> #FQOption<&mut dyn #bevy_reflect_path::PartialReflect> {
                match index {
                    #(#field_indices => #fqoption::Some(#fields_mut),)*
                    _ => #FQOption::None,
                }
            }

            fn name_at(&self, index: usize) -> #FQOption<&str> {
                match index {
                    #(#field_indices => #fqoption::Some(#field_names),)*
                    _ => #FQOption::None,
                }
            }

            fn name_of(&self, field: &dyn #bevy_reflect_path::PartialReflect) -> #FQOption<&str> {
               #(if core::ptr::addr_eq(#fields_ref, field) { return #fqoption::Some(#field_names) })*
                #FQOption::None
            }

            fn index_of(&self, field: &dyn #bevy_reflect_path::PartialReflect) -> #FQOption<usize> {
                #(if core::ptr::addr_eq(#fields_ref, field) { return #fqoption::Some(#field_indices) })*
                #FQOption::None
            }

            fn index_of_name(&self, name: &str) -> #FQOption<usize> {
                match name {
                    #(#field_names => #fqoption::Some(#field_indices),)*
                    _ => #FQOption::None,
                }
            }

            fn field_len(&self) -> usize {
                #field_count
            }

            fn iter_fields(&self) -> #bevy_reflect_path::structs::FieldIter {
                #bevy_reflect_path::structs::FieldIter::new(self)
            }

            fn to_dynamic_struct(&self) -> #bevy_reflect_path::structs::DynamicStruct {
                let mut dynamic: #bevy_reflect_path::structs::DynamicStruct = #FQDefault::default();

Review comment (suggestion):
So would this only return true if the given value actually comes from the struct?

As a user, I may expect it to return the same value based on the struct type rather than the struct value. This means that cloning the field of a struct will return `None` on that same struct. That makes sense technically but may be unintuitive.

So to me, this makes this new method (and the others that rely on similar logic) very situational. Normally I’d suggest we document it on the method definition, but this also feels like an implementation detail/limitation rather than what we actually would want the method to do if we had the choice.

Could we perhaps split these new methods into their own PR for further evaluation? I'm not fully sold on it yet, but I could be in the minority. In either case, I don't know if we need to block adding the removal methods because of this.

Code after:
                }
            }

            fn field_at(&self, index: usize) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {
                match index {
                    #(#field_indices => #fqoption::Some(#fields_ref),)*
                    _ => #FQOption::None,
                }
            }

            fn field_at_mut(&mut self, index: usize) -> #FQOption<&mut dyn #bevy_reflect_path::PartialReflect> {
                match index {
                    #(#field_indices => #fqoption::Some(#fields_mut),)*
                    _ => #FQOption::None,
                }
            }

            fn name_at(&self, index: usize) -> #FQOption<&str> {
                match index {
                    #(#field_indices => #fqoption::Some(#field_names),)*
                    _ => #FQOption::None,
                }
            }

            fn field_len(&self) -> usize {
                #field_count
            }

            fn iter_fields(&self) -> #bevy_reflect_path::structs::FieldIter {
                #bevy_reflect_path::structs::FieldIter::new(self)
            }

            fn to_dynamic_struct(&self) -> #bevy_reflect_path::structs::DynamicStruct {
                let mut dynamic: #bevy_reflect_path::structs::DynamicStruct = #FQDefault::default();
                dynamic.set_represented_type(#bevy_reflect_path::PartialReflect::get_represented_type_info(self));
                #(dynamic.insert_boxed(#field_names, #bevy_reflect_path::PartialReflect::to_dynamic(#fields_ref));)*
                dynamic
            }
        }

        impl #impl_generics #bevy_reflect_path::PartialReflect for #struct_path #ty_generics #where_reflect_clause {
            #[inline]
            fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
                #FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
            }

            #[inline]
            fn try_apply(
                &mut self,
                value: &dyn #bevy_reflect_path::PartialReflect
            ) -> #FQResult<(), #bevy_reflect_path::ApplyError> {