commit c59225b54ec721fcae69f6a80d27e35b120d712e
parent cea5c6854c1e532e35d1f34b22d901509b8d6d75
Author: Jonathan Kew <jkew@mozilla.com>
Date: Thu, 23 Oct 2025 10:40:25 +0000
Bug 1995253 - patch 4 - Use thin_vec::ThinVec for PositionTryFallbacksTryTactic. r=firefox-style-system-reviewers,layout-reviewers,emilio
This should not change any behavior.
Differential Revision: https://phabricator.services.mozilla.com/D269571
Diffstat:
8 files changed, 39 insertions(+), 67 deletions(-)
diff --git a/layout/base/AnchorPositioningUtils.cpp b/layout/base/AnchorPositioningUtils.cpp
@@ -640,8 +640,6 @@ static void ApplyFallbackTactic(
StylePositionArea& aPhysicalArea,
StylePositionTryFallbacksTryTacticKeyword aTactic, WritingMode aWM) {
switch (aTactic) {
- case StylePositionTryFallbacksTryTacticKeyword::None:
- return;
case StylePositionTryFallbacksTryTacticKeyword::FlipBlock:
FlipInAxis(aPhysicalArea, aWM.PhysicalAxis(LogicalAxis::Block));
return;
@@ -660,12 +658,12 @@ static void ApplyFallbackTactic(
}
}
-static void ApplyFallbackTactic(StylePositionArea& aArea,
- StylePositionTryFallbacksTryTactic aTactic,
- WritingMode aWM) {
- ApplyFallbackTactic(aArea, aTactic._0, aWM);
- ApplyFallbackTactic(aArea, aTactic._1, aWM);
- ApplyFallbackTactic(aArea, aTactic._2, aWM);
+static void ApplyFallbackTactic(
+ StylePositionArea& aArea, const StylePositionTryFallbacksTryTactic& aTactic,
+ WritingMode aWM) {
+ for (auto t : aTactic) {
+ ApplyFallbackTactic(aArea, t, aWM);
+ }
}
/**
diff --git a/layout/base/AnchorPositioningUtils.h b/layout/base/AnchorPositioningUtils.h
@@ -78,7 +78,6 @@ class AnchorPosReferenceData {
};
struct StylePositionArea;
-struct StylePositionTryFallbacksTryTactic;
class WritingMode;
/**
diff --git a/servo/components/style/properties/cascade.rs b/servo/components/style/properties/cascade.rs
@@ -71,7 +71,7 @@ pub fn cascade<E>(
parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
first_line_reparenting: FirstLineReparenting,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &PositionTryFallbacksTryTactic,
visited_rules: Option<&StrongRuleNode>,
cascade_input_flags: ComputedValueFlags,
rule_cache: Option<&RuleCache>,
@@ -189,7 +189,7 @@ fn cascade_rules<E>(
parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
first_line_reparenting: FirstLineReparenting,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &PositionTryFallbacksTryTactic,
cascade_mode: CascadeMode,
cascade_input_flags: ComputedValueFlags,
rule_cache: Option<&RuleCache>,
@@ -265,7 +265,7 @@ pub fn apply_declarations<'a, E, I>(
parent_style: Option<&'a ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
first_line_reparenting: FirstLineReparenting<'a>,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &'a PositionTryFallbacksTryTactic,
cascade_mode: CascadeMode,
cascade_input_flags: ComputedValueFlags,
rule_cache: Option<&'a RuleCache>,
@@ -635,7 +635,7 @@ impl<'a> Declarations<'a> {
struct Cascade<'b> {
first_line_reparenting: FirstLineReparenting<'b>,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &'b PositionTryFallbacksTryTactic,
ignore_colors: bool,
seen: LonghandIdSet,
author_specified: LonghandIdSet,
@@ -647,7 +647,7 @@ struct Cascade<'b> {
impl<'b> Cascade<'b> {
fn new(
first_line_reparenting: FirstLineReparenting<'b>,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &'b PositionTryFallbacksTryTactic,
ignore_colors: bool,
) -> Self {
Self {
diff --git a/servo/components/style/style_adjuster.rs b/servo/components/style/style_adjuster.rs
@@ -933,15 +933,14 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
/// NOTE(emilio): If we ever perform the interleaving dance, this could / should probably move
/// around to the specific properties' to_computed_value implementations, but that seems
/// overkill for now.
- fn adjust_for_try_tactic(&mut self, tactic: PositionTryFallbacksTryTactic) {
+ fn adjust_for_try_tactic(&mut self, tactic: &PositionTryFallbacksTryTactic) {
debug_assert!(!tactic.is_empty());
// TODO: This is supposed to use the containing block's WM (bug 1995256).
let wm = self.style.writing_mode;
// TODO: Flip inset / margin / sizes percentages and anchor lookup sides as necessary.
- for tactic in tactic.into_iter() {
+ for tactic in tactic.iter() {
use PositionTryFallbacksTryTacticKeyword::*;
match tactic {
- None => break,
FlipBlock => {
self.flip_self_alignment(/* block = */ true);
self.flip_insets_and_margins(/* horizontal = */ wm.is_vertical());
@@ -1127,7 +1126,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
&mut self,
layout_parent_style: &ComputedValues,
element: Option<E>,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &PositionTryFallbacksTryTactic,
) where
E: TElement,
{
diff --git a/servo/components/style/style_resolver.rs b/servo/components/style/style_resolver.rs
@@ -389,7 +389,7 @@ where
parent_style,
layout_parent_style,
FirstLineReparenting::No,
- /* try_tactic = */ Default::default(),
+ /* try_tactic = */ &Default::default(),
Some(&self.context.thread_local.rule_cache),
&mut conditions,
);
diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs
@@ -1206,7 +1206,7 @@ impl Stylist {
parent_style,
parent_style,
FirstLineReparenting::No,
- PositionTryFallbacksTryTactic::default(),
+ &PositionTryFallbacksTryTactic::default(),
/* rule_cache = */ None,
&mut RuleCacheConditions::default(),
)
@@ -1270,7 +1270,7 @@ impl Stylist {
parent_style,
layout_parent_style,
FirstLineReparenting::No,
- name_and_try_tactic.try_tactic,
+ &name_and_try_tactic.try_tactic,
/* rule_cache = */ None,
&mut RuleCacheConditions::default(),
))
@@ -1299,7 +1299,7 @@ impl Stylist {
parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
first_line_reparenting: FirstLineReparenting,
- try_tactic: PositionTryFallbacksTryTactic,
+ try_tactic: &PositionTryFallbacksTryTactic,
rule_cache: Option<&RuleCache>,
rule_cache_conditions: &mut RuleCacheConditions,
) -> Arc<ComputedValues>
@@ -1803,7 +1803,7 @@ impl Stylist {
Some(parent_style),
Some(parent_style),
FirstLineReparenting::No,
- PositionTryFallbacksTryTactic::default(),
+ &PositionTryFallbacksTryTactic::default(),
CascadeMode::Unvisited {
visited_rules: None,
},
diff --git a/servo/components/style/values/specified/position.rs b/servo/components/style/values/specified/position.rs
@@ -32,6 +32,7 @@ use std::fmt::{self, Write};
use style_traits::arc_slice::ArcSlice;
use style_traits::values::specified::AllowedNumericType;
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
+use thin_vec::ThinVec;
/// The specified value of a CSS `<position>`
pub type Position = GenericPosition<HorizontalPosition, VerticalPosition>;
@@ -499,7 +500,6 @@ impl PositionAnchor {
Clone,
Copy,
Debug,
- Default,
Eq,
MallocSizeOf,
Parse,
@@ -514,10 +514,6 @@ impl PositionAnchor {
#[repr(u8)]
/// How to swap values for the automatically-generated position tactic.
pub enum PositionTryFallbacksTryTacticKeyword {
- /// Magic value for no change.
- #[css(skip)]
- #[default]
- None,
/// Swap the values in the block axis.
FlipBlock,
/// Swap the values in the inline axis.
@@ -530,38 +526,26 @@ pub enum PositionTryFallbacksTryTacticKeyword {
FlipY,
}
-impl PositionTryFallbacksTryTacticKeyword {
- fn is_none(&self) -> bool {
- *self == Self::None
- }
-}
-
#[derive(
Clone,
- Copy,
Debug,
Default,
Eq,
MallocSizeOf,
PartialEq,
- Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
-#[repr(C)]
+#[repr(transparent)]
/// Changes for the automatically-generated position option.
/// Note that this is order-dependent - e.g. `flip-start flip-inline` != `flip-inline flip-start`.
///
/// https://drafts.csswg.org/css-anchor-position-1/#typedef-position-try-fallbacks-try-tactic
pub struct PositionTryFallbacksTryTactic(
- pub PositionTryFallbacksTryTacticKeyword,
- pub PositionTryFallbacksTryTacticKeyword,
- pub PositionTryFallbacksTryTacticKeyword,
- pub PositionTryFallbacksTryTacticKeyword,
- pub PositionTryFallbacksTryTacticKeyword,
+ #[css(iterable)] pub ThinVec<PositionTryFallbacksTryTacticKeyword>,
);
impl Parse for PositionTryFallbacksTryTactic {
@@ -569,30 +553,22 @@ impl Parse for PositionTryFallbacksTryTactic {
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
- let kw = [
- PositionTryFallbacksTryTacticKeyword::parse(input)?,
- input
- .try_parse(PositionTryFallbacksTryTacticKeyword::parse)
- .unwrap_or_default(),
- input
- .try_parse(PositionTryFallbacksTryTacticKeyword::parse)
- .unwrap_or_default(),
- input
- .try_parse(PositionTryFallbacksTryTacticKeyword::parse)
- .unwrap_or_default(),
- input
- .try_parse(PositionTryFallbacksTryTacticKeyword::parse)
- .unwrap_or_default(),
- ];
- for i in 0..kw.len() - 1 {
- if kw[i].is_none() {
+ let mut result = ThinVec::with_capacity(5);
+ // Collect up to 5 keywords, disallowing duplicates.
+ for _ in 0..5 {
+ if let Ok(kw) = input.try_parse(PositionTryFallbacksTryTacticKeyword::parse) {
+ if result.contains(&kw) {
+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
+ }
+ result.push(kw);
+ } else {
break;
}
- if kw[i + 1..].contains(&kw[i]) {
- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
- }
}
- Ok(Self(kw[0], kw[1], kw[2], kw[3], kw[4]))
+ if result.is_empty() {
+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
+ }
+ Ok(Self(result))
}
}
@@ -600,13 +576,13 @@ impl PositionTryFallbacksTryTactic {
/// Returns whether there's any tactic.
#[inline]
pub fn is_empty(&self) -> bool {
- self.0.is_none()
+ self.0.is_empty()
}
/// Iterates over the fallbacks in order.
#[inline]
- pub fn into_iter(&self) -> impl IntoIterator<Item = PositionTryFallbacksTryTacticKeyword> {
- [self.0, self.1, self.2, self.3, self.4]
+ pub fn iter(&self) -> impl Iterator<Item = &PositionTryFallbacksTryTacticKeyword> {
+ self.0.iter()
}
}
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
@@ -6842,7 +6842,7 @@ pub extern "C" fn Servo_ReparentStyle(
Some(parent_style),
Some(layout_parent_style),
FirstLineReparenting::Yes { style_to_reparent },
- /* try_tactic = */ Default::default(),
+ /* try_tactic = */ &Default::default(),
/* rule_cache = */ None,
&mut RuleCacheConditions::default(),
)