Skip to content

Carry resolved anchor() insets on the abspos layout inputs - #11078

Merged
kalenikaliaksandr merged 2 commits into
LadybirdBrowser:masterfrom
kalenikaliaksandr:anchor-inset-store-removal
Aug 10, 2026
Merged

Carry resolved anchor() insets on the abspos layout inputs#11078
kalenikaliaksandr merged 2 commits into
LadybirdBrowser:masterfrom
kalenikaliaksandr:anchor-inset-store-removal

Conversation

@kalenikaliaksandr

Copy link
Copy Markdown
Member

Anchor resolution published its results through a pass-global side store
on LayoutState that every later inset style read consulted, running as
an implicit channel parallel to AbsposLayoutInputs, which already
crosses the run boundary into the out-of-flow sizing passes and is
persisted for replay. Make resolve_anchor_insets pure and thread its
result explicitly: the abspos engine stores it on the layout inputs and
hands it to the sizing chain, compute_inset consumes its own resolution
locally, and replay now reuses the resolutions the original pass saved
instead of reading unresolved anchor() values against an empty store.

This removes the last pass-global mutable state from layout:
LayoutState is now only the pass purpose.

The calculated wrapper a bare anchor() inset resolves through was
memoized in the pass-global anchor-inset store, which existed in part
only to own the Arc those reads borrow. Build the wrapper eagerly when a
fresh surround payload is created instead: equality excludes the
wrappers (they are pure derivatives of the anchor-inset fields), so
deduped payloads keep sharing, and inset reads now borrow the wrapper
straight from the immutable payload.
Anchor resolution published its results through a pass-global side store
on LayoutState that every later inset style read consulted, running as
an implicit channel parallel to AbsposLayoutInputs, which already
crosses the run boundary into the out-of-flow sizing passes and is
persisted for replay. Make resolve_anchor_insets pure and thread its
result explicitly: the abspos engine stores it on the layout inputs and
hands it to the sizing chain, compute_inset consumes its own resolution
locally, and replay now reuses the resolutions the original pass saved
instead of reading unresolved anchor() values against an empty store.

This removes the last pass-global mutable state from layout:
LayoutState is now only the pass purpose.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds computed wrapper handles for bare anchor() insets. It replaces the per-layout anchor inset store with ResolvedAnchorInsets. Absolute-positioned layout now returns resolved inset data and passes it through containing-block setup, sizing, root layout, replay, and relative inset computation. StyleValues applies resolved overrides, then wrapper payloads, then computed style values.

Sequence Diagram(s)

sequenceDiagram
  participant AbsposLayout as abspos_engine
  participant StyleValues
  participant ContainingBlock
  participant LayoutInputs as AbsposLayoutInputs
  AbsposLayout->>ContainingBlock: resolve anchor insets
  AbsposLayout->>StyleValues: read resolved inset values
  AbsposLayout->>LayoutInputs: save resolved_anchor_insets
  LayoutInputs-->>AbsposLayout: provide data during replay
  AbsposLayout->>StyleValues: apply inset overrides during sizing
Loading

Possibly related PRs

Suggested reviewers: calme1709

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the removal of pass-global anchor-inset state and explicit threading of resolved insets, matching the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Libraries/LibWeb/Rust/src/layout/grid_formatting_context.rs (1)

3528-3530: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tighten the last clause of the comment.

The first two claims are accurate. layout_pending_child() does resolve the insets later, at abspos_engine.rs Line 1728.

The third claim, "an anchor-bearing inset is never auto either way", holds only before resolution. Before resolution the side is InsetValue::BareAnchor, and is_auto() returns false. After resolution the side is InsetValue::Resolved, and is_auto() returns resolved.is_auto, which resolve_anchor_insets() sets to true when the anchor does not resolve. The recompute in base_containing_block_info() covers that case, so the code is correct; only the stated invariant is too strong.

📝 Proposed comment wording
-                    // Registration-time axis modes read raw style: anchor()
-                    // insets resolve later in layout_pending_child, and an
-                    // anchor-bearing inset is never auto either way.
+                    // Registration-time axis modes read raw style: anchor()
+                    // insets resolve later in layout_pending_child, where an
+                    // unresolvable anchor becomes auto and the axis modes are
+                    // recomputed from the resolutions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Libraries/LibWeb/Rust/src/layout/grid_formatting_context.rs` around lines
3528 - 3530, Update the comment near the axis-mode registration logic to limit
the “anchor-bearing inset is never auto” statement to the
pre-resolution/raw-style state. Mention that anchor insets may become auto after
resolution when the anchor cannot be resolved, while preserving the accurate
claims about later resolution in layout_pending_child().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Libraries/LibWeb/Rust/src/layout/grid_formatting_context.rs`:
- Around line 3528-3530: Update the comment near the axis-mode registration
logic to limit the “anchor-bearing inset is never auto” statement to the
pre-resolution/raw-style state. Mention that anchor insets may become auto after
resolution when the anchor cannot be resolved, while preserving the accurate
claims about later resolution in layout_pending_child().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6708c445-adc5-4f8c-a27f-d0ab33cfcefa

📥 Commits

Reviewing files that changed from the base of the PR and between 5b3e3fa and 3f96ded.

📒 Files selected for processing (7)
  • Libraries/LibWeb/Rust/src/css/computed_value_types.rs
  • Libraries/LibWeb/Rust/src/css/computed_values.rs
  • Libraries/LibWeb/Rust/src/layout/abspos_engine.rs
  • Libraries/LibWeb/Rust/src/layout/formatting_context.rs
  • Libraries/LibWeb/Rust/src/layout/grid_formatting_context.rs
  • Libraries/LibWeb/Rust/src/layout/layout_state.rs
  • Libraries/LibWeb/Rust/src/layout/style_facts.rs

@kalenikaliaksandr
kalenikaliaksandr merged commit 0073974 into LadybirdBrowser:master Aug 10, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant