Change WhereClauseOptions::active_fields to active_types

This could have been part of #19876, which deduplicated the fields. It's
also simpler and more efficient to keep the (short-lived) active types
as an `IndexSet<Type>`, and avoid converting them to a `Vec<Type>` and
then a `Box<[Type]>`.
This commit is contained in:
Nicholas Nethercote 2025-07-01 21:36:32 +10:00
parent 33bed5dd70
commit ed1a5ab94a
2 changed files with 12 additions and 18 deletions

View File

@ -605,13 +605,11 @@ impl<'a> ReflectStruct<'a> {
}
/// Get a collection of types which are exposed to the reflection API
pub fn active_types(&self) -> Vec<Type> {
// Collect via `IndexSet` to eliminate duplicate types.
pub fn active_types(&self) -> IndexSet<Type> {
// Collect into an `IndexSet` to eliminate duplicate types.
self.active_fields()
.map(|field| field.reflected_type().clone())
.collect::<IndexSet<_>>()
.into_iter()
.collect::<Vec<_>>()
}
/// Get an iterator of fields which are exposed to the reflection API.
@ -634,7 +632,7 @@ impl<'a> ReflectStruct<'a> {
}
pub fn where_clause_options(&self) -> WhereClauseOptions {
WhereClauseOptions::new_with_fields(self.meta(), self.active_types().into_boxed_slice())
WhereClauseOptions::new_with_types(self.meta(), self.active_types())
}
/// Generates a `TokenStream` for `TypeInfo::Struct` or `TypeInfo::TupleStruct` construction.
@ -841,13 +839,11 @@ impl<'a> ReflectEnum<'a> {
}
/// Get a collection of types which are exposed to the reflection API
pub fn active_types(&self) -> Vec<Type> {
// Collect via `IndexSet` to eliminate duplicate types.
pub fn active_types(&self) -> IndexSet<Type> {
// Collect into an `IndexSet` to eliminate duplicate types.
self.active_fields()
.map(|field| field.reflected_type().clone())
.collect::<IndexSet<_>>()
.into_iter()
.collect::<Vec<_>>()
}
/// Get an iterator of fields which are exposed to the reflection API
@ -856,7 +852,7 @@ impl<'a> ReflectEnum<'a> {
}
pub fn where_clause_options(&self) -> WhereClauseOptions {
WhereClauseOptions::new_with_fields(self.meta(), self.active_types().into_boxed_slice())
WhereClauseOptions::new_with_types(self.meta(), self.active_types())
}
/// Returns the `GetTypeRegistration` impl as a `TokenStream`.

View File

@ -1,5 +1,6 @@
use crate::derive_data::ReflectMeta;
use bevy_macro_utils::fq_std::{FQAny, FQSend, FQSync};
use indexmap::IndexSet;
use proc_macro2::{TokenStream, TokenTree};
use quote::{quote, ToTokens};
use syn::{punctuated::Punctuated, Ident, Token, Type, WhereClause};
@ -7,22 +8,19 @@ use syn::{punctuated::Punctuated, Ident, Token, Type, WhereClause};
/// Options defining how to extend the `where` clause for reflection.
pub(crate) struct WhereClauseOptions<'a, 'b> {
meta: &'a ReflectMeta<'b>,
active_fields: Box<[Type]>,
active_types: IndexSet<Type>,
}
impl<'a, 'b> WhereClauseOptions<'a, 'b> {
pub fn new(meta: &'a ReflectMeta<'b>) -> Self {
Self {
meta,
active_fields: Box::new([]),
active_types: IndexSet::new(),
}
}
pub fn new_with_fields(meta: &'a ReflectMeta<'b>, active_fields: Box<[Type]>) -> Self {
Self {
meta,
active_fields,
}
pub fn new_with_types(meta: &'a ReflectMeta<'b>, active_types: IndexSet<Type>) -> Self {
Self { meta, active_types }
}
pub fn meta(&self) -> &'a ReflectMeta<'b> {
@ -207,7 +205,7 @@ impl<'a, 'b> WhereClauseOptions<'a, 'b> {
false
}
Some(self.active_fields.iter().filter_map(move |ty| {
Some(self.active_types.iter().filter_map(move |ty| {
// Field type bounds are only required if `ty` is generic. How to determine that?
// Search `ty`s token stream for identifiers that match the identifiers from the
// function's type params. E.g. if `T` and `U` are the type param identifiers and