Clear PositioningContext for speculative layouts

`try_layout` is used for laying out absolutely positioned
descendants multiple times when min/max-{width, height}
properties are set. When the same PositioningContext instance
is used between successive attempts without clearing the accumulated
descendants, we will generate multiple fragments which reference
the same box, which then will lead to a double borrow error
when layout is performed in parallel.

Signed-off-by: Mukilan Thiyagarajan <me@mukilan.in>
This commit is contained in:
Mukilan Thiyagarajan 2023-06-02 20:34:51 +05:30
parent fd7698c3ea
commit 7ead24a138

View file

@ -379,6 +379,14 @@ impl PositioningContext {
)
}
}
pub(crate) fn clear(&mut self) {
self.for_nearest_containing_block_for_all_descendants
.clear();
self.for_nearest_positioned_ancestor
.as_mut()
.map(|v| v.clear());
}
}
impl HoistedAbsolutelyPositionedBox {
@ -563,6 +571,13 @@ impl HoistedAbsolutelyPositionedBox {
"Mixed writing modes are not supported yet"
);
let dummy_tree_rank = 0;
// Clear the context since we will lay out the same descendants
// more than once. Otherwise, absolute descendants will create
// multiple fragments which could later lead to double-borrow
// errors.
positioning_context.clear();
let independent_layout = non_replaced.layout(
layout_context,
&mut positioning_context,