77
88use crate :: utility;
99use bevy_macro_utils:: fq_std:: { FQAny , FQOption } ;
10- use proc_macro2:: { Ident , Span } ;
10+ use proc_macro2:: { Ident , Span , TokenTree } ;
1111use quote:: quote_spanned;
1212use syn:: parse:: { Parse , ParseStream } ;
1313use syn:: punctuated:: Punctuated ;
1414use syn:: spanned:: Spanned ;
1515use syn:: token:: Comma ;
16- use syn:: { Expr , LitBool , Meta , Path , Token , WherePredicate } ;
16+ use syn:: { Expr , LitBool , Meta , MetaList , Path , WhereClause } ;
1717
1818// The "special" trait idents that are used internally for reflection.
1919// Received via attributes like `#[reflect(PartialEq, Hash, ...)]`
@@ -31,9 +31,6 @@ const FROM_REFLECT_ATTR: &str = "from_reflect";
3131// Attributes for `TypePath` implementation
3232const TYPE_PATH_ATTR : & str = "type_path" ;
3333
34- // Attributes for `Reflect` implementation
35- const CUSTOM_WHERE_ATTR : & str = "custom_where" ;
36-
3734// The error message to show when a trait/type is specified multiple times
3835const CONFLICTING_TYPE_DATA_MESSAGE : & str = "conflicting type data registration" ;
3936
@@ -214,12 +211,29 @@ pub(crate) struct ReflectTraits {
214211 partial_eq : TraitImpl ,
215212 from_reflect_attrs : FromReflectAttrs ,
216213 type_path_attrs : TypePathAttrs ,
217- custom_where : Option < Punctuated < WherePredicate , Token ! [ , ] > > ,
214+ custom_where : Option < WhereClause > ,
218215 idents : Vec < Ident > ,
219216}
220217
221218impl ReflectTraits {
222- pub fn from_metas (
219+ pub fn from_meta_list (
220+ meta : & MetaList ,
221+ is_from_reflect_derive : bool ,
222+ ) -> Result < Self , syn:: Error > {
223+ match meta. tokens . clone ( ) . into_iter ( ) . next ( ) {
224+ // Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
225+ Some ( TokenTree :: Ident ( ident) ) if ident == "where" => Ok ( Self {
226+ custom_where : Some ( meta. parse_args :: < WhereClause > ( ) ?) ,
227+ ..Self :: default ( )
228+ } ) ,
229+ _ => Self :: from_metas (
230+ meta. parse_args_with ( Punctuated :: < Meta , Comma > :: parse_terminated) ?,
231+ is_from_reflect_derive,
232+ ) ,
233+ }
234+ }
235+
236+ fn from_metas (
223237 metas : Punctuated < Meta , Comma > ,
224238 is_from_reflect_derive : bool ,
225239 ) -> Result < Self , syn:: Error > {
@@ -257,12 +271,6 @@ impl ReflectTraits {
257271 }
258272 }
259273 }
260- // Handles `#[reflect(custom_where(T: Trait, U::Assoc: Trait))]`
261- Meta :: List ( list) if list. path . is_ident ( CUSTOM_WHERE_ATTR ) => {
262- let predicate: Punctuated < WherePredicate , Token ! [ , ] > =
263- list. parse_args_with ( Punctuated :: parse_terminated) ?;
264- traits. merge_custom_where ( Some ( predicate) ) ;
265- }
266274 // Handles `#[reflect( Debug(custom_debug_fn) )]`
267275 Meta :: List ( list) if list. path . is_ident ( DEBUG_ATTR ) => {
268276 let ident = list. path . get_ident ( ) . unwrap ( ) ;
@@ -290,7 +298,9 @@ impl ReflectTraits {
290298 Meta :: List ( list) => {
291299 return Err ( syn:: Error :: new_spanned (
292300 list,
293- format ! ( "expected one of [{DEBUG_ATTR:?}, {PARTIAL_EQ_ATTR:?}, {HASH_ATTR:?}, {CUSTOM_WHERE_ATTR:?}]" )
301+ format ! (
302+ "expected one of [{DEBUG_ATTR:?}, {PARTIAL_EQ_ATTR:?}, {HASH_ATTR:?}]"
303+ ) ,
294304 ) ) ;
295305 }
296306 Meta :: NameValue ( pair) => {
@@ -408,7 +418,7 @@ impl ReflectTraits {
408418 }
409419 }
410420
411- pub fn custom_where ( & self ) -> Option < & Punctuated < WherePredicate , Token ! [ , ] > > {
421+ pub fn custom_where ( & self ) -> Option < & WhereClause > {
412422 self . custom_where . as_ref ( )
413423 }
414424
@@ -430,10 +440,10 @@ impl ReflectTraits {
430440 Ok ( ( ) )
431441 }
432442
433- fn merge_custom_where ( & mut self , other : Option < Punctuated < WherePredicate , Token ! [ , ] > > ) {
443+ fn merge_custom_where ( & mut self , other : Option < WhereClause > ) {
434444 match ( & mut self . custom_where , other) {
435445 ( Some ( this) , Some ( other) ) => {
436- this. extend ( other) ;
446+ this. predicates . extend ( other. predicates ) ;
437447 }
438448 ( None , Some ( other) ) => {
439449 self . custom_where = Some ( other) ;
0 commit comments