Skip to content

Commit 3587aed

Browse files
authored
Merge pull request #3035 from dishmaker/dishmaker/serde_derive_with_bound_llvml
serde_derive: rewrite with_bound without filter/chain/vec allocation
2 parents 888de67 + bfc9ccf commit 3587aed

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

serde_derive/src/bound.rs

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -281,39 +281,47 @@ pub fn with_bound(
281281

282282
let relevant_type_params = visitor.relevant_type_params;
283283
let associated_type_usage = visitor.associated_type_usage;
284-
let new_predicates = generics
285-
.type_params()
286-
.map(|param| param.ident.clone())
287-
.filter(|id| relevant_type_params.contains(id))
288-
.map(|id| syn::TypePath {
289-
qself: None,
290-
path: id.into(),
291-
})
292-
.chain(associated_type_usage.into_iter().cloned())
293-
.map(|bounded_ty| {
294-
syn::WherePredicate::Type(syn::PredicateType {
295-
lifetimes: None,
296-
// the type parameter that is being bounded e.g. T
297-
bounded_ty: syn::Type::Path(bounded_ty),
298-
colon_token: <Token![:]>::default(),
299-
// the bound e.g. Serialize
300-
bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
284+
285+
fn make_where_bounded_type(
286+
bounded_ty: syn::TypePath,
287+
bound: &syn::Path,
288+
) -> syn::WherePredicate {
289+
syn::WherePredicate::Type(syn::PredicateType {
290+
lifetimes: None,
291+
// the type parameter that is being bounded e.g. T
292+
bounded_ty: syn::Type::Path(bounded_ty),
293+
colon_token: <Token![:]>::default(),
294+
// the bound e.g. Serialize
295+
bounds: {
296+
let mut punct = Punctuated::new();
297+
punct.push(syn::TypeParamBound::Trait(syn::TraitBound {
301298
paren_token: None,
302299
modifier: syn::TraitBoundModifier::None,
303300
lifetimes: None,
304301
path: bound.clone(),
305-
})]
306-
.into_iter()
307-
.collect(),
308-
})
309-
});
302+
}));
303+
punct
304+
},
305+
})
306+
}
310307

311-
let mut generics = generics.clone();
312-
generics
313-
.make_where_clause()
314-
.predicates
315-
.extend(new_predicates);
316-
generics
308+
let mut dst_generics = generics.clone();
309+
let dst_predicates = &mut dst_generics.make_where_clause().predicates;
310+
for param in generics.type_params() {
311+
let id = &param.ident;
312+
if !relevant_type_params.contains(id) {
313+
continue;
314+
}
315+
let bounded_ty = syn::TypePath {
316+
qself: None,
317+
path: id.clone().into(),
318+
};
319+
dst_predicates.push(make_where_bounded_type(bounded_ty, bound));
320+
}
321+
for bounded_ty in associated_type_usage {
322+
dst_predicates.push(make_where_bounded_type(bounded_ty.clone(), bound));
323+
}
324+
dst_generics
317325
}
318326

319327
pub fn with_self_bound(

0 commit comments

Comments
 (0)