From d6fa2a5617f81b76cdd29793377eb1bf28e0033f Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 8 Sep 2026 12:42:27 -0700 Subject: [PATCH] chore(deps): pull portable-atomic only where it is reachable A firmware was fetching and compiling `portable-atomic` and then discarding it at link time. Its only use site is gated `all(not(target_has_atomic = "64"), feature = "std")` -- a `no_std` build uses `options::split64` instead -- but the dependency was declared for the target regardless of the feature. It is now `optional` and enabled by `std`, so it appears exactly where it is used. Verified on three shapes: riscv32imac WITH std 1 in the graph (the case that needs it) riscv32imac no_std 0 (was 1, and 20 build artifacts) x86_64 windows 0 (target section never matches) Costs nothing on the device either way -- after `split64` landed, its symbols in a shipped ESP32 image went to zero and its 4,288-byte `LOCKS` table left the symbol map -- so this buys an accurate dependency graph rather than bytes. An unused crate still shows up in an SBOM, a `cargo audit`, and every dependency count a firmware reviewer looks at. No version bump here: this rides with the next release rather than spending a 2.0.1 on tidiness. Gates: 109/33 default, 90/19 small profile, clippy on three configs, both RISC-V targets at both geometries, rusty_alloc-api no_std, wasm32, unsafe census, gate selftest 5/5, wasm size ratchet. Downstream corpus unchanged -- spacedb-sdk (plain and secure), rusty_alloc_default and rusty_zstd all green; rusty_maplibre still on its documented `features = ["std"]` migration. Co-Authored-By: Claude Opus 5 (1M context) --- crates/rusty_alloc/Cargo.toml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/rusty_alloc/Cargo.toml b/crates/rusty_alloc/Cargo.toml index 7106eba..b5c3ee0 100644 --- a/crates/rusty_alloc/Cargo.toml +++ b/crates/rusty_alloc/Cargo.toml @@ -24,8 +24,17 @@ readme = "README.md" # mimalloc's `mi_deferred_free_fun`. Narrowing either breaks a contract, and # hand-rolling a 64-bit atomic out of two 32-bit halves inside an allocator is # exactly the kind of thing that produces a subtle bug. +# +# `optional`, and enabled by `std` rather than by the target alone. The use site +# is gated `all(not(target_has_atomic = "64"), feature = "std")` -- a `no_std` +# build uses `options::split64` instead -- so a firmware was fetching and +# compiling a crate it then discarded at link time. Zero bytes on the device +# either way (verified: after `split64` landed, `portable_atomic` symbols in a +# shipped ESP32 image went to zero and its 4,288-byte `LOCKS` table left the +# symbol map), but an unused crate still shows up in an SBOM, a `cargo audit` +# and every dependency count a firmware reviewer looks at. [target.'cfg(not(target_has_atomic = "64"))'.dependencies] -portable-atomic = { version = "1", default-features = false, features = ["fallback"] } +portable-atomic = { version = "1", default-features = false, features = ["fallback"], optional = true } [features] # `std` is DEFAULT and additive — unlike the geometry `--cfg` (P2), which is @@ -35,7 +44,12 @@ portable-atomic = { version = "1", default-features = false, features = ["fallba # single-heap profile: no `thread_local!`, no environment, no `process::abort` # (see `lib.rs`). P3 of docs/plans/small-metal.md. default = ["std"] -std = [] +# Pulls `portable-atomic` ONLY where it is actually reachable: a target without +# 64-bit atomics that also has `std`. On every other target the dependency is +# not in the graph at all -- the `dep:` reference resolves against a +# target-gated declaration, so it simply does not apply where the target section +# does not match. +std = ["dep:portable-atomic"] # Full invariant checking: list walks, canaries, double-free detection (our `dmi`). debug_checks = [] # Feature-gated rdtsc path profiler (§7.5 of the plan). OFF = byte-identical build.