Files
lightcraft/xtask
0429844cd9 never-crash: deny the panic lints in every crate root; GPU asserts become fail paths (#2137) (#2170)
* never-crash: deny the panic lints in every crate root; GPU asserts become fail paths (#2137)

The never-crash policy was documented but not machine-checked for the two largest crates:
engine and meta carried only #![forbid(unsafe_code)], so a future unwrap/expect/panic would
pass cargo xtask ci. Both crate roots now also carry
as does xtask (previously un-annotated); the guarded expects in meta/src/xmp.rs and xtask's
parity.rs / root() now use the documented #[allow(clippy::expect_used)] + invariant form.

crates/gpu: the three production asserts become fail(FailKind::Fatal, ..) + return, so a
binding-count mismatch, an over-long readback, or a wrong-length curve fails the render over
to the CPU instead of crashing (finish_and_read also early-returns on len == 0, which would
have issued a zero-size copy_buffer_to_buffer that wgpu rejects).

xtask: new roots check (in ci) verifies every workspace lib root and every binary main.rs
carries both attributes; crates/sysmem is the documented exception for forbid(unsafe_code)
only. A panic in placement or readback is a fail, not a crash.

* audit fixes: roots covers binary and cdylib/rlib roots; render gates on failed() after finish_block (#2137)

Two reviewers audited the first commit; both highs it found are fixed here:

- roots scanner: the by_ref().any()/any() pair consumed the kind iterator hunting for
  "lib", so every bin-only root (both app mains, the sam3-worker bin, xtask itself) and the
  cdylib/rlib web root was silently unchecked — the check covered 29 of the 33 real roots.
  Kind detection now collects the kinds once and matches lib/rlib/dylib/cdylib/staticlib,
  with a root_paths regression test over bin, lib and cdylib/rlib targets; unreadable root
  files now fail with the I/O error instead of a fake policy violation.
- render.rs: the caller gates on failed() right after finish_block, so the malformed-curve
  fail path can no longer reach the band loop's p[y0_at] index on the empty block.
- finish_and_read: the len == 0 path now submits the encoder before returning zeros, so a
  failure staged in the same render stays detectable (the old zero-size copy failed loudly
  via the error scopes; a bare return would have hidden it).
- docs: finish_block and finish_and_read state their failure contracts; USAGE and AGENTS.md
  name the new roots step in the ci enumeration.

* xtask: check a library root at the source path that cargo metadata reports

The roots check read src/lib.rs for every library target, so a package that sets its library path was checked on the wrong file. Libraries now use the reported source path, with the same default as binaries when none is given.

* xtask: match the crate-root deny lints by whole name, ignoring a trailing comment

A lint named only in a trailing comment, or a lint whose name contains another (clippy::panic inside clippy::panic_in_result_fn), satisfied the deny check. Lint names are now compared whole and a trailing comment is ignored.

* xtask: read the crate-root attributes from the header, not a fixed 30 lines

The roots check read only the first 30 lines of each crate root, so a root whose attributes came after a longer doc header was reported as missing them. The check now reads the inner attributes at the top of the file: it skips blank lines and comments, reads each attribute whole, and stops at the first item. A multi-line list is read in full and a commented-out attribute does not count.

* xtask: reword two comments in the roots check

Comments only: the lint-name match and the source-path default are described without naming a lint or a build tool. No code changes.

* xtask: report a root attribute that overrides the required denies

* xtask: accept a runtime manifest dir only when it has a parent

* xtask: render the overridden deny attribute without literal braces

The write! escaped the braces around the substituted attribute and lint,
so the violation printed `#![{allow}({clippy::panic})]`; assert the
rendered message in the allow-override test.

* Tests: new test helpers meet the crate-root panic lints

Main added test helpers after this branch; the deny at the crate root now
applies to them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* roots: crates/wincolor is the second crate allowed unsafe

Main added it for the Windows colour APIs after this branch; its module docs
already say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 00:29:41 +01:00
..