diff --git a/components/derive_common/cg.rs b/components/derive_common/cg.rs index c51c0d7750b..8abfd871496 100644 --- a/components/derive_common/cg.rs +++ b/components/derive_common/cg.rs @@ -154,19 +154,19 @@ pub fn fmap_trait_output(input: &DeriveInput, trait_path: &Path, trait_output: & segment.into() } -pub fn map_type_params(ty: &Type, params: &[&TypeParam], f: &mut F) -> Type +pub fn map_type_params(ty: &Type, params: &[&TypeParam], self_type: &Path, f: &mut F) -> Type where F: FnMut(&Ident) -> Type, { match *ty { Type::Slice(ref inner) => Type::from(TypeSlice { - elem: Box::new(map_type_params(&inner.elem, params, f)), + elem: Box::new(map_type_params(&inner.elem, params, self_type, f)), ..inner.clone() }), Type::Array(ref inner) => { //ref ty, ref expr) => { Type::from(TypeArray { - elem: Box::new(map_type_params(&inner.elem, params, f)), + elem: Box::new(map_type_params(&inner.elem, params, self_type, f)), ..inner.clone() }) }, @@ -175,7 +175,7 @@ where elems: inner .elems .iter() - .map(|ty| map_type_params(&ty, params, f)) + .map(|ty| map_type_params(&ty, params, self_type, f)) .collect(), ..inner.clone() }), @@ -187,10 +187,16 @@ where if params.iter().any(|ref param| ¶m.ident == ident) { return f(ident); } + if ident == "Self" { + return Type::from(TypePath { + qself: None, + path: self_type.clone(), + }); + } } Type::from(TypePath { qself: None, - path: map_type_params_in_path(path, params, f), + path: map_type_params_in_path(path, params, self_type, f), }) }, Type::Path(TypePath { @@ -198,25 +204,25 @@ where ref path, }) => Type::from(TypePath { qself: qself.as_ref().map(|qself| QSelf { - ty: Box::new(map_type_params(&qself.ty, params, f)), + ty: Box::new(map_type_params(&qself.ty, params, self_type, f)), position: qself.position, ..qself.clone() }), - path: map_type_params_in_path(path, params, f), + path: map_type_params_in_path(path, params, self_type, f), }), Type::Paren(ref inner) => Type::from(TypeParen { - elem: Box::new(map_type_params(&inner.elem, params, f)), + elem: Box::new(map_type_params(&inner.elem, params, self_type, f)), ..inner.clone() }), Type::Group(ref inner) => Type::from(TypeGroup { - elem: Box::new(map_type_params(&inner.elem, params, f)), + elem: Box::new(map_type_params(&inner.elem, params, self_type, f)), ..inner.clone() }), ref ty => panic!("type {:?} cannot be mapped yet", ty), } } -fn map_type_params_in_path(path: &Path, params: &[&TypeParam], f: &mut F) -> Path +fn map_type_params_in_path(path: &Path, params: &[&TypeParam], self_type: &Path, f: &mut F) -> Path where F: FnMut(&Ident) -> Type, { @@ -236,11 +242,11 @@ where .map(|arg| match arg { ty @ &GenericArgument::Lifetime(_) => ty.clone(), &GenericArgument::Type(ref data) => { - GenericArgument::Type(map_type_params(data, params, f)) + GenericArgument::Type(map_type_params(data, params, self_type, f)) }, &GenericArgument::Binding(ref data) => { GenericArgument::Binding(Binding { - ty: map_type_params(&data.ty, params, f), + ty: map_type_params(&data.ty, params, self_type, f), ..data.clone() }) }, diff --git a/components/style_derive/specified_value_info.rs b/components/style_derive/specified_value_info.rs index b9473c64008..c477f4a7cf9 100644 --- a/components/style_derive/specified_value_info.rs +++ b/components/style_derive/specified_value_info.rs @@ -112,6 +112,7 @@ pub fn derive(mut input: DeriveInput) -> TokenStream { let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + quote! { impl #impl_generics style_traits::SpecifiedValueInfo for #name #ty_generics #where_clause diff --git a/components/style_derive/to_computed_value.rs b/components/style_derive/to_computed_value.rs index 5fe2be5af75..5e0f595c6b9 100644 --- a/components/style_derive/to_computed_value.rs +++ b/components/style_derive/to_computed_value.rs @@ -47,12 +47,15 @@ pub fn derive_to_value( cg::add_predicate(&mut where_clause, parse_quote!(#param: #trait_path)); } + let computed_value_type = cg::fmap_trait_output(&input, &trait_path, &output_type_name); + let mut add_field_bound = |binding: &BindingInfo| { let ty = &binding.ast().ty; let output_type = cg::map_type_params( ty, ¶ms, + &computed_value_type, &mut |ident| parse_quote!(<#ident as #trait_path>::#output_type_name), ); @@ -142,7 +145,6 @@ pub fn derive_to_value( input.generics.where_clause = where_clause; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let computed_value_type = cg::fmap_trait_output(&input, &trait_path, &output_type_name); let impl_ = trait_impl(from_body, to_body);