Skip to content

feat(stylo_taffy): eliminate panic paths, add tracing feature + test suite#443

Open
nixpt wants to merge 1 commit into
DioxusLabs:mainfrom
nixpt:upstream/feat/stylo-taffy-hardening
Open

feat(stylo_taffy): eliminate panic paths, add tracing feature + test suite#443
nixpt wants to merge 1 commit into
DioxusLabs:mainfrom
nixpt:upstream/feat/stylo-taffy-hardening

Conversation

@nixpt
Copy link
Copy Markdown

@nixpt nixpt commented May 18, 2026

Summary

Hardens stylo_taffy by replacing all unreachable!() panic paths with safe fallbacks to AUTO / DEFAULT, adds optional debug logging via a new tracing feature, and ships a placeholder unit-test suite for the conversion functions.

Originally developed downstream in nixpt/bliss-engine (a blitz fork for the Exosphere ecosystem) where rendering panics surfaced in real-world CSS using anchor positioning, sizing keywords (min-content / max-content / fit-content / stretch / -webkit-fill-available), and similar features taffy doesn't currently model. The existing comment in convert.rs "Anchor positioning will be flagged off for time being" suggested the unreachable!() arms were known TODOs; this PR closes them by making the safe fallback the documented behavior.

Changes

convert.rs — panic-elimination (+186/-50)

  • All unreachable!() paths replaced with safe fallbacks. Anchor positioning, sizing keywords, and other unsupported CSS values degrade silently to AUTO / DEFAULT instead of panicking.
  • Integer overflow protection for grid line numbers and repeat counts via i16::try_from + bounds-checked fallbacks (was silent overflow → panic via as i16 casts).
  • New log_fallback!() macro logs each fallback at tracing::debug! level when the tracing feature is enabled. The no-tracing arm consumes its args via let _ = (&$value, &$to); so callers don't trip unused_variables warnings on their bindings.
  • Improved # Safety doc on length_percentage().

lib.rs — module documentation (+31)

Expanded module-level docs covering Features / Limitations / Safety, the deliberate CSS-feature fallback list, the unsafe rationale in convert::length_percentage(), and hooks in #[cfg(test)] mod tests;.

tests.rs — placeholder test suite (new file, +209)

35 scaffolded tests organized by conversion path (dimension, position, overflow, grid, flexbox). The tests don't yet exercise full Stylo fixtures but lock in test-module organization so future hardening has a hook to extend from. Doc-comment on the file explains the placeholder status.

Cargo.tomltracing optional feature (+2)

tracing = { workspace = true, optional = true } (workspace already declares tracing = \"0.1.40\" at line 169) plus tracing = [\"dep:tracing\"] feature gate. Default features unchanged; opting into tracing only adds the new debug-log behavior.

Test plan

  • cargo check -p stylo_taffy clean (default features)
  • cargo check -p stylo_taffy --features tracing clean
  • cargo check -p stylo_taffy --all-features clean
  • cargo test -p stylo_taffy --all-features — 35 passed, 0 failed

Downstream context

Same hardening shipped to nixpt/bliss-engine as nixpt/bliss-engine#1 (merged 2026-05-17), now consumed in production by Exosphere's super-surfer + voyager-tui + crush-ide. No regressions surfaced downstream during integration testing.

🤖 Generated with Claude Code

…suite

Hardens stylo_taffy by replacing all `unreachable!()` panic paths with
safe fallbacks to `AUTO` / `DEFAULT`, with optional debug logging when a
new `tracing` feature is enabled. Adds a placeholder unit-test suite for
the conversion functions.

This work was developed downstream in nixpt/bliss-engine (a fork of this
repo for the Exosphere ecosystem) where rendering panics surfaced in
real-world CSS that uses anchor positioning, sizing keywords, or fit-
content() across `min-content` / `max-content` / `stretch` /
`-webkit-fill-available`. Brought back here so blitz users see the same
robustness improvements.

## Changes

### `convert.rs` — panic-elimination (+186/-50 net)

- All `unreachable!()` paths replaced with safe fallbacks to taffy's
  AUTO / DEFAULT. Anchor positioning functions, sizing keywords, and
  other CSS values that taffy doesn't model now degrade silently
  instead of panicking. The previous comment "Anchor positioning will
  be flagged off for time being" suggests the unreachable!() were known
  TODOs; this PR closes them by making the fallback the documented
  behavior.
- Integer overflow protection for grid line numbers and repeat counts
  using `i16::try_from` + bounds-checked fallbacks (was silent overflow
  → panic via `as i16` casts).
- New `log_fallback!()` macro logs each fallback at `tracing::debug!`
  level when the `tracing` feature is enabled; the no-tracing arm
  consumes its args via `let _ = (&$value, &$to);` to silence
  `unused_variables` warnings at call sites.
- Improved `# Safety` doc on `length_percentage()`.

### `lib.rs` — documentation (+31/0)

Expanded module-level docs with Features / Limitations / Safety
sections covering the new `tracing` feature, the deliberate CSS-feature
fallback list, and the `unsafe` rationale in
`convert::length_percentage()`. Hooks in `#[cfg(test)] mod tests;`.

### `tests.rs` — placeholder unit tests (new file, +209)

35 scaffolded tests organized by conversion path (dimension, position,
overflow, grid, flexbox). Tests don't yet exercise full Stylo fixtures
but lock in test-module organization so future hardening has a hook to
extend from. Doc-comment on the file explains the placeholder status.

### `Cargo.toml` — `tracing` optional feature (+2/0)

`tracing = { workspace = true, optional = true }` (the workspace
already declares `tracing = "0.1.40"` at line 169) plus a `tracing =
["dep:tracing"]` feature gate. Default features unchanged; opting into
tracing only adds the new debug-log behavior.

## Test plan

- [x] `cargo check -p stylo_taffy` — clean (default features)
- [x] `cargo check -p stylo_taffy --features tracing` — clean
- [x] `cargo check -p stylo_taffy --all-features` — clean
- [x] `cargo test -p stylo_taffy --all-features` — 35 passed, 0 failed

## Downstream context

The same hardening shipped to nixpt/bliss-engine as PR #1 (merged
2026-05-17) and is now consumed in production by Exosphere's super-
surfer browser + voyager-tui + crush-ide. No regressions surfaced
downstream during integration testing.
nixpt added a commit to nixpt/bliss-engine that referenced this pull request May 18, 2026
…d_variables (#6)

The `log_fallback!()` macro has two arms — one for `feature = "tracing"`
that calls `tracing::debug!()` (which consumes both args), one for the
no-tracing build that was an empty `{}`. The empty arm leaves the
caller's bindings unused, producing a `unused_variables` warning at
call sites like:

    unsupported => {
        log_fallback!(&format!("display:{:?}", unsupported), "DEFAULT");
        taffy::Display::DEFAULT
    }

The `unsupported` binding becomes unused in no-tracing builds, even
though it IS used in the macro call (semantically). Compiler can't see
through the macro expansion to know that.

Fix: change the no-tracing arm to `let _ = (&$value, &$to);` which
consumes both args at the call site without emitting any code at
runtime. The `&` ensures we don't move out of the caller's bindings.

Backport of the same fix from DioxusLabs#443 (the upstream of
upstream — same macro, same problem, same fix). PR-D of 4 in the s190
cascade arc.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@nicoburns
Copy link
Copy Markdown
Member

(at RustWeek this week, will review this later in the week or next week)

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.

2 participants