From 039e1146f4276cd93a371932497f6e7f77feaceb Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Thu, 4 Nov 2021 18:31:55 +0000 Subject: [PATCH] Bug 1738520 - Make #[css(field_bound)] and #[css(iterable)] work properly. r=mats For now, use IntoIterator to figure the right type to add the bound. If we need this on types that are iterable but don't provide IntoIterator, we can add another attribute field or something. Differential Revision: https://phabricator.services.mozilla.com/D129962 --- servo/components/style_derive/to_css.rs | 16 ++++++++++++---- servo/components/style_traits/owned_slice.rs | 16 ++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/servo/components/style_derive/to_css.rs b/servo/components/style_derive/to_css.rs index 8281a82bd893..1fd47510f63a 100644 --- a/servo/components/style_derive/to_css.rs +++ b/servo/components/style_derive/to_css.rs @@ -135,11 +135,19 @@ fn derive_variant_fields_expr( Some(pair) => pair, None => return quote! { Ok(()) }, }; + if attrs.field_bound { + let ty = &first.ast().ty; + // TODO(emilio): IntoIterator might not be enough for every type of + // iterable thing (like ArcSlice<> or what not). We might want to expose + // an `item = "T"` attribute to handle that in the future. + let predicate = if attrs.iterable { + parse_quote!(<#ty as IntoIterator>::Item: style_traits::ToCss) + } else { + parse_quote!(#ty: style_traits::ToCss) + }; + cg::add_predicate(where_clause, predicate); + } if !attrs.iterable && iter.peek().is_none() { - if attrs.field_bound { - let ty = &first.ast().ty; - cg::add_predicate(where_clause, parse_quote!(#ty: style_traits::ToCss)); - } let mut expr = quote! { style_traits::ToCss::to_css(#first, dest) }; if let Some(condition) = attrs.skip_if { expr = quote! { diff --git a/servo/components/style_traits/owned_slice.rs b/servo/components/style_traits/owned_slice.rs index f60683653609..36ba3162e592 100644 --- a/servo/components/style_traits/owned_slice.rs +++ b/servo/components/style_traits/owned_slice.rs @@ -93,12 +93,6 @@ impl OwnedSlice { ret } - /// Iterate over all the elements in the slice taking ownership of them. - #[inline] - pub fn into_iter(self) -> impl Iterator + ExactSizeIterator { - self.into_vec().into_iter() - } - /// Convert the regular slice into an owned slice. #[inline] pub fn from_slice(s: &[T]) -> Self @@ -109,6 +103,16 @@ impl OwnedSlice { } } +impl IntoIterator for OwnedSlice { + type Item = T; + type IntoIter = as IntoIterator>::IntoIter; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.into_vec().into_iter() + } +} + impl Deref for OwnedSlice { type Target = [T];