mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Opt out of trait bounds on type params for #[derive(Animate)]
This allows us to not generate trait bounds for field types anymore, by excluding bounds for type parameters used only in fields annotated with `#[animation(error)]`. The syntax is `#[animation(no_bound(Foo, Bar))]` where `Foo` is a type parameter for the type on which we derive things. Ideally this should be an attribute on the type parameter but this isn't stable yet.
This commit is contained in:
parent
29e10d4f88
commit
5cc2d7c4b3
3 changed files with 24 additions and 13 deletions
|
@ -43,6 +43,7 @@ pub enum ShapeBox {
|
||||||
|
|
||||||
/// A shape source, for some reference box.
|
/// A shape source, for some reference box.
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
#[animate(no_bound(ImageOrUrl))]
|
||||||
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
||||||
pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
||||||
#[animation(error)]
|
#[animation(error)]
|
||||||
|
|
|
@ -15,6 +15,7 @@ use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||||
/// An SVG paint value
|
/// An SVG paint value
|
||||||
///
|
///
|
||||||
/// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint>
|
/// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint>
|
||||||
|
#[animate(no_bound(UrlPaintServer))]
|
||||||
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
|
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
|
||||||
#[derive(ToAnimatedValue, ToComputedValue, ToCss)]
|
#[derive(ToAnimatedValue, ToComputedValue, ToCss)]
|
||||||
pub struct SVGPaint<ColorType, UrlPaintServer> {
|
pub struct SVGPaint<ColorType, UrlPaintServer> {
|
||||||
|
@ -29,6 +30,7 @@ pub struct SVGPaint<ColorType, UrlPaintServer> {
|
||||||
/// Whereas the spec only allows PaintServer
|
/// Whereas the spec only allows PaintServer
|
||||||
/// to have a fallback, Gecko lets the context
|
/// to have a fallback, Gecko lets the context
|
||||||
/// properties have a fallback as well.
|
/// properties have a fallback as well.
|
||||||
|
#[animate(no_bound(UrlPaintServer))]
|
||||||
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
|
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
|
||||||
#[derive(ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)]
|
#[derive(ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)]
|
||||||
pub enum SVGPaintKind<ColorType, UrlPaintServer> {
|
pub enum SVGPaintKind<ColorType, UrlPaintServer> {
|
||||||
|
|
|
@ -2,23 +2,31 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use cg::{self, WhereClause};
|
use cg;
|
||||||
|
use darling::util::IdentList;
|
||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
use syn::{DeriveInput, Path};
|
use syn::{DeriveInput, Path};
|
||||||
use synstructure::{Structure, VariantInfo};
|
use synstructure::{Structure, VariantInfo};
|
||||||
|
|
||||||
pub fn derive(input: DeriveInput) -> Tokens {
|
pub fn derive(mut input: DeriveInput) -> Tokens {
|
||||||
let name = &input.ident;
|
|
||||||
let trait_path = parse_quote!(values::animated::Animate);
|
|
||||||
let (impl_generics, ty_generics, mut where_clause) =
|
|
||||||
cg::trait_parts(&input, &trait_path);
|
|
||||||
|
|
||||||
let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input);
|
let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input);
|
||||||
|
let no_bound = input_attrs.no_bound.unwrap_or_default();
|
||||||
|
let mut where_clause = input.generics.where_clause.take();
|
||||||
|
for param in input.generics.type_params() {
|
||||||
|
if !no_bound.contains(¶m.ident) {
|
||||||
|
cg::add_predicate(
|
||||||
|
&mut where_clause,
|
||||||
|
parse_quote!(#param: ::values::animated::Animate),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.generics.where_clause = where_clause;
|
||||||
|
|
||||||
let s = Structure::new(&input);
|
let s = Structure::new(&input);
|
||||||
let mut append_error_clause = s.variants().len() > 1;
|
let mut append_error_clause = s.variants().len() > 1;
|
||||||
|
|
||||||
let mut match_body = s.variants().iter().fold(quote!(), |body, variant| {
|
let mut match_body = s.variants().iter().fold(quote!(), |body, variant| {
|
||||||
let arm = match derive_variant_arm(variant, &mut where_clause) {
|
let arm = match derive_variant_arm(variant) {
|
||||||
Ok(arm) => arm,
|
Ok(arm) => arm,
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
append_error_clause = true;
|
append_error_clause = true;
|
||||||
|
@ -38,6 +46,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let name = &input.ident;
|
||||||
|
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics ::values::animated::Animate for #name #ty_generics #where_clause {
|
impl #impl_generics ::values::animated::Animate for #name #ty_generics #where_clause {
|
||||||
#[allow(unused_variables, unused_imports)]
|
#[allow(unused_variables, unused_imports)]
|
||||||
|
@ -55,10 +66,7 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_variant_arm(
|
fn derive_variant_arm(variant: &VariantInfo) -> Result<Tokens, ()> {
|
||||||
variant: &VariantInfo,
|
|
||||||
where_clause: &mut WhereClause,
|
|
||||||
) -> Result<Tokens, ()> {
|
|
||||||
let variant_attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
|
let variant_attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
|
||||||
if variant_attrs.error {
|
if variant_attrs.error {
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -78,7 +86,6 @@ fn derive_variant_arm(
|
||||||
let #result = ::std::clone::Clone::clone(#this);
|
let #result = ::std::clone::Clone::clone(#this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
where_clause.add_trait_bound(&result.ast().ty);
|
|
||||||
quote! {
|
quote! {
|
||||||
let #result =
|
let #result =
|
||||||
::values::animated::Animate::animate(#this, #other, procedure)?;
|
::values::animated::Animate::animate(#this, #other, procedure)?;
|
||||||
|
@ -97,6 +104,7 @@ fn derive_variant_arm(
|
||||||
#[derive(Default, FromDeriveInput)]
|
#[derive(Default, FromDeriveInput)]
|
||||||
struct AnimateInputAttrs {
|
struct AnimateInputAttrs {
|
||||||
fallback: Option<Path>,
|
fallback: Option<Path>,
|
||||||
|
no_bound: Option<IdentList>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[darling(attributes(animation), default)]
|
#[darling(attributes(animation), default)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue