Auto merge of #29835 - mukilan:fix-double-borrow-in-hoisted, r=mrobinson

Clear PositioningContext for speculative layouts

<!-- Please describe your changes on the following line: -->
Developed in collaboration with @mrobinson

`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.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because crash testing is currently not working in servo. New tests will be added once #29832 is fixed.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2023-06-03 05:48:13 +02:00 committed by GitHub
commit 0dd27d487f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

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 {
@ -564,6 +572,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,