From 44f0ae7ec74fca65033bfffc4def2b19afb2f6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Sun, 7 May 2023 08:51:47 +0200 Subject: [PATCH 01/14] update syn, encase and glam --- Cargo.toml | 5 + benches/Cargo.toml | 2 +- crates/bevy_derive/Cargo.toml | 2 +- crates/bevy_ecs/macros/Cargo.toml | 2 +- crates/bevy_ecs/macros/src/component.rs | 56 +++----- crates/bevy_ecs/macros/src/fetch.rs | 17 +-- crates/bevy_ecs/macros/src/lib.rs | 35 ++--- crates/bevy_encase_derive/Cargo.toml | 2 +- crates/bevy_macro_utils/Cargo.toml | 2 +- crates/bevy_macro_utils/src/attrs.rs | 39 ++--- crates/bevy_macro_utils/src/lib.rs | 2 +- crates/bevy_math/Cargo.toml | 2 +- crates/bevy_mikktspace/Cargo.toml | 2 +- crates/bevy_reflect/Cargo.toml | 2 +- .../bevy_reflect_derive/Cargo.toml | 2 +- .../src/container_attributes.rs | 83 +++++------ .../bevy_reflect_derive/src/derive_data.rs | 29 +++- .../bevy_reflect_derive/src/documentation.rs | 22 +-- .../src/field_attributes.rs | 22 +-- .../bevy_reflect_derive/src/type_uuid.rs | 19 +-- crates/bevy_render/Cargo.toml | 2 +- crates/bevy_render/macros/Cargo.toml | 2 +- .../bevy_render/macros/src/as_bind_group.rs | 136 ++++++++---------- .../macros/src/extract_component.rs | 2 +- crates/bevy_utils/macros/Cargo.toml | 2 +- 25 files changed, 222 insertions(+), 269 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f7b0eb6f3986d..4b39afd5f031d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2023,3 +2023,8 @@ codegen-units = 1 inherits = "release" lto = "fat" panic = "abort" + + +[patch.crates-io] +encase = { git = "https://github.com/mockersf/encase", branch = "allow-doc-comments" } +encase_derive_impl = { git = "https://github.com/mockersf/encase", branch = "allow-doc-comments" } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 8b5f7906d03d1..0c66806f34acc 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -7,7 +7,7 @@ publish = false license = "MIT OR Apache-2.0" [dev-dependencies] -glam = "0.23" +glam = "0.24" rand = "0.8" rand_chacha = "0.3" criterion = { version = "0.3", features = ["html_reports"] } diff --git a/crates/bevy_derive/Cargo.toml b/crates/bevy_derive/Cargo.toml index e09ff1bd5f41e..f0e9688f2115b 100644 --- a/crates/bevy_derive/Cargo.toml +++ b/crates/bevy_derive/Cargo.toml @@ -15,4 +15,4 @@ proc-macro = true bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.11.0-dev" } quote = "1.0" -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } diff --git a/crates/bevy_ecs/macros/Cargo.toml b/crates/bevy_ecs/macros/Cargo.toml index 8a5f1664e5992..9675f10594492 100644 --- a/crates/bevy_ecs/macros/Cargo.toml +++ b/crates/bevy_ecs/macros/Cargo.toml @@ -11,6 +11,6 @@ proc-macro = true [dependencies] bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.11.0-dev" } -syn = "1.0" +syn = "2.0" quote = "1.0" proc-macro2 = "1.0" diff --git a/crates/bevy_ecs/macros/src/component.rs b/crates/bevy_ecs/macros/src/component.rs index b051e630ebc44..d1e3a1e351432 100644 --- a/crates/bevy_ecs/macros/src/component.rs +++ b/crates/bevy_ecs/macros/src/component.rs @@ -1,8 +1,7 @@ -use bevy_macro_utils::{get_lit_str, Symbol}; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::{quote, ToTokens}; -use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result}; +use quote::quote; +use syn::{parse_macro_input, parse_quote, DeriveInput, Ident, LitStr, Path, Result}; pub fn derive_resource(input: TokenStream) -> TokenStream { let mut ast = parse_macro_input!(input as DeriveInput); @@ -48,8 +47,8 @@ pub fn derive_component(input: TokenStream) -> TokenStream { }) } -pub const COMPONENT: Symbol = Symbol("component"); -pub const STORAGE: Symbol = Symbol("storage"); +pub const COMPONENT: &str = "component"; +pub const STORAGE: &str = "storage"; struct Attrs { storage: StorageTy, @@ -66,48 +65,27 @@ const TABLE: &str = "Table"; const SPARSE_SET: &str = "SparseSet"; fn parse_component_attr(ast: &DeriveInput) -> Result { - let meta_items = bevy_macro_utils::parse_attrs(ast, COMPONENT)?; - let mut attrs = Attrs { storage: StorageTy::Table, }; - for meta in meta_items { - use syn::{ - Meta::NameValue, - NestedMeta::{Lit, Meta}, - }; - match meta { - Meta(NameValue(m)) if m.path == STORAGE => { - attrs.storage = match get_lit_str(STORAGE, &m.lit)?.value().as_str() { - TABLE => StorageTy::Table, - SPARSE_SET => StorageTy::SparseSet, + for meta in ast.attrs.iter().filter(|a| a.path().is_ident(COMPONENT)) { + meta.parse_nested_meta(|nested| { + if nested.path.is_ident(STORAGE) { + attrs.storage = match nested.value()?.parse::()?.value() { + s if s == TABLE => StorageTy::Table, + s if s == SPARSE_SET => StorageTy::SparseSet, s => { - return Err(Error::new_spanned( - m.lit, - format!( - "Invalid storage type `{s}`, expected '{TABLE}' or '{SPARSE_SET}'.", - ), - )) + return Err(nested.error(format!( + "Invalid storage type `{s}`, expected '{TABLE}' or '{SPARSE_SET}'.", + ))); } }; + Ok(()) + } else { + Err(nested.error("Unsuported attribute")) } - Meta(meta_item) => { - return Err(Error::new_spanned( - meta_item.path(), - format!( - "unknown component attribute `{}`", - meta_item.path().into_token_stream() - ), - )); - } - Lit(lit) => { - return Err(Error::new_spanned( - lit, - "unexpected literal in component attribute", - )) - } - } + })?; } Ok(attrs) diff --git a/crates/bevy_ecs/macros/src/fetch.rs b/crates/bevy_ecs/macros/src/fetch.rs index 93491bb531d6a..4ed43cc7fed59 100644 --- a/crates/bevy_ecs/macros/src/fetch.rs +++ b/crates/bevy_ecs/macros/src/fetch.rs @@ -6,7 +6,7 @@ use syn::{ parse::{Parse, ParseStream}, parse_macro_input, parse_quote, punctuated::Punctuated, - Attribute, Data, DataStruct, DeriveInput, Field, Index, + Attribute, Data, DataStruct, DeriveInput, Field, Index, Meta, Token, }; use crate::bevy_ecs_path; @@ -14,7 +14,7 @@ use crate::bevy_ecs_path; #[derive(Default)] struct FetchStructAttributes { pub is_mutable: bool, - pub derive_args: Punctuated, + pub derive_args: Punctuated, } static MUTABLE_ATTRIBUTE_NAME: &str = "mutable"; @@ -35,7 +35,7 @@ pub fn derive_world_query_impl(input: TokenStream) -> TokenStream { let mut fetch_struct_attributes = FetchStructAttributes::default(); for attr in &ast.attrs { if !attr - .path + .path() .get_ident() .map_or(false, |ident| ident == WORLD_QUERY_ATTRIBUTE_NAME) { @@ -43,7 +43,7 @@ pub fn derive_world_query_impl(input: TokenStream) -> TokenStream { } attr.parse_args_with(|input: ParseStream| { - let meta = input.parse_terminated::(syn::Meta::parse)?; + let meta = input.parse_terminated(syn::Meta::parse, Token![,])?; for meta in meta { let ident = meta.path().get_ident().unwrap_or_else(|| { panic!( @@ -61,9 +61,10 @@ pub fn derive_world_query_impl(input: TokenStream) -> TokenStream { } } else if ident == DERIVE_ATTRIBUTE_NAME { if let syn::Meta::List(meta_list) = meta { - fetch_struct_attributes - .derive_args - .extend(meta_list.nested.iter().cloned()); + meta_list.parse_nested_meta(|meta| { + fetch_struct_attributes.derive_args.push(Meta::Path(meta.path)); + Ok(()) + })?; } else { panic!( "Expected a structured list within the `{DERIVE_ATTRIBUTE_NAME}` attribute", @@ -463,7 +464,7 @@ fn read_world_query_field_info(field: &Field) -> syn::Result TokenStream { let mut field_kind = Vec::with_capacity(named_fields.len()); - 'field_loop: for field in named_fields.iter() { - for attr in &field.attrs { - if attr.path.is_ident(BUNDLE_ATTRIBUTE_NAME) { - if let Ok(Meta::List(MetaList { nested, .. })) = attr.parse_meta() { - if let Some(&NestedMeta::Meta(Meta::Path(ref path))) = nested.first() { - if path.is_ident(BUNDLE_ATTRIBUTE_IGNORE_NAME) { - field_kind.push(BundleFieldKind::Ignore); - continue 'field_loop; - } - - return syn::Error::new( - path.span(), - format!( - "Invalid bundle attribute. Use `{BUNDLE_ATTRIBUTE_IGNORE_NAME}`" - ), - ) - .into_compile_error() - .into(); - } - - return syn::Error::new(attr.span(), format!("Invalid bundle attribute. Use `#[{BUNDLE_ATTRIBUTE_NAME}({BUNDLE_ATTRIBUTE_IGNORE_NAME})]`")).into_compile_error().into(); + for field in named_fields.iter() { + for attr in field + .attrs + .iter() + .filter(|a| a.path().is_ident(BUNDLE_ATTRIBUTE_NAME)) + { + let _ = attr.parse_nested_meta(|meta| { + if meta.path.is_ident(BUNDLE_ATTRIBUTE_IGNORE_NAME) { + field_kind.push(BundleFieldKind::Ignore); } - } + Ok(()) + }); } field_kind.push(BundleFieldKind::Component); diff --git a/crates/bevy_encase_derive/Cargo.toml b/crates/bevy_encase_derive/Cargo.toml index 5dc65d805118b..0b497eca2a084 100644 --- a/crates/bevy_encase_derive/Cargo.toml +++ b/crates/bevy_encase_derive/Cargo.toml @@ -13,4 +13,4 @@ proc-macro = true [dependencies] bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.11.0-dev" } -encase_derive_impl = "0.5.0" +encase_derive_impl = "0.6.0" diff --git a/crates/bevy_macro_utils/Cargo.toml b/crates/bevy_macro_utils/Cargo.toml index 76cb1d690f295..08c1d0243b96e 100644 --- a/crates/bevy_macro_utils/Cargo.toml +++ b/crates/bevy_macro_utils/Cargo.toml @@ -10,6 +10,6 @@ keywords = ["bevy"] [dependencies] toml_edit = "0.19" -syn = "1.0" +syn = "2.0" quote = "1.0" rustc-hash = "1.0" diff --git a/crates/bevy_macro_utils/src/attrs.rs b/crates/bevy_macro_utils/src/attrs.rs index 496ce42257ec2..33b96e5b99897 100644 --- a/crates/bevy_macro_utils/src/attrs.rs +++ b/crates/bevy_macro_utils/src/attrs.rs @@ -1,41 +1,32 @@ -use syn::DeriveInput; +use syn::{Expr, ExprLit, Lit}; use crate::symbol::Symbol; -pub fn parse_attrs(ast: &DeriveInput, attr_name: Symbol) -> syn::Result> { - let mut list = Vec::new(); - for attr in ast.attrs.iter().filter(|a| a.path == attr_name) { - match attr.parse_meta()? { - syn::Meta::List(meta) => list.extend(meta.nested.into_iter()), - other => { - return Err(syn::Error::new_spanned( - other, - format!("expected #[{attr_name}(...)]"), - )) - } - } - } - Ok(list) -} - -pub fn get_lit_str(attr_name: Symbol, lit: &syn::Lit) -> syn::Result<&syn::LitStr> { - if let syn::Lit::Str(lit) = lit { +pub fn get_lit_str(attr_name: Symbol, value: &Expr) -> syn::Result<&syn::LitStr> { + if let Expr::Lit(ExprLit { + lit: Lit::Str(lit), .. + }) = &value + { Ok(lit) } else { Err(syn::Error::new_spanned( - lit, + value, format!("expected {attr_name} attribute to be a string: `{attr_name} = \"...\"`"), )) } } -pub fn get_lit_bool(attr_name: Symbol, lit: &syn::Lit) -> syn::Result { - if let syn::Lit::Bool(lit) = lit { +pub fn get_lit_bool(attr_name: Symbol, value: &Expr) -> syn::Result { + if let Expr::Lit(ExprLit { + lit: Lit::Bool(lit), + .. + }) = &value + { Ok(lit.value()) } else { Err(syn::Error::new_spanned( - lit, + value, format!("expected {attr_name} attribute to be a bool value, `true` or `false`: `{attr_name} = ...`"), - )) + ))? } } diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 0aeea189448b4..6b994ff9ba90e 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -214,7 +214,7 @@ pub fn derive_label( ) -> TokenStream { // return true if the variant specified is an `ignore_fields` attribute fn is_ignore(attr: &syn::Attribute, attr_name: &str) -> bool { - if attr.path.get_ident().as_ref().unwrap() != &attr_name { + if attr.path().get_ident().as_ref().unwrap() != &attr_name { return false; } diff --git a/crates/bevy_math/Cargo.toml b/crates/bevy_math/Cargo.toml index 5c2c49afae5b7..b6105f6664a26 100644 --- a/crates/bevy_math/Cargo.toml +++ b/crates/bevy_math/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [dependencies] -glam = { version = "0.23", features = ["bytemuck"] } +glam = { version = "0.24", features = ["bytemuck"] } serde = { version = "1", features = ["derive"], optional = true } [features] diff --git a/crates/bevy_mikktspace/Cargo.toml b/crates/bevy_mikktspace/Cargo.toml index ed2b73a5ffa26..fc5cbba391e5b 100644 --- a/crates/bevy_mikktspace/Cargo.toml +++ b/crates/bevy_mikktspace/Cargo.toml @@ -11,7 +11,7 @@ license = "Zlib AND (MIT OR Apache-2.0)" keywords = ["bevy", "3D", "graphics", "algorithm", "tangent"] [dependencies] -glam = "0.23" +glam = "0.24" [[example]] name = "generate" diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index 240b839162042..2736045723d83 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -31,7 +31,7 @@ thiserror = "1.0" once_cell = "1.11" serde = "1" smallvec = { version = "1.6", features = ["serde", "union", "const_generics"], optional = true } -glam = { version = "0.23", features = ["serde"], optional = true } +glam = { version = "0.24", features = ["serde"], optional = true } [dev-dependencies] ron = "0.8.0" diff --git a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml index 6048b0393e005..fa6b7259dce53 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml +++ b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml @@ -19,7 +19,7 @@ documentation = [] [dependencies] bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.11.0-dev" } -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } proc-macro2 = "1.0" quote = "1.0" uuid = { version = "1.1", features = ["v4"] } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 87940c689a387..4528c39a19e7a 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -13,7 +13,7 @@ use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::token::Comma; -use syn::{Meta, NestedMeta, Path}; +use syn::{Meta, Path}; // The "special" trait idents that are used internally for reflection. // Received via attributes like `#[reflect(PartialEq, Hash, ...)]` @@ -48,9 +48,13 @@ impl TraitImpl { /// Returns whichever value is not [`TraitImpl::NotImplemented`]. /// If both values are [`TraitImpl::NotImplemented`], then that is returned. /// Otherwise, an error is returned if neither value is [`TraitImpl::NotImplemented`]. - pub fn merge(self, other: TraitImpl) -> Result { - match (self, other) { - (TraitImpl::NotImplemented, value) | (value, TraitImpl::NotImplemented) => Ok(value), + pub fn merge(&mut self, other: TraitImpl) -> Result<(), syn::Error> { + match (&self, other) { + (TraitImpl::NotImplemented, value) => { + *self = value; + Ok(()) + } + (_, TraitImpl::NotImplemented) => Ok(()), (_, TraitImpl::Implemented(span) | TraitImpl::Custom(_, span)) => { Err(syn::Error::new(span, CONFLICTING_TYPE_DATA_MESSAGE)) } @@ -128,15 +132,13 @@ pub(crate) struct ReflectTraits { } impl ReflectTraits { - /// Create a new [`ReflectTraits`] instance from a set of nested metas. - pub fn from_nested_metas( - nested_metas: &Punctuated, - ) -> Result { + // pub fn from_metas(metas: &Punctuated) -> Result { + pub fn from_metas(metas: Vec) -> Result { let mut traits = ReflectTraits::default(); - for nested_meta in nested_metas.iter() { - match nested_meta { + for meta in &metas { + match meta { // Handles `#[reflect( Hash, Default, ... )]` - NestedMeta::Meta(Meta::Path(path)) => { + Meta::Path(path) => { // Get the first ident in the path (hopefully the path only contains one and not `std::hash::Hash`) let Some(segment) = path.segments.iter().next() else { continue; @@ -149,14 +151,13 @@ impl ReflectTraits { match ident_name.as_str() { DEBUG_ATTR => { - traits.debug = traits.debug.merge(TraitImpl::Implemented(span))?; + traits.debug.merge(TraitImpl::Implemented(span))?; } PARTIAL_EQ_ATTR => { - traits.partial_eq = - traits.partial_eq.merge(TraitImpl::Implemented(span))?; + traits.partial_eq.merge(TraitImpl::Implemented(span))?; } HASH_ATTR => { - traits.hash = traits.hash.merge(TraitImpl::Implemented(span))?; + traits.hash.merge(TraitImpl::Implemented(span))?; } // We only track reflected idents for traits not considered special _ => { @@ -170,7 +171,7 @@ impl ReflectTraits { } } // Handles `#[reflect( Hash(custom_hash_fn) )]` - NestedMeta::Meta(Meta::List(list)) => { + Meta::List(list) => { // Get the first ident in the path (hopefully the path only contains one and not `std::hash::Hash`) let Some(segment) = list.path.segments.iter().next() else { continue; @@ -181,23 +182,18 @@ impl ReflectTraits { // Track the span where the trait is implemented for future errors let span = ident.span(); - let list_meta = list.nested.iter().next(); - if let Some(NestedMeta::Meta(Meta::Path(path))) = list_meta { + list.parse_nested_meta(|meta| { // This should be the path of the custom function - let trait_func_ident = TraitImpl::Custom(path.clone(), span); - match ident.as_str() { - DEBUG_ATTR => { - traits.debug = traits.debug.merge(trait_func_ident)?; - } - PARTIAL_EQ_ATTR => { - traits.partial_eq = traits.partial_eq.merge(trait_func_ident)?; - } - HASH_ATTR => { - traits.hash = traits.hash.merge(trait_func_ident)?; - } - _ => {} + let trait_func_ident = TraitImpl::Custom(meta.path.clone(), span); + if meta.path.is_ident(DEBUG_ATTR) { + traits.debug.merge(trait_func_ident)?; + } else if meta.path.is_ident(PARTIAL_EQ_ATTR) { + traits.partial_eq.merge(trait_func_ident)?; + } else if meta.path.is_ident(HASH_ATTR) { + traits.hash.merge(trait_func_ident)?; } - } + Ok(()) + })?; } _ => {} } @@ -289,26 +285,21 @@ impl ReflectTraits { /// Merges the trait implementations of this [`ReflectTraits`] with another one. /// /// An error is returned if the two [`ReflectTraits`] have conflicting implementations. - pub fn merge(self, other: ReflectTraits) -> Result { - Ok(ReflectTraits { - debug: self.debug.merge(other.debug)?, - hash: self.hash.merge(other.hash)?, - partial_eq: self.partial_eq.merge(other.partial_eq)?, - idents: { - let mut idents = self.idents; - for ident in other.idents { - add_unique_ident(&mut idents, ident)?; - } - idents - }, - }) + pub fn merge(&mut self, other: ReflectTraits) -> Result<(), syn::Error> { + self.debug.merge(other.debug)?; + self.hash.merge(other.hash)?; + self.partial_eq.merge(other.partial_eq)?; + for ident in other.idents { + add_unique_ident(&mut self.idents, ident)?; + } + Ok(()) } } impl Parse for ReflectTraits { fn parse(input: ParseStream) -> syn::Result { - let result = Punctuated::::parse_terminated(input)?; - ReflectTraits::from_nested_metas(&result) + let result = Punctuated::::parse_terminated(input)?; + ReflectTraits::from_metas(result.into_iter().collect::>()) } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index 1b47092dbd872..0e7402e1ff0fe 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -136,8 +136,8 @@ impl<'a> ReflectDerive<'a> { #[cfg(feature = "documentation")] let mut doc = crate::documentation::Documentation::default(); - for attribute in input.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) { - match attribute { + for attribute in &input.attrs { + match &attribute.meta { Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_ATTRIBUTE_NAME) => { if !matches!(reflect_mode, None | Some(ReflectMode::Normal)) { return Err(syn::Error::new( @@ -147,8 +147,14 @@ impl<'a> ReflectDerive<'a> { } reflect_mode = Some(ReflectMode::Normal); - let new_traits = ReflectTraits::from_nested_metas(&meta_list.nested)?; - traits = traits.merge(new_traits)?; + + let mut metas = vec![]; + meta_list.parse_nested_meta(|meta| { + metas.push(Meta::Path(meta.path)); + Ok(()) + })?; + let new_traits = ReflectTraits::from_metas(metas)?; + traits.merge(new_traits)?; } Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => { if !matches!(reflect_mode, None | Some(ReflectMode::Value)) { @@ -159,8 +165,13 @@ impl<'a> ReflectDerive<'a> { } reflect_mode = Some(ReflectMode::Value); - let new_traits = ReflectTraits::from_nested_metas(&meta_list.nested)?; - traits = traits.merge(new_traits)?; + let mut metas = vec![]; + meta_list.parse_nested_meta(|meta| { + metas.push(Meta::Path(meta.path)); + Ok(()) + })?; + let new_traits = ReflectTraits::from_metas(metas)?; + traits.merge(new_traits)?; } Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => { if !matches!(reflect_mode, None | Some(ReflectMode::Value)) { @@ -174,7 +185,11 @@ impl<'a> ReflectDerive<'a> { } #[cfg(feature = "documentation")] Meta::NameValue(pair) if pair.path.is_ident("doc") => { - if let syn::Lit::Str(lit) = pair.lit { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = &pair.value + { doc.push(lit.value()); } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs index 4bf2474873655..f3f8e3cfb9599 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs @@ -3,7 +3,7 @@ use crate::fq_std::FQOption; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; -use syn::{Attribute, Lit, Meta}; +use syn::{Attribute, Expr, ExprLit, Lit, Meta}; /// A struct used to represent a type's documentation, if any. /// @@ -21,18 +21,18 @@ impl Documentation { pub fn from_attributes<'a>(attributes: impl IntoIterator) -> Self { let docs = attributes .into_iter() - .filter_map(|attr| { - let meta = attr.parse_meta().ok()?; - match meta { - Meta::NameValue(pair) if pair.path.is_ident("doc") => { - if let Lit::Str(lit) = pair.lit { - Some(lit.value()) - } else { - None - } + .filter_map(|attr| match &attr.meta { + Meta::NameValue(pair) if pair.path.is_ident("doc") => { + if let Expr::Lit(ExprLit { + lit: Lit::Str(lit), .. + }) = &pair.value + { + Some(lit.value()) + } else { + None } - _ => None, } + _ => None, }) .collect(); diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs index a57378067b9df..e010039fbbe05 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs @@ -7,7 +7,7 @@ use crate::REFLECT_ATTRIBUTE_NAME; use quote::ToTokens; use syn::spanned::Spanned; -use syn::{Attribute, Lit, Meta, NestedMeta}; +use syn::{Attribute, Expr, Lit, Meta}; pub(crate) static IGNORE_SERIALIZATION_ATTR: &str = "skip_serializing"; pub(crate) static IGNORE_ALL_ATTR: &str = "ignore"; @@ -76,10 +76,9 @@ pub(crate) fn parse_field_attrs(attrs: &[Attribute]) -> Result Result<(), syn::Error format!("unknown attribute parameter: {}", path.to_token_stream()), )), Meta::NameValue(pair) if pair.path.is_ident(DEFAULT_ATTR) => { - let lit = &pair.lit; - match lit { + let Expr::Lit(lit) = &pair.value else { + Err(syn::Error::new( + pair.span(), + format!("expected a string literal containing the name of a function, but found: {}", pair.to_token_stream()), + ))? + }; + match &lit.lit { Lit::Str(lit_str) => { args.default = DefaultBehavior::Func(lit_str.parse()?); Ok(()) @@ -142,10 +146,8 @@ fn parse_meta(args: &mut ReflectFieldAttr, meta: &Meta) -> Result<(), syn::Error Err(syn::Error::new(list.path.span(), "unexpected property")) } Meta::List(list) => { - for nested in &list.nested { - if let NestedMeta::Meta(meta) = nested { - parse_meta(args, meta)?; - } + if let Ok(meta) = list.parse_args() { + parse_meta(args, &meta)?; } Ok(()) } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs index 353002cb7def6..ebec4eefbefe4 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs @@ -15,22 +15,13 @@ pub(crate) fn type_uuid_derive(input: proc_macro::TokenStream) -> proc_macro::To let type_ident = ast.ident; let mut uuid = None; - for attribute in ast.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) { - let Meta::NameValue(name_value) = attribute else { - continue; + for attribute in ast.attrs.iter().filter(|attr| attr.path().is_ident("uuid")) { + let Meta::NameValue(ref name_value) = attribute.meta else { + continue }; - if name_value - .path - .get_ident() - .map(|i| i != "uuid") - .unwrap_or(true) - { - continue; - } - - let uuid_str = match name_value.lit { - Lit::Str(lit_str) => lit_str, + let uuid_str = match &name_value.value { + Expr::Lit(ExprLit{lit: Lit::Str(lit_str), ..}) => lit_str, _ => panic!("`uuid` attribute must take the form `#[uuid = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"`."), }; diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index aec631dde0f8c..59ff1dab1d278 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -79,7 +79,7 @@ flate2 = { version = "1.0.22", optional = true } ruzstd = { version = "0.2.4", optional = true } # For transcoding of UASTC/ETC1S universal formats, and for .basis file support basis-universal = { version = "0.2.0", optional = true } -encase = { version = "0.5", features = ["glam"] } +encase = { version = "0.6", features = ["glam"] } # For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans. profiling = { version = "1", features = ["profile-with-tracing"], optional = true } async-channel = "1.8" diff --git a/crates/bevy_render/macros/Cargo.toml b/crates/bevy_render/macros/Cargo.toml index ae698d7a52a41..6f177ab2174b3 100644 --- a/crates/bevy_render/macros/Cargo.toml +++ b/crates/bevy_render/macros/Cargo.toml @@ -14,6 +14,6 @@ proc-macro = true [dependencies] bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.11.0-dev" } -syn = "1.0" +syn = "2.0" proc-macro2 = "1.0" quote = "1.0" diff --git a/crates/bevy_render/macros/src/as_bind_group.rs b/crates/bevy_render/macros/src/as_bind_group.rs index 7b44b7e0bbbf1..928913020590e 100644 --- a/crates/bevy_render/macros/src/as_bind_group.rs +++ b/crates/bevy_render/macros/src/as_bind_group.rs @@ -5,7 +5,7 @@ use quote::{quote, ToTokens}; use syn::{ parse::{Parse, ParseStream}, punctuated::Punctuated, - Data, DataStruct, Error, Fields, LitInt, LitStr, NestedMeta, Result, Token, + Data, DataStruct, Error, Fields, LitInt, LitStr, Meta, Result, Token, }; const UNIFORM_ATTRIBUTE_NAME: Symbol = Symbol("uniform"); @@ -48,7 +48,7 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { // Read struct-level attributes for attr in &ast.attrs { - if let Some(attr_ident) = attr.path.get_ident() { + if let Some(attr_ident) = attr.path().get_ident() { if attr_ident == BIND_GROUP_DATA_ATTRIBUTE_NAME { if let Ok(prepared_data_ident) = attr.parse_args_with(|input: ParseStream| input.parse::()) @@ -117,7 +117,7 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { // Read field-level attributes for field in fields.iter() { for attr in &field.attrs { - let Some(attr_ident) = attr.path.get_ident() else { + let Some(attr_ident) = attr.path().get_ident() else { continue; }; @@ -469,7 +469,7 @@ struct UniformBindingMeta { /// Represents the arguments for any general binding attribute. /// /// If parsed, represents an attribute -/// like `#[foo(LitInt, ...)]` where the rest is optional [`NestedMeta`]. +/// like `#[foo(LitInt, ...)]` where the rest is optional [`Meta`]. enum BindingMeta { IndexOnly(LitInt), IndexWithOptions(BindingIndexOptions), @@ -481,7 +481,7 @@ enum BindingMeta { struct BindingIndexOptions { lit_int: LitInt, _comma: Token![,], - meta_list: Punctuated, + meta_list: Punctuated, } impl Parse for BindingMeta { @@ -499,7 +499,7 @@ impl Parse for BindingIndexOptions { Ok(Self { lit_int: input.parse()?, _comma: input.parse()?, - meta_list: input.parse_terminated(NestedMeta::parse)?, + meta_list: input.parse_terminated(Meta::parse, Token![,])?, }) } } @@ -523,7 +523,7 @@ fn get_uniform_binding_attr(attr: &syn::Attribute) -> Result<(u32, Ident)> { Ok((binding_index, ident)) } -fn get_binding_nested_attr(attr: &syn::Attribute) -> Result<(u32, Vec)> { +fn get_binding_nested_attr(attr: &syn::Attribute) -> Result<(u32, Vec)> { let binding_meta = attr.parse_args_with(BindingMeta::parse)?; match binding_meta { @@ -598,43 +598,39 @@ const VISIBILITY_COMPUTE: Symbol = Symbol("compute"); const VISIBILITY_ALL: Symbol = Symbol("all"); const VISIBILITY_NONE: Symbol = Symbol("none"); -fn get_visibility_flag_value( - nested_metas: &Punctuated, -) -> Result { +fn get_visibility_flag_value(meta: Meta) -> Result { let mut visibility = VisibilityFlags::vertex_fragment(); - for meta in nested_metas { - use syn::{Meta::Path, NestedMeta::Meta}; - match meta { - // Parse `visibility(all)]`. - Meta(Path(path)) if path == VISIBILITY_ALL => { - return Ok(ShaderStageVisibility::All) - } - // Parse `visibility(none)]`. - Meta(Path(path)) if path == VISIBILITY_NONE => { - return Ok(ShaderStageVisibility::None) - } - // Parse `visibility(vertex, ...)]`. - Meta(Path(path)) if path == VISIBILITY_VERTEX => { - visibility.vertex = true; - } - // Parse `visibility(fragment, ...)]`. - Meta(Path(path)) if path == VISIBILITY_FRAGMENT => { - visibility.fragment = true; - } - // Parse `visibility(compute, ...)]`. - Meta(Path(path)) if path == VISIBILITY_COMPUTE => { - visibility.compute = true; - } - Meta(Path(path)) => return Err(Error::new_spanned( - path, - "Not a valid visibility flag. Must be `all`, `none`, or a list-combination of `vertex`, `fragment` and/or `compute`." - )), - _ => return Err(Error::new_spanned( - meta, - "Invalid visibility format: `visibility(...)`.", - )), + use syn::Meta::Path; + match meta { + // Parse `visibility(all)]`. + Path(path) if path == VISIBILITY_ALL => { + return Ok(ShaderStageVisibility::All) + } + // Parse `visibility(none)]`. + Path(path) if path == VISIBILITY_NONE => { + return Ok(ShaderStageVisibility::None) } + // Parse `visibility(vertex, ...)]`. + Path(path) if path == VISIBILITY_VERTEX => { + visibility.vertex = true; + } + // Parse `visibility(fragment, ...)]`. + Path(path) if path == VISIBILITY_FRAGMENT => { + visibility.fragment = true; + } + // Parse `visibility(compute, ...)]`. + Path(path) if path == VISIBILITY_COMPUTE => { + visibility.compute = true; + } + Path(path) => return Err(Error::new_spanned( + path, + "Not a valid visibility flag. Must be `all`, `none`, or a list-combination of `vertex`, `fragment` and/or `compute`." + )), + _ => return Err(Error::new_spanned( + meta, + "Invalid visibility format: `visibility(...)`.", + )), } Ok(ShaderStageVisibility::Flags(visibility)) @@ -727,7 +723,7 @@ const DEPTH: &str = "depth"; const S_INT: &str = "s_int"; const U_INT: &str = "u_int"; -fn get_texture_attrs(metas: Vec) -> Result { +fn get_texture_attrs(metas: Vec) -> Result { let mut dimension = Default::default(); let mut sample_type = Default::default(); let mut multisampled = Default::default(); @@ -737,35 +733,32 @@ fn get_texture_attrs(metas: Vec) -> Result { let mut visibility = ShaderStageVisibility::vertex_fragment(); for meta in metas { - use syn::{ - Meta::{List, NameValue}, - NestedMeta::Meta, - }; + use syn::Meta::{List, NameValue}; match meta { // Parse #[texture(0, dimension = "...")]. - Meta(NameValue(m)) if m.path == DIMENSION => { - let value = get_lit_str(DIMENSION, &m.lit)?; + NameValue(m) if m.path == DIMENSION => { + let value = get_lit_str(DIMENSION, &m.value)?; dimension = get_texture_dimension_value(value)?; } // Parse #[texture(0, sample_type = "...")]. - Meta(NameValue(m)) if m.path == SAMPLE_TYPE => { - let value = get_lit_str(SAMPLE_TYPE, &m.lit)?; + NameValue(m) if m.path == SAMPLE_TYPE => { + let value = get_lit_str(SAMPLE_TYPE, &m.value)?; sample_type = get_texture_sample_type_value(value)?; } // Parse #[texture(0, multisampled = "...")]. - Meta(NameValue(m)) if m.path == MULTISAMPLED => { - multisampled = get_lit_bool(MULTISAMPLED, &m.lit)?; + NameValue(m) if m.path == MULTISAMPLED => { + multisampled = get_lit_bool(MULTISAMPLED, &m.value)?; } // Parse #[texture(0, filterable = "...")]. - Meta(NameValue(m)) if m.path == FILTERABLE => { - filterable = get_lit_bool(FILTERABLE, &m.lit)?.into(); + NameValue(m) if m.path == FILTERABLE => { + filterable = get_lit_bool(FILTERABLE, &m.value)?.into(); filterable_ident = m.path.into(); } // Parse #[texture(0, visibility(...))]. - Meta(List(m)) if m.path == VISIBILITY => { - visibility = get_visibility_flag_value(&m.nested)?; + List(m) if m.path == VISIBILITY => { + visibility = get_visibility_flag_value(Meta::Path(m.path))?; } - Meta(NameValue(m)) => { + NameValue(m) => { return Err(Error::new_spanned( m.path, "Not a valid name. Available attributes: `dimension`, `sample_type`, `multisampled`, or `filterable`." @@ -865,26 +858,23 @@ const FILTERING: &str = "filtering"; const NON_FILTERING: &str = "non_filtering"; const COMPARISON: &str = "comparison"; -fn get_sampler_attrs(metas: Vec) -> Result { +fn get_sampler_attrs(metas: Vec) -> Result { let mut sampler_binding_type = Default::default(); let mut visibility = ShaderStageVisibility::vertex_fragment(); for meta in metas { - use syn::{ - Meta::{List, NameValue}, - NestedMeta::Meta, - }; + use syn::Meta::{List, NameValue}; match meta { // Parse #[sampler(0, sampler_type = "..."))]. - Meta(NameValue(m)) if m.path == SAMPLER_TYPE => { - let value = get_lit_str(DIMENSION, &m.lit)?; + NameValue(m) if m.path == SAMPLER_TYPE => { + let value = get_lit_str(DIMENSION, &m.value)?; sampler_binding_type = get_sampler_binding_type_value(value)?; } // Parse #[sampler(0, visibility(...))]. - Meta(List(m)) if m.path == VISIBILITY => { - visibility = get_visibility_flag_value(&m.nested)?; + List(m) if m.path == VISIBILITY => { + visibility = get_visibility_flag_value(Meta::Path(m.path))?; } - Meta(NameValue(m)) => { + NameValue(m) => { return Err(Error::new_spanned( m.path, "Not a valid name. Available attributes: `sampler_type`.", @@ -928,22 +918,22 @@ struct StorageAttrs { const READ_ONLY: Symbol = Symbol("read_only"); const BUFFER: Symbol = Symbol("buffer"); -fn get_storage_binding_attr(metas: Vec) -> Result { +fn get_storage_binding_attr(metas: Vec) -> Result { let mut visibility = ShaderStageVisibility::vertex_fragment(); let mut read_only = false; let mut buffer = false; for meta in metas { - use syn::{Meta::List, Meta::Path, NestedMeta::Meta}; + use syn::{Meta::List, Meta::Path}; match meta { // Parse #[storage(0, visibility(...))]. - Meta(List(m)) if m.path == VISIBILITY => { - visibility = get_visibility_flag_value(&m.nested)?; + List(m) if m.path == VISIBILITY => { + visibility = get_visibility_flag_value(Meta::Path(m.path))?; } - Meta(Path(path)) if path == READ_ONLY => { + Path(path) if path == READ_ONLY => { read_only = true; } - Meta(Path(path)) if path == BUFFER => { + Path(path) if path == BUFFER => { buffer = true; } _ => { diff --git a/crates/bevy_render/macros/src/extract_component.rs b/crates/bevy_render/macros/src/extract_component.rs index 3def17a7b8a51..8fd10ce2b4c10 100644 --- a/crates/bevy_render/macros/src/extract_component.rs +++ b/crates/bevy_render/macros/src/extract_component.rs @@ -20,7 +20,7 @@ pub fn derive_extract_component(input: TokenStream) -> TokenStream { let filter = if let Some(attr) = ast .attrs .iter() - .find(|a| a.path.is_ident("extract_component_filter")) + .find(|a| a.path().is_ident("extract_component_filter")) { let filter = match attr.parse_args::() { Ok(filter) => filter, diff --git a/crates/bevy_utils/macros/Cargo.toml b/crates/bevy_utils/macros/Cargo.toml index 1e4bc4c22f675..b6439e72b6da7 100644 --- a/crates/bevy_utils/macros/Cargo.toml +++ b/crates/bevy_utils/macros/Cargo.toml @@ -9,6 +9,6 @@ license = "MIT OR Apache-2.0" proc-macro = true [dependencies] -syn = "1.0" +syn = "2.0" quote = "1.0" proc-macro2 = "1.0" From 8e881f4baa735f2d685a161389afae93e633120a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Tue, 9 May 2023 22:14:07 +0200 Subject: [PATCH 02/14] use updated encase version --- Cargo.toml | 5 ----- crates/bevy_encase_derive/Cargo.toml | 2 +- crates/bevy_render/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b39afd5f031d..f7b0eb6f3986d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2023,8 +2023,3 @@ codegen-units = 1 inherits = "release" lto = "fat" panic = "abort" - - -[patch.crates-io] -encase = { git = "https://github.com/mockersf/encase", branch = "allow-doc-comments" } -encase_derive_impl = { git = "https://github.com/mockersf/encase", branch = "allow-doc-comments" } diff --git a/crates/bevy_encase_derive/Cargo.toml b/crates/bevy_encase_derive/Cargo.toml index 0b497eca2a084..be4e0096d55bf 100644 --- a/crates/bevy_encase_derive/Cargo.toml +++ b/crates/bevy_encase_derive/Cargo.toml @@ -13,4 +13,4 @@ proc-macro = true [dependencies] bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.11.0-dev" } -encase_derive_impl = "0.6.0" +encase_derive_impl = "0.6.1" diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index 59ff1dab1d278..f68b861524382 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -79,7 +79,7 @@ flate2 = { version = "1.0.22", optional = true } ruzstd = { version = "0.2.4", optional = true } # For transcoding of UASTC/ETC1S universal formats, and for .basis file support basis-universal = { version = "0.2.0", optional = true } -encase = { version = "0.6", features = ["glam"] } +encase = { version = "0.6.1", features = ["glam"] } # For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans. profiling = { version = "1", features = ["profile-with-tracing"], optional = true } async-channel = "1.8" From fb422743a028711f9b8ba6ac8908bf0e8aab7c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:02:17 +0200 Subject: [PATCH 03/14] update hexasphere --- crates/bevy_render/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index f68b861524382..149d7245e94ec 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -69,7 +69,7 @@ thread_local = "1.1" thiserror = "1.0" futures-lite = "1.4.0" anyhow = "1.0" -hexasphere = "8.1" +hexasphere = "9.0" parking_lot = "0.12.1" regex = "1.5" ddsfile = { version = "0.5.0", optional = true } From 886ea1fabf25788d32051e92c808cc83057a7b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:03:42 +0200 Subject: [PATCH 04/14] Update crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs Co-authored-by: Nicola Papale --- crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs index ebec4eefbefe4..c276b65cc45cb 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs @@ -17,7 +17,7 @@ pub(crate) fn type_uuid_derive(input: proc_macro::TokenStream) -> proc_macro::To let mut uuid = None; for attribute in ast.attrs.iter().filter(|attr| attr.path().is_ident("uuid")) { let Meta::NameValue(ref name_value) = attribute.meta else { - continue + continue; }; let uuid_str = match &name_value.value { From 2976171f445a0fbc11d94ca347474b17158468ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:04:51 +0200 Subject: [PATCH 05/14] remove old line --- .../bevy_reflect/bevy_reflect_derive/src/container_attributes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 4528c39a19e7a..3cd8a49c828a8 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -132,7 +132,6 @@ pub(crate) struct ReflectTraits { } impl ReflectTraits { - // pub fn from_metas(metas: &Punctuated) -> Result { pub fn from_metas(metas: Vec) -> Result { let mut traits = ReflectTraits::default(); for meta in &metas { From 824e9ecfb01a346dfa367167272589aaef2cde14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:07:03 +0200 Subject: [PATCH 06/14] improve syntax in comments Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com> --- crates/bevy_render/macros/src/as_bind_group.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/macros/src/as_bind_group.rs b/crates/bevy_render/macros/src/as_bind_group.rs index 928913020590e..a8f4b6c3114c8 100644 --- a/crates/bevy_render/macros/src/as_bind_group.rs +++ b/crates/bevy_render/macros/src/as_bind_group.rs @@ -603,23 +603,23 @@ fn get_visibility_flag_value(meta: Meta) -> Result { use syn::Meta::Path; match meta { - // Parse `visibility(all)]`. + // Parse `#[visibility(all)]`. Path(path) if path == VISIBILITY_ALL => { return Ok(ShaderStageVisibility::All) } - // Parse `visibility(none)]`. + // Parse `#[visibility(none)]`. Path(path) if path == VISIBILITY_NONE => { return Ok(ShaderStageVisibility::None) } - // Parse `visibility(vertex, ...)]`. + // Parse `#[visibility(vertex, ...)]`. Path(path) if path == VISIBILITY_VERTEX => { visibility.vertex = true; } - // Parse `visibility(fragment, ...)]`. + // Parse `#[visibility(fragment, ...)]`. Path(path) if path == VISIBILITY_FRAGMENT => { visibility.fragment = true; } - // Parse `visibility(compute, ...)]`. + // Parse `#[visibility(compute, ...)]`. Path(path) if path == VISIBILITY_COMPUTE => { visibility.compute = true; } From 23878d27d720d04f01a8e582054add5b170f9298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:16:06 +0200 Subject: [PATCH 07/14] shorter syntax --- .../src/field_attributes.rs | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs index e010039fbbe05..0aa37349b4e8c 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs @@ -7,7 +7,7 @@ use crate::REFLECT_ATTRIBUTE_NAME; use quote::ToTokens; use syn::spanned::Spanned; -use syn::{Attribute, Expr, Lit, Meta}; +use syn::{Attribute, Expr, ExprLit, Lit, Meta}; pub(crate) static IGNORE_SERIALIZATION_ATTR: &str = "skip_serializing"; pub(crate) static IGNORE_ALL_ATTR: &str = "ignore"; @@ -116,24 +116,16 @@ fn parse_meta(args: &mut ReflectFieldAttr, meta: &Meta) -> Result<(), syn::Error format!("unknown attribute parameter: {}", path.to_token_stream()), )), Meta::NameValue(pair) if pair.path.is_ident(DEFAULT_ATTR) => { - let Expr::Lit(lit) = &pair.value else { + if let Expr::Lit(ExprLit {lit: Lit::Str(lit_str), ..}) = &pair.value then { + args.default = DefaultBehavior::Func(lit_str.parse()?); + Ok(()) + } + else { Err(syn::Error::new( pair.span(), format!("expected a string literal containing the name of a function, but found: {}", pair.to_token_stream()), ))? }; - match &lit.lit { - Lit::Str(lit_str) => { - args.default = DefaultBehavior::Func(lit_str.parse()?); - Ok(()) - } - err => { - Err(syn::Error::new( - err.span(), - format!("expected a string literal containing the name of a function, but found: {}", err.to_token_stream()), - )) - } - } } Meta::NameValue(pair) => { let path = &pair.path; From 6d143bab94af3f23cfa32fa4cbb90f69767b33dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:20:20 +0200 Subject: [PATCH 08/14] update doc comment for merge --- .../bevy_reflect_derive/src/container_attributes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 3cd8a49c828a8..5bfa591f481c4 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -45,9 +45,9 @@ pub(crate) enum TraitImpl { impl TraitImpl { /// Merges this [`TraitImpl`] with another. /// - /// Returns whichever value is not [`TraitImpl::NotImplemented`]. - /// If both values are [`TraitImpl::NotImplemented`], then that is returned. - /// Otherwise, an error is returned if neither value is [`TraitImpl::NotImplemented`]. + /// Update `self` with whichever value is not [`TraitImpl::NotImplemented`]. + /// If `other` is [`TraitImpl::NotImplemented`], then `self` is not modified. + /// An error is returned if neither value is [`TraitImpl::NotImplemented`]. pub fn merge(&mut self, other: TraitImpl) -> Result<(), syn::Error> { match (&self, other) { (TraitImpl::NotImplemented, value) => { From 14d2cd32a7aacb982a7a82d6b084e9fd01789f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:29:58 +0200 Subject: [PATCH 09/14] some :facepalm: there --- .../bevy_reflect/bevy_reflect_derive/src/field_attributes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs index 0aa37349b4e8c..f4b81f08f5259 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs @@ -116,7 +116,7 @@ fn parse_meta(args: &mut ReflectFieldAttr, meta: &Meta) -> Result<(), syn::Error format!("unknown attribute parameter: {}", path.to_token_stream()), )), Meta::NameValue(pair) if pair.path.is_ident(DEFAULT_ATTR) => { - if let Expr::Lit(ExprLit {lit: Lit::Str(lit_str), ..}) = &pair.value then { + if let Expr::Lit(ExprLit {lit: Lit::Str(lit_str), ..}) = &pair.value { args.default = DefaultBehavior::Func(lit_str.parse()?); Ok(()) } @@ -125,7 +125,7 @@ fn parse_meta(args: &mut ReflectFieldAttr, meta: &Meta) -> Result<(), syn::Error pair.span(), format!("expected a string literal containing the name of a function, but found: {}", pair.to_token_stream()), ))? - }; + } } Meta::NameValue(pair) => { let path = &pair.path; From 8149b0365f6d838924b065d7ff43bbaf9518a9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 12:39:46 +0200 Subject: [PATCH 10/14] return an error on invalid attribute --- crates/bevy_ecs/macros/src/lib.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 01f9ff63657bf..8844aac76d901 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -43,12 +43,18 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { .iter() .filter(|a| a.path().is_ident(BUNDLE_ATTRIBUTE_NAME)) { - let _ = attr.parse_nested_meta(|meta| { + if let Err(error) = attr.parse_nested_meta(|meta| { if meta.path.is_ident(BUNDLE_ATTRIBUTE_IGNORE_NAME) { field_kind.push(BundleFieldKind::Ignore); + Ok(()) + } else { + Err(meta.error(format!( + "Invalid bundle attribute. Use `{BUNDLE_ATTRIBUTE_IGNORE_NAME}`" + ))) } - Ok(()) - }); + }) { + return error.into_compile_error().into(); + } } field_kind.push(BundleFieldKind::Component); From 499b4d133d2efe94a307387ed60f507cd4d9655d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 23:39:25 +0200 Subject: [PATCH 11/14] fix using a custom function for a trait --- .../src/container_attributes.rs | 19 +++++++++++++------ .../bevy_reflect_derive/src/derive_data.rs | 18 ++++++++---------- crates/bevy_reflect/src/lib.rs | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 5bfa591f481c4..16a90a7bf8ce5 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -184,12 +184,19 @@ impl ReflectTraits { list.parse_nested_meta(|meta| { // This should be the path of the custom function let trait_func_ident = TraitImpl::Custom(meta.path.clone(), span); - if meta.path.is_ident(DEBUG_ATTR) { - traits.debug.merge(trait_func_ident)?; - } else if meta.path.is_ident(PARTIAL_EQ_ATTR) { - traits.partial_eq.merge(trait_func_ident)?; - } else if meta.path.is_ident(HASH_ATTR) { - traits.hash.merge(trait_func_ident)?; + match ident.as_str() { + DEBUG_ATTR => { + traits.debug.merge(trait_func_ident)?; + } + PARTIAL_EQ_ATTR => { + traits.partial_eq.merge(trait_func_ident)?; + } + HASH_ATTR => { + traits.hash.merge(trait_func_ident)?; + } + _ => { + return Err(syn::Error::new(span, "Can only use custom functions for special traits (i.e. `Hash`, `PartialEq`, `Debug`)")); + } } Ok(()) })?; diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index 0e7402e1ff0fe..065529eaded27 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -148,11 +148,10 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Normal); - let mut metas = vec![]; - meta_list.parse_nested_meta(|meta| { - metas.push(Meta::Path(meta.path)); - Ok(()) - })?; + let metas = meta_list + .parse_args_with(Punctuated::::parse_terminated)? + .into_iter() + .collect(); let new_traits = ReflectTraits::from_metas(metas)?; traits.merge(new_traits)?; } @@ -165,11 +164,10 @@ impl<'a> ReflectDerive<'a> { } reflect_mode = Some(ReflectMode::Value); - let mut metas = vec![]; - meta_list.parse_nested_meta(|meta| { - metas.push(Meta::Path(meta.path)); - Ok(()) - })?; + let metas = meta_list + .parse_args_with(Punctuated::::parse_terminated)? + .into_iter() + .collect(); let new_traits = ReflectTraits::from_metas(metas)?; traits.merge(new_traits)?; } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index a2ef6d4af6161..4e03f6c12e02f 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1636,6 +1636,24 @@ bevy_reflect::tests::should_reflect_debug::Test { assert_eq!("Foo".to_string(), format!("{foo:?}")); } + #[test] + fn custom_debug_function() { + #[derive(Reflect)] + #[reflect(Debug(custom_debug))] + struct Foo { + a: u32, + } + + fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "123") + } + + let foo = Foo { a: 1 }; + let foo: &dyn Reflect = &foo; + + assert_eq!("123", format!("{:?}", foo)); + } + #[cfg(feature = "glam")] mod glam { use super::*; From b783ee5d5c8edc74d256dff58e4e3aa904929eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 11 May 2023 23:42:55 +0200 Subject: [PATCH 12/14] clippy --- .../bevy_reflect_derive/src/container_attributes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 16a90a7bf8ce5..d14b4bc1f96cd 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -183,7 +183,7 @@ impl ReflectTraits { list.parse_nested_meta(|meta| { // This should be the path of the custom function - let trait_func_ident = TraitImpl::Custom(meta.path.clone(), span); + let trait_func_ident = TraitImpl::Custom(meta.path, span); match ident.as_str() { DEBUG_ATTR => { traits.debug.merge(trait_func_ident)?; From bb1766082c24af0edf22ec3284d5735ad37bd46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Mon, 15 May 2023 08:41:23 +0200 Subject: [PATCH 13/14] commas! --- crates/bevy_ecs/macros/src/fetch.rs | 5 +++-- crates/bevy_ecs/macros/src/lib.rs | 10 +++++----- .../bevy_reflect_derive/src/derive_data.rs | 9 +++++---- .../bevy_reflect_derive/src/type_uuid.rs | 3 ++- crates/bevy_render/macros/src/as_bind_group.rs | 13 +++++++------ 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/crates/bevy_ecs/macros/src/fetch.rs b/crates/bevy_ecs/macros/src/fetch.rs index 4ed43cc7fed59..4e3dcb5feb11a 100644 --- a/crates/bevy_ecs/macros/src/fetch.rs +++ b/crates/bevy_ecs/macros/src/fetch.rs @@ -6,7 +6,8 @@ use syn::{ parse::{Parse, ParseStream}, parse_macro_input, parse_quote, punctuated::Punctuated, - Attribute, Data, DataStruct, DeriveInput, Field, Index, Meta, Token, + token::Comma, + Attribute, Data, DataStruct, DeriveInput, Field, Index, Meta, }; use crate::bevy_ecs_path; @@ -43,7 +44,7 @@ pub fn derive_world_query_impl(input: TokenStream) -> TokenStream { } attr.parse_args_with(|input: ParseStream| { - let meta = input.parse_terminated(syn::Meta::parse, Token![,])?; + let meta = input.parse_terminated(syn::Meta::parse, Comma)?; for meta in meta { let ident = meta.path().get_ident().unwrap_or_else(|| { panic!( diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 8844aac76d901..8be707bda63dd 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -13,8 +13,8 @@ use proc_macro::TokenStream; use proc_macro2::Span; use quote::{format_ident, quote}; use syn::{ - parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, ConstParam, - DeriveInput, GenericParam, Ident, Index, Token, TypeParam, + parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, + ConstParam, DeriveInput, GenericParam, Ident, Index, TypeParam, }; enum BundleFieldKind { @@ -303,7 +303,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { let shadowed_lifetimes: Vec<_> = generics.lifetimes().map(|_| quote!('_)).collect(); - let mut punctuated_generics = Punctuated::<_, Token![,]>::new(); + let mut punctuated_generics = Punctuated::<_, Comma>::new(); punctuated_generics.extend(lifetimeless_generics.iter().map(|g| match g { GenericParam::Type(g) => GenericParam::Type(TypeParam { default: None, @@ -316,14 +316,14 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { _ => unreachable!(), })); - let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new(); + let mut punctuated_generic_idents = Punctuated::<_, Comma>::new(); punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g { GenericParam::Type(g) => &g.ident, GenericParam::Const(g) => &g.ident, _ => unreachable!(), })); - let punctuated_generics_no_bounds: Punctuated<_, Token![,]> = lifetimeless_generics + let punctuated_generics_no_bounds: Punctuated<_, Comma> = lifetimeless_generics .iter() .map(|&g| match g.clone() { GenericParam::Type(mut g) => { diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index 065529eaded27..df6358586a4a5 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -4,11 +4,12 @@ use crate::fq_std::{FQAny, FQDefault, FQSend, FQSync}; use crate::utility::{members_to_serialization_denylist, WhereClauseOptions}; use bit_set::BitSet; use quote::quote; +use syn::token::Comma; use crate::{utility, REFLECT_ATTRIBUTE_NAME, REFLECT_VALUE_ATTRIBUTE_NAME}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{Data, DeriveInput, Field, Fields, Generics, Ident, Meta, Path, Token, Variant}; +use syn::{Data, DeriveInput, Field, Fields, Generics, Ident, Meta, Path, Variant}; pub(crate) enum ReflectDerive<'a> { Struct(ReflectStruct<'a>), @@ -149,7 +150,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Normal); let metas = meta_list - .parse_args_with(Punctuated::::parse_terminated)? + .parse_args_with(Punctuated::::parse_terminated)? .into_iter() .collect(); let new_traits = ReflectTraits::from_metas(metas)?; @@ -165,7 +166,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Value); let metas = meta_list - .parse_args_with(Punctuated::::parse_terminated)? + .parse_args_with(Punctuated::::parse_terminated)? .into_iter() .collect(); let new_traits = ReflectTraits::from_metas(metas)?; @@ -260,7 +261,7 @@ impl<'a> ReflectDerive<'a> { } fn collect_enum_variants( - variants: &'a Punctuated, + variants: &'a Punctuated, ) -> Result>, syn::Error> { let sifter: utility::ResultSifter> = variants .iter() diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs index c276b65cc45cb..6a32445439d53 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs @@ -3,6 +3,7 @@ extern crate proc_macro; use bevy_macro_utils::BevyManifest; use quote::quote; use syn::parse::{Parse, ParseStream}; +use syn::token::Comma; use syn::*; use uuid::Uuid; @@ -92,7 +93,7 @@ impl Parse for TypeUuidDef { fn parse(input: ParseStream) -> Result { let type_ident = input.parse::()?; let generics = input.parse::()?; - input.parse::()?; + input.parse::()?; let uuid = input.parse::()?.value(); let uuid = Uuid::parse_str(&uuid).map_err(|err| input.error(format!("{err}")))?; diff --git a/crates/bevy_render/macros/src/as_bind_group.rs b/crates/bevy_render/macros/src/as_bind_group.rs index a8f4b6c3114c8..9970e0b93676d 100644 --- a/crates/bevy_render/macros/src/as_bind_group.rs +++ b/crates/bevy_render/macros/src/as_bind_group.rs @@ -5,7 +5,8 @@ use quote::{quote, ToTokens}; use syn::{ parse::{Parse, ParseStream}, punctuated::Punctuated, - Data, DataStruct, Error, Fields, LitInt, LitStr, Meta, Result, Token, + token::Comma, + Data, DataStruct, Error, Fields, LitInt, LitStr, Meta, Result, }; const UNIFORM_ATTRIBUTE_NAME: Symbol = Symbol("uniform"); @@ -462,7 +463,7 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { /// like `#[uniform(LitInt, Ident)]` struct UniformBindingMeta { lit_int: LitInt, - _comma: Token![,], + _comma: Comma, ident: Ident, } @@ -480,13 +481,13 @@ enum BindingMeta { /// This represents, for example, `#[texture(0, dimension = "2d_array")]`. struct BindingIndexOptions { lit_int: LitInt, - _comma: Token![,], - meta_list: Punctuated, + _comma: Comma, + meta_list: Punctuated, } impl Parse for BindingMeta { fn parse(input: ParseStream) -> Result { - if input.peek2(Token![,]) { + if input.peek2(Comma) { input.parse().map(Self::IndexWithOptions) } else { input.parse().map(Self::IndexOnly) @@ -499,7 +500,7 @@ impl Parse for BindingIndexOptions { Ok(Self { lit_int: input.parse()?, _comma: input.parse()?, - meta_list: input.parse_terminated(Meta::parse, Token![,])?, + meta_list: input.parse_terminated(Meta::parse, Comma)?, }) } } From 402fcc5e41dd24c81cec6620326bd523ae93ff51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Mon, 15 May 2023 08:45:20 +0200 Subject: [PATCH 14/14] don't collect --- .../src/container_attributes.rs | 5 ++--- .../bevy_reflect_derive/src/derive_data.rs | 17 ++++++----------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index d14b4bc1f96cd..101bf0334efb1 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -132,7 +132,7 @@ pub(crate) struct ReflectTraits { } impl ReflectTraits { - pub fn from_metas(metas: Vec) -> Result { + pub fn from_metas(metas: Punctuated) -> Result { let mut traits = ReflectTraits::default(); for meta in &metas { match meta { @@ -304,8 +304,7 @@ impl ReflectTraits { impl Parse for ReflectTraits { fn parse(input: ParseStream) -> syn::Result { - let result = Punctuated::::parse_terminated(input)?; - ReflectTraits::from_metas(result.into_iter().collect::>()) + ReflectTraits::from_metas(Punctuated::::parse_terminated(input)?) } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index df6358586a4a5..132dc36dbaf88 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -148,12 +148,9 @@ impl<'a> ReflectDerive<'a> { } reflect_mode = Some(ReflectMode::Normal); - - let metas = meta_list - .parse_args_with(Punctuated::::parse_terminated)? - .into_iter() - .collect(); - let new_traits = ReflectTraits::from_metas(metas)?; + let new_traits = ReflectTraits::from_metas( + meta_list.parse_args_with(Punctuated::::parse_terminated)?, + )?; traits.merge(new_traits)?; } Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => { @@ -165,11 +162,9 @@ impl<'a> ReflectDerive<'a> { } reflect_mode = Some(ReflectMode::Value); - let metas = meta_list - .parse_args_with(Punctuated::::parse_terminated)? - .into_iter() - .collect(); - let new_traits = ReflectTraits::from_metas(metas)?; + let new_traits = ReflectTraits::from_metas( + meta_list.parse_args_with(Punctuated::::parse_terminated)?, + )?; traits.merge(new_traits)?; } Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {