Skip to content

Commit 888de67

Browse files
authored
Merge pull request #3034 from dishmaker/dishmaker/serde_derive_less_filter_map
serde_derive: rewrite .iter().filter_map() with less llvm-lines
2 parents 681270e + 2c6d0d2 commit 888de67

File tree

3 files changed

+78
-72
lines changed

3 files changed

+78
-72
lines changed

serde_derive/src/bound.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ pub fn with_where_predicates(
3131
predicates: &[syn::WherePredicate],
3232
) -> syn::Generics {
3333
let mut generics = generics.clone();
34-
generics
35-
.make_where_clause()
36-
.predicates
37-
.extend(predicates.iter().cloned());
34+
let dst_predicates = &mut generics.make_where_clause().predicates;
35+
36+
for predicate in predicates {
37+
dst_predicates.push(predicate.clone());
38+
}
3839
generics
3940
}
4041

@@ -43,14 +44,17 @@ pub fn with_where_predicates_from_fields(
4344
generics: &syn::Generics,
4445
from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
4546
) -> syn::Generics {
46-
let predicates = cont
47-
.data
48-
.all_fields()
49-
.filter_map(|field| from_field(&field.attrs))
50-
.flat_map(<[syn::WherePredicate]>::to_vec);
51-
5247
let mut generics = generics.clone();
53-
generics.make_where_clause().predicates.extend(predicates);
48+
let dst_predicates = &mut generics.make_where_clause().predicates;
49+
50+
for field in cont.data.all_fields() {
51+
let Some(predicate_slice) = from_field(&field.attrs) else {
52+
continue;
53+
};
54+
for inner_predicate in predicate_slice {
55+
dst_predicates.push(inner_predicate.clone());
56+
}
57+
}
5458
generics
5559
}
5660

@@ -65,14 +69,17 @@ pub fn with_where_predicates_from_variants(
6569
return generics.clone();
6670
}
6771
};
68-
69-
let predicates = variants
70-
.iter()
71-
.filter_map(|variant| from_variant(&variant.attrs))
72-
.flat_map(<[syn::WherePredicate]>::to_vec);
73-
7472
let mut generics = generics.clone();
75-
generics.make_where_clause().predicates.extend(predicates);
73+
let dst_predicates = &mut generics.make_where_clause().predicates;
74+
75+
for variant in variants {
76+
let Some(predicate_slice) = from_variant(&variant.attrs) else {
77+
continue;
78+
};
79+
for inner_predicate in predicate_slice {
80+
dst_predicates.push(inner_predicate.clone());
81+
}
82+
}
7683
generics
7784
}
7885

@@ -256,18 +263,18 @@ pub fn with_bound(
256263
match &cont.data {
257264
Data::Enum(variants) => {
258265
for variant in variants {
259-
let relevant_fields = variant
260-
.fields
261-
.iter()
262-
.filter(|field| filter(&field.attrs, Some(&variant.attrs)));
263-
for field in relevant_fields {
264-
visitor.visit_field(field.original);
266+
for field in &variant.fields {
267+
if filter(&field.attrs, Some(&variant.attrs)) {
268+
visitor.visit_field(field.original);
269+
}
265270
}
266271
}
267272
}
268273
Data::Struct(_, fields) => {
269-
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
270-
visitor.visit_field(field.original);
274+
for field in fields {
275+
if filter(&field.attrs, None) {
276+
visitor.visit_field(field.original);
277+
}
271278
}
272279
}
273280
}

serde_derive/src/de/enum_adjacently.rs

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,19 @@ pub(super) fn deserialize(
3131

3232
let (variants_stmt, variant_visitor) = enum_::prepare_enum_variant_enum(variants);
3333

34-
let variant_arms: &Vec<_> = &variants
35-
.iter()
36-
.enumerate()
37-
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
38-
.map(|(i, variant)| {
39-
let variant_index = field_i(i);
34+
let mut variant_arms = Vec::new();
35+
for (i, variant) in variants.iter().enumerate() {
36+
if variant.attrs.skip_deserializing() {
37+
continue;
38+
}
39+
let variant_index = field_i(i);
4040

41-
let block = Match(enum_untagged::deserialize_variant(params, variant, cattrs));
41+
let block = Match(enum_untagged::deserialize_variant(params, variant, cattrs));
4242

43-
quote! {
44-
__Field::#variant_index => #block
45-
}
46-
})
47-
.collect();
43+
variant_arms.push(quote! {
44+
__Field::#variant_index => #block
45+
});
46+
}
4847

4948
let rust_name = params.type_name();
5049
let expecting = format!("adjacently tagged enum {}", rust_name);
@@ -64,35 +63,35 @@ pub(super) fn deserialize(
6463
_serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
6564
};
6665
let mut missing_content_fallthrough = quote!();
67-
let missing_content_arms = variants
68-
.iter()
69-
.enumerate()
70-
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
71-
.filter_map(|(i, variant)| {
72-
let variant_index = field_i(i);
73-
let variant_ident = &variant.ident;
66+
let mut missing_content_arms = Vec::new();
67+
for (i, variant) in variants.iter().enumerate() {
68+
if variant.attrs.skip_deserializing() {
69+
continue;
70+
}
71+
let variant_index = field_i(i);
72+
let variant_ident = &variant.ident;
7473

75-
let arm = match variant.style {
76-
Style::Unit => quote! {
77-
_serde::#private::Ok(#this_value::#variant_ident)
78-
},
79-
Style::Newtype if variant.attrs.deserialize_with().is_none() => {
80-
let span = variant.original.span();
81-
let func = quote_spanned!(span=> _serde::#private::de::missing_field);
82-
quote! {
83-
#func(#content).map(#this_value::#variant_ident)
84-
}
85-
}
86-
_ => {
87-
missing_content_fallthrough = quote!(_ => #missing_content);
88-
return None;
74+
let arm = match variant.style {
75+
Style::Unit => quote! {
76+
_serde::#private::Ok(#this_value::#variant_ident)
77+
},
78+
Style::Newtype if variant.attrs.deserialize_with().is_none() => {
79+
let span = variant.original.span();
80+
let func = quote_spanned!(span=> _serde::#private::de::missing_field);
81+
quote! {
82+
#func(#content).map(#this_value::#variant_ident)
8983
}
90-
};
91-
Some(quote! {
92-
__Field::#variant_index => #arm,
93-
})
94-
})
95-
.collect::<Vec<_>>();
84+
}
85+
_ => {
86+
missing_content_fallthrough = quote!(_ => #missing_content);
87+
continue;
88+
}
89+
};
90+
missing_content_arms.push(quote! {
91+
__Field::#variant_index => #arm,
92+
});
93+
}
94+
9695
if !missing_content_arms.is_empty() {
9796
missing_content = quote! {
9897
match __field {

serde_derive/src/pretend.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,18 @@ fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStre
114114
let type_ident = &cont.ident;
115115
let (_, ty_generics, _) = cont.generics.split_for_impl();
116116

117-
let patterns = variants
118-
.iter()
119-
.filter_map(|variant| match variant.style {
117+
let mut patterns = Vec::new();
118+
for variant in variants {
119+
match variant.style {
120120
Style::Struct | Style::Tuple | Style::Newtype => {
121121
let variant_ident = &variant.ident;
122122
let members = variant.fields.iter().map(|field| &field.member);
123123
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
124-
Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
124+
patterns.push(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
125125
}
126-
Style::Unit => None,
127-
})
128-
.collect::<Vec<_>>();
126+
Style::Unit => {}
127+
}
128+
}
129129

130130
let private2 = private;
131131
quote! {

0 commit comments

Comments
 (0)