Skip to content

Commit 5a6a06a

Browse files
authored
Cleaner macros utilizing syn::Member v2 (#21678)
# Objective Some macros were handling Idents and indexes as seperate things, we can use syn::Member to make this more readable and nicer. revive of #18199
1 parent f2bbf8f commit 5a6a06a

File tree

17 files changed

+234
-365
lines changed

17 files changed

+234
-365
lines changed

crates/bevy_asset/macros/src/lib.rs

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
//! Macros for deriving asset traits.
44
5-
use bevy_macro_utils::BevyManifest;
5+
use bevy_macro_utils::{as_member, BevyManifest};
66
use proc_macro::{Span, TokenStream};
77
use quote::{format_ident, quote};
8-
use syn::{parse_macro_input, Data, DeriveInput, Path};
8+
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Path};
99

1010
pub(crate) fn bevy_asset_path() -> Path {
1111
BevyManifest::shared(|manifest| manifest.get_path("bevy_asset"))
@@ -55,47 +55,30 @@ fn derive_dependency_visitor_internal(
5555
let field_has_dep = |f: &syn::Field| f.attrs.iter().any(is_dep_attribute);
5656

5757
let body = match &ast.data {
58-
Data::Struct(data_struct) => {
59-
let fields = data_struct.fields.iter();
60-
let field_visitors = fields.enumerate().filter(|(_, f)| field_has_dep(f));
61-
let field_visitors = field_visitors.map(|(i, field)| match &field.ident {
62-
Some(ident) => visit_dep(quote!(&self.#ident)),
63-
None => {
64-
let index = syn::Index::from(i);
65-
visit_dep(quote!(&self.#index))
66-
}
67-
});
68-
Some(quote!( #(#field_visitors)* ))
58+
Data::Struct(DataStruct { fields, .. }) => {
59+
let field_visitors = fields
60+
.iter()
61+
.enumerate()
62+
.filter(|(_, f)| field_has_dep(f))
63+
.map(|(i, field)| as_member(field.ident.as_ref(), i))
64+
.map(|member| visit_dep(quote!(&self.#member)));
65+
Some(quote!(#(#field_visitors)*))
6966
}
7067
Data::Enum(data_enum) => {
7168
let variant_has_dep = |v: &syn::Variant| v.fields.iter().any(field_has_dep);
7269
let any_case_required = data_enum.variants.iter().any(variant_has_dep);
7370
let cases = data_enum.variants.iter().filter(|v| variant_has_dep(v));
7471
let cases = cases.map(|variant| {
7572
let ident = &variant.ident;
76-
let fields = &variant.fields;
77-
78-
let field_visitors = fields.iter().enumerate().filter(|(_, f)| field_has_dep(f));
79-
80-
let field_visitors = field_visitors.map(|(i, field)| match &field.ident {
81-
Some(ident) => visit_dep(quote!(#ident)),
82-
None => {
83-
let ident = format_ident!("member{i}");
84-
visit_dep(quote!(#ident))
85-
}
86-
});
87-
let fields = match fields {
88-
syn::Fields::Named(fields) => {
89-
let named = fields.named.iter().map(|f| f.ident.as_ref());
90-
quote!({ #(#named,)* .. })
91-
}
92-
syn::Fields::Unnamed(fields) => {
93-
let named = (0..fields.unnamed.len()).map(|i| format_ident!("member{i}"));
94-
quote!( ( #(#named,)* ) )
95-
}
96-
syn::Fields::Unit => unreachable!("Can't pass filter is_dep_attribute"),
97-
};
98-
quote!(Self::#ident #fields => {
73+
let field_members = variant
74+
.fields
75+
.iter()
76+
.enumerate()
77+
.filter(|(_, f)| field_has_dep(f))
78+
.map(|(i, field)| as_member(field.ident.as_ref(), i));
79+
let field_locals = field_members.clone().map(|m| format_ident!("__self_{}", m));
80+
let field_visitors = field_locals.clone().map(|i| visit_dep(quote!(#i)));
81+
quote!(Self::#ident {#(#field_members: #field_locals,)* ..} => {
9982
#(#field_visitors)*
10083
})
10184
});

crates/bevy_ecs/compile_fail/tests/ui/world_query_derive.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,6 @@ struct MutableInvalidAttribute {
1717
a: &'static mut Foo,
1818
}
1919

20-
#[derive(QueryData)]
21-
#[query_data(mutable(foo))]
22-
//~^ ERROR: `mutable` does not take any arguments
23-
struct MutableInvalidAttributeParameters {
24-
a: &'static mut Foo,
25-
}
26-
27-
#[derive(QueryData)]
28-
#[query_data(derive)]
29-
//~^ ERROR: `derive` requires at least one argument
30-
struct MutableMissingAttributeParameters {
31-
a: &'static mut Foo,
32-
}
33-
3420
#[derive(QueryData)]
3521
#[query_data(mutable)]
3622
struct MutableMarked {

crates/bevy_ecs/compile_fail/tests/ui/world_query_derive.stderr

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,6 @@ error: invalid attribute, expected `mutable` or `derive`
44
14 | #[query_data(mut)]
55
| ^^^
66

7-
error: `mutable` does not take any arguments
8-
--> tests/ui/world_query_derive.rs:21:14
9-
|
10-
21 | #[query_data(mutable(foo))]
11-
| ^^^^^^^
12-
13-
error: `derive` requires at least one argument
14-
--> tests/ui/world_query_derive.rs:28:14
15-
|
16-
28 | #[query_data(derive)]
17-
| ^^^^^^
18-
197
error[E0277]: the trait bound `&'static mut Foo: ReadOnlyQueryData` is not satisfied
208
--> tests/ui/world_query_derive.rs:10:8
219
|

crates/bevy_ecs/macros/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ proc-macro = true
1111
[dependencies]
1212
bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.18.0-dev" }
1313

14-
syn = { version = "2.0.99", features = ["full", "extra-traits"] }
14+
syn = { version = "2.0.108", features = ["full", "extra-traits"] }
1515
quote = "1.0"
1616
proc-macro2 = "1.0"
1717
[lints]

crates/bevy_ecs/macros/src/component.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ pub(crate) fn map_entities(
350350
let ident = &variant.ident;
351351
let field_idents = field_members
352352
.iter()
353-
.map(|member| format_ident!("__self_{}", member))
353+
.map(|member| format_ident!("__self{}", member))
354354
.collect::<Vec<_>>();
355355

356356
map.push(

0 commit comments

Comments
 (0)