diff options
Diffstat (limited to 'components/style_derive/animate.rs')
-rw-r--r-- | components/style_derive/animate.rs | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/components/style_derive/animate.rs b/components/style_derive/animate.rs index 4d8581a8f2b..190568514fc 100644 --- a/components/style_derive/animate.rs +++ b/components/style_derive/animate.rs @@ -11,6 +11,8 @@ use synstructure::{Structure, VariantInfo}; pub fn derive(mut input: DeriveInput) -> TokenStream { let animation_input_attrs = cg::parse_input_attrs::<AnimationInputAttrs>(&input); + let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input); + let no_bound = animation_input_attrs.no_bound.unwrap_or_default(); let mut where_clause = input.generics.where_clause.take(); for param in input.generics.type_params() { @@ -21,39 +23,32 @@ pub fn derive(mut input: DeriveInput) -> TokenStream { ); } } - let (mut match_body, append_error_clause) = { + let (mut match_body, needs_catchall_branch) = { let s = Structure::new(&input); - let mut append_error_clause = s.variants().len() > 1; - + let needs_catchall_branch = s.variants().len() > 1; let match_body = s.variants().iter().fold(quote!(), |body, variant| { - let arm = match derive_variant_arm(variant, &mut where_clause) { - Ok(arm) => arm, - Err(()) => { - append_error_clause = true; - return body; - }, - }; + let arm = derive_variant_arm(variant, &mut where_clause); quote! { #body #arm } }); - (match_body, append_error_clause) + (match_body, needs_catchall_branch) }; input.generics.where_clause = where_clause; - if append_error_clause { - let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input); - if let Some(fallback) = input_attrs.fallback { - match_body.append_all(quote! { - (this, other) => #fallback(this, other, procedure) - }); - } else { - match_body.append_all(quote! { _ => Err(()) }); - } + if needs_catchall_branch { + // This ideally shouldn't be needed, but see + // https://github.com/rust-lang/rust/issues/68867 + match_body.append_all(quote! { _ => unsafe { debug_unreachable!() } }); } let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let fallback = match input_attrs.fallback { + Some(fallback) => quote! { #fallback(self, other, procedure) }, + None => quote! { Err(()) }, + }; + quote! { impl #impl_generics crate::values::animated::Animate for #name #ty_generics #where_clause { #[allow(unused_variables, unused_imports)] @@ -63,6 +58,9 @@ pub fn derive(mut input: DeriveInput) -> TokenStream { other: &Self, procedure: crate::values::animated::Procedure, ) -> Result<Self, ()> { + if std::mem::discriminant(self) != std::mem::discriminant(other) { + return #fallback; + } match (self, other) { #match_body } @@ -74,13 +72,17 @@ pub fn derive(mut input: DeriveInput) -> TokenStream { fn derive_variant_arm( variant: &VariantInfo, where_clause: &mut Option<WhereClause>, -) -> Result<TokenStream, ()> { +) -> TokenStream { let variant_attrs = cg::parse_variant_attrs_from_ast::<AnimationVariantAttrs>(&variant.ast()); - if variant_attrs.error { - return Err(()); - } let (this_pattern, this_info) = cg::ref_pattern(&variant, "this"); let (other_pattern, other_info) = cg::ref_pattern(&variant, "other"); + + if variant_attrs.error { + return quote! { + (&#this_pattern, &#other_pattern) => Err(()), + }; + } + let (result_value, result_info) = cg::value(&variant, "result"); let mut computations = quote!(); let iter = result_info.iter().zip(this_info.iter().zip(&other_info)); @@ -107,12 +109,13 @@ fn derive_variant_arm( } } })); - Ok(quote! { + + quote! { (&#this_pattern, &#other_pattern) => { #computations Ok(#result_value) } - }) + } } #[darling(attributes(animate), default)] |