mirror of
https://github.com/servo/servo.git
synced 2025-06-22 08:08:59 +01:00
We have this optimization where, for non-generic structs, we generate just a clone / move as the ToComputedValue / ToResolvedValue implementation. This moves the optimization a bit further down, and refines it so that we still generate all the relevant where clauses that make it sound, that is, that all the ToComputedValue implementations of the fields return the same type. Otherwise this wouldn't be sound and the type would need to become generic. We add an escape hatch (no_field_bound) for fields that need to be cloned but which don't implement the trait. This is right now only for the RefPtr<> in the shared font-family list, and a piece of code in PaintWorklet which looks kinda fishy, and probably should be fixed (but we don't ship it in Firefox and there's a pre-existing FIXME for servo, so I punted on it for now). The other thing this patch does is adding a bunch of ToComputedValue / ToResolvedValue implementations that are trivial and were missing. Differential Revision: https://phabricator.services.mozilla.com/D67913
52 lines
1.6 KiB
Rust
52 lines
1.6 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use derive_common::cg;
|
|
use proc_macro2::TokenStream;
|
|
use syn::DeriveInput;
|
|
use synstructure::BindStyle;
|
|
use to_computed_value;
|
|
|
|
pub fn derive(input: DeriveInput) -> TokenStream {
|
|
let trait_impl = |from_body, to_body| {
|
|
quote! {
|
|
#[inline]
|
|
fn from_resolved_value(from: Self::ResolvedValue) -> Self {
|
|
#from_body
|
|
}
|
|
|
|
#[inline]
|
|
fn to_resolved_value(
|
|
self,
|
|
context: &crate::values::resolved::Context,
|
|
) -> Self::ResolvedValue {
|
|
#to_body
|
|
}
|
|
}
|
|
};
|
|
|
|
to_computed_value::derive_to_value(
|
|
input,
|
|
parse_quote!(crate::values::resolved::ToResolvedValue),
|
|
parse_quote!(ResolvedValue),
|
|
BindStyle::Move,
|
|
|binding| {
|
|
let attrs = cg::parse_field_attrs::<ResolvedValueAttrs>(&binding.ast());
|
|
to_computed_value::ToValueAttrs {
|
|
field_bound: attrs.field_bound,
|
|
no_field_bound: attrs.no_field_bound,
|
|
}
|
|
},
|
|
|binding| quote!(crate::values::resolved::ToResolvedValue::from_resolved_value(#binding)),
|
|
|binding| quote!(crate::values::resolved::ToResolvedValue::to_resolved_value(#binding, context)),
|
|
trait_impl,
|
|
)
|
|
}
|
|
|
|
#[darling(attributes(resolve), default)]
|
|
#[derive(Default, FromField)]
|
|
struct ResolvedValueAttrs {
|
|
field_bound: bool,
|
|
no_field_bound: bool,
|
|
}
|