mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Ensure that derived types are right for optimized-away implementations.
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
This commit is contained in:
parent
0514059618
commit
7d438cd816
18 changed files with 295 additions and 146 deletions
|
@ -408,7 +408,7 @@ impl ToCss for System {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol>
|
/// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol>
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToCss, ToShmem)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Symbol {
|
pub enum Symbol {
|
||||||
/// <string>
|
/// <string>
|
||||||
|
@ -554,7 +554,7 @@ impl Parse for Fallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols>
|
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols>
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToCss, ToShmem)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Symbols(#[css(iterable)] pub crate::OwnedSlice<Symbol>);
|
pub struct Symbols(#[css(iterable)] pub crate::OwnedSlice<Symbol>);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ macro_rules! ns {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Gecko namespace is just a wrapped atom.
|
/// A Gecko namespace is just a wrapped atom.
|
||||||
#[derive(Clone, Debug, Default, Eq, Hash, MallocSizeOf, PartialEq, ToShmem)]
|
#[derive(Clone, Debug, Default, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Namespace(pub Atom);
|
pub struct Namespace(pub Atom);
|
||||||
|
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ pub enum LogicalGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for a given longhand property.
|
/// An identifier for a given longhand property.
|
||||||
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq, ToShmem)]
|
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
pub enum LonghandId {
|
pub enum LonghandId {
|
||||||
% for i, property in enumerate(data.longhands):
|
% for i, property in enumerate(data.longhands):
|
||||||
|
@ -1353,7 +1353,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for a given shorthand property.
|
/// An identifier for a given shorthand property.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToShmem)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
pub enum ShorthandId {
|
pub enum ShorthandId {
|
||||||
% for i, property in enumerate(data.shorthands):
|
% for i, property in enumerate(data.shorthands):
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl ToAnimatedValue for FontSize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, ToResolvedValue)]
|
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToResolvedValue)]
|
||||||
#[cfg_attr(feature = "servo", derive(Hash, MallocSizeOf))]
|
#[cfg_attr(feature = "servo", derive(Hash, MallocSizeOf))]
|
||||||
/// Specifies a prioritized list of font family names or generic family names.
|
/// Specifies a prioritized list of font family names or generic family names.
|
||||||
pub struct FontFamily {
|
pub struct FontFamily {
|
||||||
|
@ -227,7 +227,7 @@ impl ToCss for FontFamily {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
/// The name of a font family of choice
|
/// The name of a font family of choice
|
||||||
pub struct FamilyName {
|
pub struct FamilyName {
|
||||||
|
@ -270,7 +270,7 @@ impl ToCss for FamilyName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
/// Font family names must either be given quoted as strings,
|
/// Font family names must either be given quoted as strings,
|
||||||
/// or unquoted as a sequence of one or more identifiers.
|
/// or unquoted as a sequence of one or more identifiers.
|
||||||
|
@ -285,7 +285,7 @@ pub enum FontFamilyNameSyntax {
|
||||||
Identifiers,
|
Identifiers,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, Hash))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, Hash))]
|
||||||
/// A set of faces that vary in weight, width or slope.
|
/// A set of faces that vary in weight, width or slope.
|
||||||
pub enum SingleFontFamily {
|
pub enum SingleFontFamily {
|
||||||
|
@ -301,7 +301,7 @@ pub enum SingleFontFamily {
|
||||||
/// `gfxPlatformFontList.h`s ranged array and `gfxFontFamilyList`'s
|
/// `gfxPlatformFontList.h`s ranged array and `gfxFontFamilyList`'s
|
||||||
/// sSingleGenerics are updated as well.
|
/// sSingleGenerics are updated as well.
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, Parse, ToCss, ToResolvedValue, ToShmem,
|
Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, Parse, ToCss, ToComputedValue, ToResolvedValue, ToShmem,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -427,16 +427,20 @@ impl SingleFontFamily {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
/// A list of SingleFontFamily
|
/// A list of SingleFontFamily
|
||||||
pub struct FontFamilyList(Box<[SingleFontFamily]>);
|
pub struct FontFamilyList(Box<[SingleFontFamily]>);
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, ToComputedValue, ToResolvedValue)]
|
||||||
/// A list of SingleFontFamily
|
/// A list of SingleFontFamily
|
||||||
pub enum FontFamilyList {
|
pub enum FontFamilyList {
|
||||||
/// A strong reference to a Gecko SharedFontList object.
|
/// A strong reference to a Gecko SharedFontList object.
|
||||||
SharedFontList(RefPtr<structs::SharedFontList>),
|
SharedFontList(
|
||||||
|
#[compute(no_field_bound)]
|
||||||
|
#[resolve(no_field_bound)]
|
||||||
|
RefPtr<structs::SharedFontList>,
|
||||||
|
),
|
||||||
/// A font-family generic ID.
|
/// A font-family generic ID.
|
||||||
Generic(GenericFontFamily),
|
Generic(GenericFontFamily),
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,7 @@ impl Size {
|
||||||
Serialize,
|
Serialize,
|
||||||
ToAnimatedValue,
|
ToAnimatedValue,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
|
|
|
@ -21,10 +21,11 @@ use crate::media_queries::Device;
|
||||||
use crate::properties;
|
use crate::properties;
|
||||||
use crate::properties::{ComputedValues, LonghandId, StyleBuilder};
|
use crate::properties::{ComputedValues, LonghandId, StyleBuilder};
|
||||||
use crate::rule_cache::RuleCacheConditions;
|
use crate::rule_cache::RuleCacheConditions;
|
||||||
use crate::Atom;
|
use crate::{ArcSlice, Atom};
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use crate::Prefix;
|
use crate::Prefix;
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
|
use servo_arc::Arc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
@ -450,6 +451,46 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(emilio): This is implementable more generically, but it's unlikely
|
||||||
|
// what you want there, as it forces you to have an extra allocation.
|
||||||
|
//
|
||||||
|
// We could do that if needed, ideally with specialization for the case where
|
||||||
|
// ComputedValue = T. But we don't need it for now.
|
||||||
|
impl<T> ToComputedValue for Arc<T>
|
||||||
|
where
|
||||||
|
T: ToComputedValue<ComputedValue = T>,
|
||||||
|
{
|
||||||
|
type ComputedValue = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, _: &Context) -> Self {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self) -> Self {
|
||||||
|
computed.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same caveat as above applies.
|
||||||
|
impl<T> ToComputedValue for ArcSlice<T>
|
||||||
|
where
|
||||||
|
T: ToComputedValue<ComputedValue = T>,
|
||||||
|
{
|
||||||
|
type ComputedValue = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, _: &Context) -> Self {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self) -> Self {
|
||||||
|
computed.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trivial_to_computed_value!(());
|
trivial_to_computed_value!(());
|
||||||
trivial_to_computed_value!(bool);
|
trivial_to_computed_value!(bool);
|
||||||
trivial_to_computed_value!(f32);
|
trivial_to_computed_value!(f32);
|
||||||
|
@ -464,6 +505,7 @@ trivial_to_computed_value!(Prefix);
|
||||||
trivial_to_computed_value!(String);
|
trivial_to_computed_value!(String);
|
||||||
trivial_to_computed_value!(Box<str>);
|
trivial_to_computed_value!(Box<str>);
|
||||||
trivial_to_computed_value!(crate::OwnedStr);
|
trivial_to_computed_value!(crate::OwnedStr);
|
||||||
|
trivial_to_computed_value!(style_traits::values::specified::AllowedNumericType);
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
|
@ -237,6 +237,8 @@ pub struct PaintWorklet {
|
||||||
/// The arguments for the worklet.
|
/// The arguments for the worklet.
|
||||||
/// TODO: store a parsed representation of the arguments.
|
/// TODO: store a parsed representation of the arguments.
|
||||||
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
|
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
|
||||||
|
#[compute(no_field_bound)]
|
||||||
|
#[resolve(no_field_bound)]
|
||||||
pub arguments: Vec<Arc<custom_properties::SpecifiedValue>>,
|
pub arguments: Vec<Arc<custom_properties::SpecifiedValue>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
//! there are used values.
|
//! there are used values.
|
||||||
|
|
||||||
use crate::properties::ComputedValues;
|
use crate::properties::ComputedValues;
|
||||||
|
use crate::ArcSlice;
|
||||||
use cssparser;
|
use cssparser;
|
||||||
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
mod color;
|
mod color;
|
||||||
|
@ -79,6 +81,7 @@ trivial_to_resolved_value!(computed::url::ComputedImageUrl);
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
trivial_to_resolved_value!(html5ever::Prefix);
|
trivial_to_resolved_value!(html5ever::Prefix);
|
||||||
trivial_to_resolved_value!(computed::LengthPercentage);
|
trivial_to_resolved_value!(computed::LengthPercentage);
|
||||||
|
trivial_to_resolved_value!(style_traits::values::specified::AllowedNumericType);
|
||||||
|
|
||||||
impl<A, B> ToResolvedValue for (A, B)
|
impl<A, B> ToResolvedValue for (A, B)
|
||||||
where
|
where
|
||||||
|
@ -214,3 +217,43 @@ where
|
||||||
Self::from(Box::from_resolved_value(resolved.into_box()))
|
Self::from(Box::from_resolved_value(resolved.into_box()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(emilio): This is implementable more generically, but it's unlikely what
|
||||||
|
// you want there, as it forces you to have an extra allocation.
|
||||||
|
//
|
||||||
|
// We could do that if needed, ideally with specialization for the case where
|
||||||
|
// ResolvedValue = T. But we don't need it for now.
|
||||||
|
impl<T> ToResolvedValue for Arc<T>
|
||||||
|
where
|
||||||
|
T: ToResolvedValue<ResolvedValue = T>,
|
||||||
|
{
|
||||||
|
type ResolvedValue = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_resolved_value(self, _: &Context) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_resolved_value(resolved: Self) -> Self {
|
||||||
|
resolved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same caveat as above applies.
|
||||||
|
impl<T> ToResolvedValue for ArcSlice<T>
|
||||||
|
where
|
||||||
|
T: ToResolvedValue<ResolvedValue = T>,
|
||||||
|
{
|
||||||
|
type ResolvedValue = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_resolved_value(self, _: &Context) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_resolved_value(resolved: Self) -> Self {
|
||||||
|
resolved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -556,7 +556,7 @@ impl SpecifiedValueInfo for AlignItems {
|
||||||
/// Value of the `justify-items` property
|
/// Value of the `justify-items` property
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-align/#justify-items-property>
|
/// <https://drafts.csswg.org/css-align/#justify-items-property>
|
||||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToShmem)]
|
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToResolvedValue, ToShmem)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct JustifyItems(pub AlignFlags);
|
pub struct JustifyItems(pub AlignFlags);
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,18 @@ impl Parse for BorderSpacing {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
pub enum BorderImageRepeatKeyword {
|
pub enum BorderImageRepeatKeyword {
|
||||||
Stretch,
|
Stretch,
|
||||||
|
|
|
@ -492,7 +492,9 @@ impl ToComputedValue for FontStretch {
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedValue,
|
ToAnimatedValue,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -534,7 +536,9 @@ impl Default for KeywordSize {
|
||||||
PartialEq,
|
PartialEq,
|
||||||
ToAnimatedValue,
|
ToAnimatedValue,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
/// Additional information for keyword-derived font sizes.
|
/// Additional information for keyword-derived font sizes.
|
||||||
|
@ -567,7 +571,7 @@ impl KeywordInfo {
|
||||||
/// Computes the final size for this font-size keyword, accounting for
|
/// Computes the final size for this font-size keyword, accounting for
|
||||||
/// text-zoom.
|
/// text-zoom.
|
||||||
fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
|
fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
|
||||||
let base = context.maybe_zoom_text(self.kw.to_computed_value(context).0);
|
let base = context.maybe_zoom_text(self.kw.to_length(context).0);
|
||||||
base * self.factor + context.maybe_zoom_text(self.offset)
|
base * self.factor + context.maybe_zoom_text(self.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,11 +764,10 @@ const LARGER_FONT_SIZE_RATIO: f32 = 1.2;
|
||||||
/// The default font size.
|
/// The default font size.
|
||||||
pub const FONT_MEDIUM_PX: i32 = 16;
|
pub const FONT_MEDIUM_PX: i32 = 16;
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
impl KeywordSize {
|
||||||
impl ToComputedValue for KeywordSize {
|
|
||||||
type ComputedValue = NonNegativeLength;
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, _: &Context) -> NonNegativeLength {
|
#[cfg(feature = "servo")]
|
||||||
|
fn to_length(&self, _: &Context) -> NonNegativeLength {
|
||||||
let medium = Length::new(FONT_MEDIUM_PX as f32);
|
let medium = Length::new(FONT_MEDIUM_PX as f32);
|
||||||
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
|
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
|
||||||
NonNegative(match *self {
|
NonNegative(match *self {
|
||||||
|
@ -779,17 +782,9 @@ impl ToComputedValue for KeywordSize {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(_: &NonNegativeLength) -> Self {
|
fn to_length(&self, cx: &Context) -> NonNegativeLength {
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
impl ToComputedValue for KeywordSize {
|
|
||||||
type ComputedValue = NonNegativeLength;
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, cx: &Context) -> NonNegativeLength {
|
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
|
|
||||||
// The tables in this function are originally from
|
// The tables in this function are originally from
|
||||||
|
@ -857,11 +852,6 @@ impl ToComputedValue for KeywordSize {
|
||||||
base_size * FONT_SIZE_FACTORS[html_size] as f32 / 100.0
|
base_size * FONT_SIZE_FACTORS[html_size] as f32 / 100.0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(_: &NonNegativeLength) -> Self {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontSize {
|
impl FontSize {
|
||||||
|
|
|
@ -539,7 +539,7 @@ impl TemplateAreas {
|
||||||
Ok(TemplateAreas {
|
Ok(TemplateAreas {
|
||||||
areas: areas.into(),
|
areas: areas.into(),
|
||||||
strings: strings.into(),
|
strings: strings.into(),
|
||||||
width: width,
|
width,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,16 @@ impl Parse for TemplateAreasArc {
|
||||||
/// A range of rows or columns. Using this instead of std::ops::Range for FFI
|
/// A range of rows or columns. Using this instead of std::ops::Range for FFI
|
||||||
/// purposes.
|
/// purposes.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem)]
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
pub struct UnsignedRange {
|
pub struct UnsignedRange {
|
||||||
/// The start of the range.
|
/// The start of the range.
|
||||||
pub start: u32,
|
pub start: u32,
|
||||||
|
@ -597,7 +606,16 @@ pub struct UnsignedRange {
|
||||||
pub end: u32,
|
pub end: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem)]
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
/// Not associated with any particular grid item, but can be referenced from the
|
/// Not associated with any particular grid item, but can be referenced from the
|
||||||
/// grid-placement properties.
|
/// grid-placement properties.
|
||||||
|
|
|
@ -35,7 +35,8 @@ use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||||
pub struct SVGPathData(
|
pub struct SVGPathData(
|
||||||
// TODO(emilio): Should probably measure this somehow only from the
|
// TODO(emilio): Should probably measure this somehow only from the
|
||||||
// specified values.
|
// specified values.
|
||||||
#[ignore_malloc_size_of = "Arc"] pub crate::ArcSlice<PathCommand>,
|
#[ignore_malloc_size_of = "Arc"]
|
||||||
|
pub crate::ArcSlice<PathCommand>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl SVGPathData {
|
impl SVGPathData {
|
||||||
|
@ -159,6 +160,8 @@ impl ComputeSquaredDistance for SVGPathData {
|
||||||
Serialize,
|
Serialize,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -488,6 +491,8 @@ impl ToCss for PathCommand {
|
||||||
Serialize,
|
Serialize,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -518,7 +523,9 @@ impl IsAbsolute {
|
||||||
Serialize,
|
Serialize,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -534,7 +541,7 @@ impl CoordPair {
|
||||||
|
|
||||||
/// The EllipticalArc flag type.
|
/// The EllipticalArc flag type.
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, SpecifiedValueInfo, ToShmem,
|
Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ArcFlag(bool);
|
pub struct ArcFlag(bool);
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl ToComputedValue for LineHeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A generic value for the `text-overflow` property.
|
/// A generic value for the `text-overflow` property.
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum TextOverflowSide {
|
pub enum TextOverflowSide {
|
||||||
/// Clip inline content.
|
/// Clip inline content.
|
||||||
|
@ -687,7 +687,7 @@ pub enum TextEmphasisStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fill mode for the text-emphasis-style property
|
/// Fill mode for the text-emphasis-style property
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum TextEmphasisFillMode {
|
pub enum TextEmphasisFillMode {
|
||||||
/// `filled`
|
/// `filled`
|
||||||
|
@ -706,7 +706,18 @@ impl TextEmphasisFillMode {
|
||||||
|
|
||||||
/// Shape keyword for the text-emphasis-style property
|
/// Shape keyword for the text-emphasis-style property
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToCss,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum TextEmphasisShapeKeyword {
|
pub enum TextEmphasisShapeKeyword {
|
||||||
|
|
|
@ -11,33 +11,25 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
||||||
let trait_impl = |from_body, to_body| {
|
let trait_impl = |from_body, to_body| {
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
fn from_animated_value(from: Self::AnimatedValue) -> Self {
|
||||||
match animated {
|
#from_body
|
||||||
#from_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_animated_value(self) -> Self::AnimatedValue {
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||||
match self {
|
#to_body
|
||||||
#to_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(emilio): Consider optimizing away non-generic cases as well?
|
|
||||||
let non_generic_implementation = || None;
|
|
||||||
|
|
||||||
to_computed_value::derive_to_value(
|
to_computed_value::derive_to_value(
|
||||||
input,
|
input,
|
||||||
parse_quote!(crate::values::animated::ToAnimatedValue),
|
parse_quote!(crate::values::animated::ToAnimatedValue),
|
||||||
parse_quote!(AnimatedValue),
|
parse_quote!(AnimatedValue),
|
||||||
BindStyle::Move,
|
BindStyle::Move,
|
||||||
|_| false,
|
|_| Default::default(),
|
||||||
|binding| quote!(crate::values::animated::ToAnimatedValue::from_animated_value(#binding)),
|
|binding| quote!(crate::values::animated::ToAnimatedValue::from_animated_value(#binding)),
|
||||||
|binding| quote!(crate::values::animated::ToAnimatedValue::to_animated_value(#binding)),
|
|binding| quote!(crate::values::animated::ToAnimatedValue::to_animated_value(#binding)),
|
||||||
trait_impl,
|
trait_impl,
|
||||||
non_generic_implementation,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub fn derive_to_value(
|
||||||
output_type_name: Ident,
|
output_type_name: Ident,
|
||||||
bind_style: BindStyle,
|
bind_style: BindStyle,
|
||||||
// Returns whether to apply the field bound for a given item.
|
// Returns whether to apply the field bound for a given item.
|
||||||
mut field_bound: impl FnMut(&BindingInfo) -> bool,
|
mut binding_attrs: impl FnMut(&BindingInfo) -> ToValueAttrs,
|
||||||
// Returns a token stream of the form: trait_path::from_foo(#binding)
|
// Returns a token stream of the form: trait_path::from_foo(#binding)
|
||||||
mut call_from: impl FnMut(&BindingInfo) -> TokenStream,
|
mut call_from: impl FnMut(&BindingInfo) -> TokenStream,
|
||||||
mut call_to: impl FnMut(&BindingInfo) -> TokenStream,
|
mut call_to: impl FnMut(&BindingInfo) -> TokenStream,
|
||||||
|
@ -26,25 +26,9 @@ pub fn derive_to_value(
|
||||||
// #second_arg
|
// #second_arg
|
||||||
// }
|
// }
|
||||||
mut trait_impl: impl FnMut(TokenStream, TokenStream) -> TokenStream,
|
mut trait_impl: impl FnMut(TokenStream, TokenStream) -> TokenStream,
|
||||||
// if this is provided, the derive for non-generic types will be simplified
|
|
||||||
// to this token stream, which should be the body of the impl block.
|
|
||||||
non_generic_implementation: impl FnOnce() -> Option<TokenStream>,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
|
|
||||||
if input.generics.type_params().next().is_none() {
|
|
||||||
if let Some(non_generic_implementation) = non_generic_implementation() {
|
|
||||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
|
||||||
return quote! {
|
|
||||||
impl #impl_generics #trait_path for #name #ty_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
#non_generic_implementation
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut where_clause = input.generics.where_clause.take();
|
let mut where_clause = input.generics.where_clause.take();
|
||||||
cg::propagate_clauses_to_output_type(
|
cg::propagate_clauses_to_output_type(
|
||||||
&mut where_clause,
|
&mut where_clause,
|
||||||
|
@ -52,33 +36,96 @@ pub fn derive_to_value(
|
||||||
&trait_path,
|
&trait_path,
|
||||||
&output_type_name,
|
&output_type_name,
|
||||||
);
|
);
|
||||||
let (to_body, from_body) = {
|
|
||||||
let params = input.generics.type_params().collect::<Vec<_>>();
|
let moves = match bind_style {
|
||||||
for param in ¶ms {
|
BindStyle::Move | BindStyle::MoveMut => true,
|
||||||
cg::add_predicate(&mut where_clause, parse_quote!(#param: #trait_path));
|
BindStyle::Ref | BindStyle::RefMut => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = input.generics.type_params().collect::<Vec<_>>();
|
||||||
|
for param in ¶ms {
|
||||||
|
cg::add_predicate(&mut where_clause, parse_quote!(#param: #trait_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut add_field_bound = |binding: &BindingInfo| {
|
||||||
|
let ty = &binding.ast().ty;
|
||||||
|
|
||||||
|
let output_type = cg::map_type_params(
|
||||||
|
ty,
|
||||||
|
¶ms,
|
||||||
|
&mut |ident| parse_quote!(<#ident as #trait_path>::#output_type_name),
|
||||||
|
);
|
||||||
|
|
||||||
|
cg::add_predicate(
|
||||||
|
&mut where_clause,
|
||||||
|
parse_quote!(
|
||||||
|
#ty: #trait_path<#output_type_name = #output_type>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let (to_body, from_body) = if params.is_empty() {
|
||||||
|
let mut s = synstructure::Structure::new(&input);
|
||||||
|
s.variants_mut().iter_mut().for_each(|v| {
|
||||||
|
v.bind_with(|_| bind_style);
|
||||||
|
});
|
||||||
|
|
||||||
|
for variant in s.variants() {
|
||||||
|
for binding in variant.bindings() {
|
||||||
|
let attrs = binding_attrs(&binding);
|
||||||
|
assert!(
|
||||||
|
!attrs.field_bound,
|
||||||
|
"It is default on a non-generic implementation",
|
||||||
|
);
|
||||||
|
if !attrs.no_field_bound {
|
||||||
|
// Add field bounds to all bindings except the manually
|
||||||
|
// excluded. This ensures the correctness of the clone() /
|
||||||
|
// move based implementation.
|
||||||
|
add_field_bound(binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let to_body = if moves {
|
||||||
|
quote! { self }
|
||||||
|
} else {
|
||||||
|
quote! { std::clone::Clone::clone(self) }
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_body = if moves {
|
||||||
|
quote! { from }
|
||||||
|
} else {
|
||||||
|
quote! { std::clone::Clone::clone(from) }
|
||||||
|
};
|
||||||
|
|
||||||
|
(to_body, from_body)
|
||||||
|
} else {
|
||||||
let to_body = cg::fmap_match(&input, bind_style, |binding| {
|
let to_body = cg::fmap_match(&input, bind_style, |binding| {
|
||||||
if field_bound(&binding) {
|
let attrs = binding_attrs(&binding);
|
||||||
let ty = &binding.ast().ty;
|
assert!(!attrs.no_field_bound, "It doesn't make sense on a generic implementation");
|
||||||
|
if attrs.field_bound {
|
||||||
let output_type = cg::map_type_params(
|
add_field_bound(&binding);
|
||||||
ty,
|
|
||||||
¶ms,
|
|
||||||
&mut |ident| parse_quote!(<#ident as #trait_path>::#output_type_name),
|
|
||||||
);
|
|
||||||
|
|
||||||
cg::add_predicate(
|
|
||||||
&mut where_clause,
|
|
||||||
parse_quote!(
|
|
||||||
#ty: #trait_path<#output_type_name = #output_type>
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
call_to(&binding)
|
call_to(&binding)
|
||||||
});
|
});
|
||||||
|
|
||||||
let from_body = cg::fmap_match(&input, bind_style, |binding| call_from(&binding));
|
let from_body = cg::fmap_match(&input, bind_style, |binding| call_from(&binding));
|
||||||
|
|
||||||
|
let self_ = if moves { quote! { self } } else { quote! { *self } };
|
||||||
|
let from_ = if moves { quote! { from } } else { quote! { *from } };
|
||||||
|
|
||||||
|
let to_body = quote! {
|
||||||
|
match #self_ {
|
||||||
|
#to_body
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_body = quote! {
|
||||||
|
match #from_ {
|
||||||
|
#from_body
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
(to_body, from_body)
|
(to_body, from_body)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,53 +148,45 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
||||||
let trait_impl = |from_body, to_body| {
|
let trait_impl = |from_body, to_body| {
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
fn from_computed_value(from: &Self::ComputedValue) -> Self {
|
||||||
match *computed {
|
#from_body
|
||||||
#from_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &crate::values::computed::Context) -> Self::ComputedValue {
|
fn to_computed_value(&self, context: &crate::values::computed::Context) -> Self::ComputedValue {
|
||||||
match *self {
|
#to_body
|
||||||
#to_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let non_generic_implementation = || {
|
|
||||||
Some(quote! {
|
|
||||||
type ComputedValue = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, _: &crate::values::computed::Context) -> Self::ComputedValue {
|
|
||||||
std::clone::Clone::clone(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
|
||||||
std::clone::Clone::clone(computed)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
derive_to_value(
|
derive_to_value(
|
||||||
input,
|
input,
|
||||||
parse_quote!(crate::values::computed::ToComputedValue),
|
parse_quote!(crate::values::computed::ToComputedValue),
|
||||||
parse_quote!(ComputedValue),
|
parse_quote!(ComputedValue),
|
||||||
BindStyle::Ref,
|
BindStyle::Ref,
|
||||||
|binding| cg::parse_field_attrs::<ComputedValueAttrs>(&binding.ast()).field_bound,
|
|binding| {
|
||||||
|
let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&binding.ast());
|
||||||
|
ToValueAttrs {
|
||||||
|
field_bound: attrs.field_bound,
|
||||||
|
no_field_bound: attrs.no_field_bound,
|
||||||
|
}
|
||||||
|
},
|
||||||
|binding| quote!(crate::values::computed::ToComputedValue::from_computed_value(#binding)),
|
|binding| quote!(crate::values::computed::ToComputedValue::from_computed_value(#binding)),
|
||||||
|binding| quote!(crate::values::computed::ToComputedValue::to_computed_value(#binding, context)),
|
|binding| quote!(crate::values::computed::ToComputedValue::to_computed_value(#binding, context)),
|
||||||
trait_impl,
|
trait_impl,
|
||||||
non_generic_implementation,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ToValueAttrs {
|
||||||
|
pub field_bound: bool,
|
||||||
|
pub no_field_bound: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[darling(attributes(compute), default)]
|
#[darling(attributes(compute), default)]
|
||||||
#[derive(Default, FromField)]
|
#[derive(Default, FromField)]
|
||||||
struct ComputedValueAttrs {
|
struct ComputedValueAttrs {
|
||||||
field_bound: bool,
|
field_bound: bool,
|
||||||
|
no_field_bound: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,8 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
||||||
let trait_impl = |from_body, to_body| {
|
let trait_impl = |from_body, to_body| {
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
|
fn from_resolved_value(from: Self::ResolvedValue) -> Self {
|
||||||
match resolved {
|
#from_body
|
||||||
#from_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -23,42 +21,26 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
||||||
self,
|
self,
|
||||||
context: &crate::values::resolved::Context,
|
context: &crate::values::resolved::Context,
|
||||||
) -> Self::ResolvedValue {
|
) -> Self::ResolvedValue {
|
||||||
match self {
|
#to_body
|
||||||
#to_body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let non_generic_implementation = || {
|
|
||||||
Some(quote! {
|
|
||||||
type ResolvedValue = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
|
|
||||||
resolved
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_resolved_value(
|
|
||||||
self,
|
|
||||||
context: &crate::values::resolved::Context,
|
|
||||||
) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
to_computed_value::derive_to_value(
|
to_computed_value::derive_to_value(
|
||||||
input,
|
input,
|
||||||
parse_quote!(crate::values::resolved::ToResolvedValue),
|
parse_quote!(crate::values::resolved::ToResolvedValue),
|
||||||
parse_quote!(ResolvedValue),
|
parse_quote!(ResolvedValue),
|
||||||
BindStyle::Move,
|
BindStyle::Move,
|
||||||
|binding| cg::parse_field_attrs::<ResolvedValueAttrs>(&binding.ast()).field_bound,
|
|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::from_resolved_value(#binding)),
|
||||||
|binding| quote!(crate::values::resolved::ToResolvedValue::to_resolved_value(#binding, context)),
|
|binding| quote!(crate::values::resolved::ToResolvedValue::to_resolved_value(#binding, context)),
|
||||||
trait_impl,
|
trait_impl,
|
||||||
non_generic_implementation,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,4 +48,5 @@ pub fn derive(input: DeriveInput) -> TokenStream {
|
||||||
#[derive(Default, FromField)]
|
#[derive(Default, FromField)]
|
||||||
struct ResolvedValueAttrs {
|
struct ResolvedValueAttrs {
|
||||||
field_bound: bool,
|
field_bound: bool,
|
||||||
|
no_field_bound: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const ARC_SLICE_CANARY: u64 = 0xf3f3f3f3f3f3f3f3;
|
||||||
/// cbindgen:derive-eq=false
|
/// cbindgen:derive-eq=false
|
||||||
/// cbindgen:derive-neq=false
|
/// cbindgen:derive-neq=false
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, ToShmem)]
|
#[derive(Debug, Eq, PartialEq, ToShmem)]
|
||||||
pub struct ArcSlice<T>(#[shmem(field_bound)] ThinArc<u64, T>);
|
pub struct ArcSlice<T>(#[shmem(field_bound)] ThinArc<u64, T>);
|
||||||
|
|
||||||
impl<T> Deref for ArcSlice<T> {
|
impl<T> Deref for ArcSlice<T> {
|
||||||
|
@ -39,6 +39,12 @@ impl<T> Deref for ArcSlice<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Clone for ArcSlice<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
ArcSlice(self.0.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
// ThinArc doesn't support alignments greater than align_of::<u64>.
|
// ThinArc doesn't support alignments greater than align_of::<u64>.
|
||||||
static ref EMPTY_ARC_SLICE: ArcSlice<u64> = {
|
static ref EMPTY_ARC_SLICE: ArcSlice<u64> = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue