From ecfcc7d407fff193af1a527a8ff8717ac5fefc1e Mon Sep 17 00:00:00 2001 From: meh Date: Mon, 7 Sep 2026 16:44:11 +0700 Subject: [PATCH 1/2] Stop the arctic backend from dragging std in, and check that it does not Enabling `arctic` enabled arctic's default features, which are `std` plus an SMR backend, so a crate that declares `#![no_std]` quietly linked one anyway. arctic 0.1.11 is the first release where this is fixable: before it, `smr-ps-reclaim` forced `std` on by itself. --features arctic arctic-wt [smr-ps-reclaim] ps-reclaim [libc,spin] --features arctic,std arctic-wt [smr-ps-reclaim,std] ps-reclaim [libc,spin,std] `congee` and `wti` now state `std` in the manifest, because neither crate is no_std upstream and pretending otherwise only moves the failure later. CI grows three steps in the existing job, no new runner: - the core and `hydrate` build for x86_64-unknown-none, which has no `std` to find, so the no_std claim is checked against a target rather than a host - the arctic graph is asserted to carry no `std` feature; the assertion was run against `--features arctic,std` first to prove it can fail The arctic backend itself cannot target bare metal: ps-reclaim stores its participant slot in thread-local storage and its no_std path is pthread keys, so it needs an OS. no_std here means no standard library, not no operating system, and that distinction is now written down instead of assumed. --- .github/workflows/ci.yml | 14 ++++++++++++++ Cargo.toml | 13 ++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75ed45d..31d00df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy + targets: x86_64-unknown-none - uses: Swatinem/rust-cache@v2 - run: cargo fmt --all -- --check - run: cargo clippy --all-targets --no-default-features -- -D warnings @@ -21,6 +22,19 @@ jobs: - run: cargo test --all-targets --features arctic - run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo test --all-targets --all-features + # A crate that says `#![no_std]` and is only ever built on a host with one + # proves nothing. This target has no `std` to find. + - run: cargo build --target x86_64-unknown-none --no-default-features + - run: cargo build --target x86_64-unknown-none --no-default-features --features hydrate + # The arctic backend needs an OS for its thread-local storage, so it + # cannot be built for a bare target - but it must still not pull `std` in. + - name: The arctic backend does not enable std + run: | + graph=$(cargo tree --no-default-features --features arctic -f '{p} [{f}]') + echo "$graph" | grep -E 'arctic-wt|ps-reclaim' + if echo "$graph" | grep -E '(arctic-wt|ps-reclaim) v[^[]*\[[^]]*std'; then + echo "std leaked into the arctic backend"; exit 1 + fi package: name: Release dry run diff --git a/Cargo.toml b/Cargo.toml index f09e8cb..1414307 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,12 +12,16 @@ categories = ["data-structures"] [features] default = [] +# On by default for nobody: this crate is `#![no_std]` and the core never needed +# `std`. The feature exists so a backend that does need one can say so, and so a +# bare-metal caller can prove it is not getting one. +std = ["arctic?/std"] # Load and unload rows as pages. Optional because it is the only thing here # that needs a serializer. hydrate = ["dep:rkyv", "dep:embedded-io"] arctic = ["dep:arctic"] -congee = ["dep:congee"] -wti = ["dep:wti"] +congee = ["dep:congee", "std"] +wti = ["dep:wti", "std"] [dependencies] rkyv = { version = "0.8.17", default-features = false, features = ["alloc", "bytecheck"], optional = true } @@ -26,7 +30,10 @@ rkyv = { version = "0.8.17", default-features = false, features = ["alloc", "byt # a caller with an OS gets real files and a caller without one plugs in whatever # it has. Nothing here needs `std` either way. embedded-io = { version = "0.7", default-features = false, features = ["alloc"], optional = true } -arctic = { package = "arctic-wt", version = "^0.1, >=0.1.9", optional = true } +# `default-features = false` and an explicit SMR backend, so enabling `arctic` +# does not silently enable `std`. 0.1.11 is the first release where that is +# possible: before it, `smr-ps-reclaim` forced `std` on. +arctic = { package = "arctic-wt", version = "^0.1, >=0.1.11", optional = true, default-features = false, features = ["smr-ps-reclaim"] } congee = { package = "congee-wt", version = "^0.4, >=0.4.4", optional = true } wti = { package = "WorkTablesIndex", version = "^0.0, >=0.0.11", optional = true, default-features = false, features = ["concurrent"] } From 29d6a0c86dbc2821a47878add5d1e6897c54286a Mon Sep 17 00:00:00 2001 From: meh Date: Mon, 7 Sep 2026 16:44:11 +0700 Subject: [PATCH 2/2] chore: 0.1.5 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1414307..74c088c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "worktable-vec" -version = "0.1.4" +version = "0.1.5" edition = "2024" rust-version = "1.85" license = "MIT OR Apache-2.0"