tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros
1# taffy#1000 — `distribute_space_up_to_limits` olvida lo que ya repartió
2#
3# CAUSA RAÍZ, encontrada instrumentando taffy 0.12.2 (2026-07-28). La función
4# reparte espacio libre entre pistas «hasta su límite», en varias iteraciones,
5# acumulando en `track.item_incurred_increase`. Las DOS cuentas que deciden
6# cuánto le cabe a cada pista miran `track_affected_property(track)` PELADO, sin
7# sumarle lo ya acumulado:
8#
9# · el margen restante (`min_increase_limit`), que queda inflado en todo lo
10# que la pista ya creció en iteraciones anteriores; y
11# · el guarda que aplica el incremento, que por lo mismo deja pasar pistas ya
12# CONGELADAS por el filtro de elegibilidad de arriba.
13#
14# Traza del caso real (infobox «Rust Foundation» de Wikipedia, contenedor 352,
15# bases [87, 140], límites [147, 197], libre 125):
16# iter 1: cabe min(60, 57) = 57 → ambas +57 → [144, 197], sobran 11.
17# iter 2: elegible sólo la 1ª (la 2ª topó), pero el margen se calcula
18# 147 − 87 = 60 (debería ser 3) y el guarda compara 87 + 11 ≤ 147
19# (debería ser 144 + 11) → **las DOS** se llevan +11.
20# salida [155, 208] = 363 en un contenedor de 352, con límites que sumaban
21# 344 y entraban de sobra.
22#
23# Explica las dos caras que veníamos midiendo (ver
24# `tests/grid_maximise_overshoot.rs`): la pista que supera su propio
25# max-content, y el reparto que empeora al SACAR filas.
26#
27# VERIFICADO contra el repo de taffy en el tag v0.12.2: la suite entera pasa —
28# 4421 tests generados (los de web-platform), 105 unitarios, 43 hand-written,
29# 5 de doc; cero fallas. Y arregla los dos casos: el original de taffy#1000
30# (contenedor 928, max-contents [400, 674]) pasa de [528, 528] = 1056 a
31# [400, 528] = 928 EXACTO, y el infobox de 2 filas de 363 a 344.
32#
33# Sigue VIVO en master (0972b84, posterior a 0.12.2).
34#
35# Para aplicarlo hace falta un taffy vendorizado + `[patch.crates-io]`; mientras
36# eso no se decida, esto es la evidencia y la receta, no un parche activo.
37#
38diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
39index 10e3ea2..9d8ad07 100644
40--- a/src/compute/grid/track_sizing.rs
41+++ b/src/compute/grid/track_sizing.rs
42@@ -1399,7 +1399,10 @@ fn distribute_space_up_to_limits(
43 .iter()
44 .filter(|track| track_affected_property(track) + track.item_incurred_increase < track_limit(track))
45 .filter(|track| track_is_affected(track))
46- .map(|track| (track_limit(track) - track_affected_property(track)) / track_distribution_proportion(track))
47+ .map(|track| {
48+ (track_limit(track) - track_affected_property(track) - track.item_incurred_increase)
49+ / track_distribution_proportion(track)
50+ })
51 .min_by(|a, b| a.total_cmp(b))
52 .unwrap(); // We will never pass an empty track list to this function
53 let iteration_item_incurred_increase =
54@@ -1407,7 +1410,10 @@ fn distribute_space_up_to_limits(
55
56 for track in tracks.iter_mut().filter(|track| track_is_affected(track)) {
57 let increase = iteration_item_incurred_increase * track_distribution_proportion(track);
58- if increase > 0.0 && track_affected_property(track) + increase <= track_limit(track) + THRESHOLD {
59+ if increase > 0.0
60+ && track_affected_property(track) + track.item_incurred_increase + increase
61+ <= track_limit(track) + THRESHOLD
62+ {
63 track.item_incurred_increase += increase;
64 space_to_distribute -= increase;
65 }