Record the eleventh sweep, over the built-in bounds work

This commit is contained in:
iris-ai committed 2026-09-20 20:15:02 -04:00
1 parent 17423a57b8
commit 5f01dc65c8
2 files changed
+123 -11

No files matched your search

+93
View File
@@ -6,6 +6,99 @@ nothing here is rediscovered. Each entry says who found it and when.
it (settled design, the measurement method) belongs in `docs/LAYOUT.md`, and
the current plan is in `docs/HANDOFF.md`.
## Eleventh sweep: the built-in bounds work (2026-09-20)
Over `2ac0843`, which no earlier round reviewed -- `SizeRule` from an enum to
a preferred length beside an independent `Bound`, the offer constrained in
`Placing::ask`, and `MaxSize` removed. 554 inserted lines over 18 files. Eight
findings, all in `ea1f836`.
- **A hint read that answered "cannot say" was counted as no read at all.**
The bound check moved out of `Painter::size_request` and into
`Painter::size_hint`, where it returns above `diag::hint_read` and the
`HintHits`/`HintMisses` bump. So a bounded child was neither a hit nor a
miss and left no trace event, in the one place the counters exist to watch.
It is a miss now -- the bound makes the hint `None` rather than returning
early -- with the reason written on it, since the obvious simplification
back to an early return silently loses the counter again.
- **Two loops over both axes, writing the same value.** `draw_widget` grew a
second `for axis in Axis::BOTH` when the rel-base pin moved up to join the
bound's, separated only by a comment. One loop; the pin goes first because
the bound block `continue`s on a share.
- **A twelve-line comment left describing the wrong line.** The new
one-liner about combining the ask's holds was inserted between the comment
about holding an answer to its bound and the code that comment is about.
- **Three things nothing reads.** `Declared::from_axes` lost its only caller
with `Widgets::declared_lens`; `Bounds::from_axes` and `SizeRule::declared`
never had one. `PlaceDesc::from_axes` is the only member of that family
anything calls, so nothing is left half-complete.
- **The shrinker printed a rule with derived `Debug`.** `describe`'s
hand-written printer was replaced by `format!("{r:?}")` and the comment
saying why it was hand-written deleted. Measured: one axis prints as
`SizeRule { request: Some(Linear(LayoutLen { px: 0, rel: 0, leftover: 1 })),
bound: Bound { min: None, max: Some(Len { rel: 0, px: 80 }) } }` -- 130
characters, twice per widget, in a line that joins every ancestor with
`" < "`. That is the one function whose stated job is output a tree can be
rebuilt from. It prints its parts again: `[x:1 leftover;<80 px;,y:-]`.
- **Five spellings of reading one environment variable.** `bounds_cost` wrote
three in one function (`var().unwrap_or_else`, `var().is_ok_and(== "1")`,
`var().ok().and_then(parse)`) where an identical `fn env<T: FromStr>`
already stood in `layout_dump.rs`, `layout_diagnostics.rs`,
`revision_cost.rs` and `scenario/mod.rs`. This is the class the tenth sweep
found one commit earlier and fixed one instance of. It is now one function
in `tests/rig/`, used by all six rigs, and a switch is `env(NAME, 0_u8) != 0`
everywhere.
- **A measurement rig verifying inside its measured loop.** `bounds_cost`
asserted 128 regions every frame, where `revision_cost` prints its geometry
once before the loop and asserts nothing inside it. Measured at `MODE=cap
FRAMES=2000`: 5.780B instructions with the per-frame assertions against
5.743B without, three runs each, stable to 0.005% -- 0.65%, which is far
less than it looked and still not layout. The check now runs once on each
side of the crossing before the loop, and the number is in the comment so
nobody re-adds it or deletes it for the wrong reason. Its module comment
also said it compares against "the former wrapper", which this tree no
longer contains, without saying the other side has to be run at an earlier
commit; and it documented `MODE` and `REDRAW` but not `FRAMES`, and gave no
invocation line where every neighbouring rig gives one.
- **The same fixture built by two tests, and a half-test that could no longer
decide anything.** `a_bound_holds_what_a_widget_answers` and
`a_cap_holds_an_answer_that_overflowed_its_box` both built a 250 window
holding two 200-wide rects in a row under a 300 cap; the first lost its doc
comment in `2ac0843` and the second kept one. They are one test, with the
corners assertion folded into the cap arm and a corrected explanation --
corrected because the old one said a bound "leaves the box alone", which is
no longer true in general and is true of this fixture only because 300 does
not bind a 250 box. Separately, the second half of
`a_cap_attribute_narrows_the_widgets_box` lost the assertion that
distinguished it when `MaxSize` went (the wrapper measuring 400 while its
child measured 300), leaving `rect().max_width(300)` at root in a 400
window -- which is the opening of
`a_cap_attribute_is_decided_again_on_either_side_of_the_crossing`, verbatim.
It is now `width(leftover(1)).max_width(300)`, the allocator's path, which
nothing covered at the root.
Two things the sweep **looked at and left**:
- **`SizeRule` now holds `Option<SizeRequest>` inline** where the enum held
`Request(Arc<SizeRequest>)`, so `at_least` and `at_most` clone the request
to edit a bound. Left because `SizeRequest` is `Linear(LayoutLen)` or an
`Arc` pair, so that clone is a discriminant copy or a refcount bump, never
a deep copy. `size_of::<SizeRule>()` is 40 bytes, which the rig prints.
- **`Widgets::set_len` writes the `SizeRule` literally** where `set_min_len`
and `set_max_len` go through `SizeRule::at_least`/`at_most`. A matching
builder was considered and rejected: the two bound helpers exist because a
bound is half of a pair that has to be preserved, and a request has no
other half to preserve -- a method would be a name in front of one field
assignment.
Verified at `ea1f836`: format, workspace clippy under `-D warnings` with and
without `layout-diagnostics`, 206 ordinary and 210 diagnostic tests (207 and
211 before, less the merged test), 400 depth-5 trees warm against cold in
64.19s, and the cold dump byte-identical to `2ac0843` across all **34,986**
boxes. The scan was run because the `size_hint` restructure touches what a
container records as a dependency; the dump because nothing here was meant to
move a box.
## Tenth sweep: the deferred request system (2026-09-20)
Over the part of #19 no earlier round reviewed -- `76aaf06` and `de1eb7e`