diff --git a/components/style_derive/cg.rs b/components/style_derive/cg.rs index 364fc63af13..5289eaf3f6b 100644 --- a/components/style_derive/cg.rs +++ b/components/style_derive/cg.rs @@ -126,7 +126,16 @@ pub fn fmap_trait_parts<'input, 'path>( ) -> (ImplGenerics<'input>, TypeGenerics<'input>, WhereClause<'input, 'path>, Path) { let (impl_generics, ty_generics, mut where_clause) = trait_parts(input, trait_path); where_clause.trait_output = Some(trait_output); - let output_ty = PathSegment { + let output_ty = fmap_trait_output(input, trait_path, trait_output); + (impl_generics, ty_generics, where_clause, output_ty) +} + +pub fn fmap_trait_output( + input: &DeriveInput, + trait_path: &Path, + trait_output: Ident, +) -> Path { + let segment = PathSegment { ident: input.ident.clone(), arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments { args: input.generics.params.iter().map(|arg| { @@ -151,7 +160,7 @@ pub fn fmap_trait_parts<'input, 'path>( }) }; - (impl_generics, ty_generics, where_clause, output_ty.into()) + segment.into() } pub fn is_parameterized( diff --git a/components/style_derive/to_animated_value.rs b/components/style_derive/to_animated_value.rs index 5d9cdbc0138..c2e8e4ef984 100644 --- a/components/style_derive/to_animated_value.rs +++ b/components/style_derive/to_animated_value.rs @@ -4,23 +4,34 @@ use cg; use quote; -use syn::{self, Ident}; +use syn::DeriveInput; use synstructure::BindStyle; -pub fn derive(input: syn::DeriveInput) -> quote::Tokens { - let name = &input.ident; - let trait_path = parse_quote!(values::animated::ToAnimatedValue); - let (impl_generics, ty_generics, mut where_clause, animated_value_type) = - cg::fmap_trait_parts(&input, &trait_path, Ident::from("AnimatedValue")); +pub fn derive(mut input: DeriveInput) -> quote::Tokens { + let mut where_clause = input.generics.where_clause.take(); + for param in input.generics.type_params() { + cg::add_predicate( + &mut where_clause, + parse_quote!(#param: ::values::animated::ToAnimatedValue), + ); + } + input.generics.where_clause = where_clause; let to_body = cg::fmap_match(&input, BindStyle::Move, |binding| { - where_clause.add_trait_bound(&binding.ast().ty); quote!(::values::animated::ToAnimatedValue::to_animated_value(#binding)) }); let from_body = cg::fmap_match(&input, BindStyle::Move, |binding| { quote!(::values::animated::ToAnimatedValue::from_animated_value(#binding)) }); + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let animated_value_type = cg::fmap_trait_output( + &input, + &parse_quote!(values::animated::ToAnimatedValue), + "AnimatedValue".into(), + ); + quote! { impl #impl_generics ::values::animated::ToAnimatedValue for #name #ty_generics #where_clause { type AnimatedValue = #animated_value_type;