Skip to content

feat(rust): async-spawn - build under no_std + alloc#1600

Merged
alexcrichton merged 3 commits into
bytecodealliance:mainfrom
mattwilkinsonn:nostd-async-spawn
Apr 20, 2026
Merged

feat(rust): async-spawn - build under no_std + alloc#1600
alexcrichton merged 3 commits into
bytecodealliance:mainfrom
mattwilkinsonn:nostd-async-spawn

Conversation

@mattwilkinsonn

@mattwilkinsonn mattwilkinsonn commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #1599.

Follow-up to #1591, which made the async feature work under no_std. That PR left std on the async-spawn feature, but nothing in src/rt/async_support/spawn.rs actually requires std — it's Box, Vec, Future, Context, Poll, and FuturesUnordered / StreamExt from the futures crate. All of these are available through core / alloc once futures opts out of its default std feature.

This PR is the mechanical swap: std::*alloc::* / core::*, drop std from the feature definition, and add default-features = false, features = ["alloc"] to the futures dep.

Changes

Five edits across three files:

  • crates/guest-rust/Cargo.toml:
    • async-spawn = ['async', 'dep:futures', 'std']async-spawn = ['async', 'dep:futures']
    • futures = { version = "0.3.30", optional = true }futures = { version = "0.3.30", optional = true, default-features = false, features = ["alloc"] }
  • crates/guest-rust/src/rt/async_support/spawn.rs:
    • use std::{boxed, future, task, vec}; swapped for use alloc::{boxed, vec}; + use core::{future, task};
  • .github/workflows/main.yml:
    • rustup target add wasm32v1-none in the check job setup
    • Two cargo build --target wasm32v1-none -p wit-bindgen --no-default-features --features {async,async-spawn} lines so a regression that pulls std back in fails CI instead of silently relinking against wasm32-wasip1's std.

wasm32v1-none (Tier 2, stable) is used for the guard because it has no std at all, unlike wasm32-unknown-unknown which happily links std even when you opt out via features.

Verification

Default-features build is unchanged. The async-spawn feature also builds without std:

$ cargo check -p wit-bindgen --no-default-features --features "realloc,async,async-spawn,bitflags,macros"
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.70s

The new CI guards are correct — on main (before this PR) the wasm32v1-none line fails to link because futures-executor pulls in std:

$ cargo build --target wasm32v1-none -p wit-bindgen --no-default-features --features async-spawn
error[E0463]: can't find crate for `std`
   --> memchr-2.8.0/src/lib.rs:198:1
    |
198 | extern crate std;
    | ^^^^^^^^^^^^^^^^^ can't find crate

With the patch applied, it compiles clean.

Downstream verification: my WIP project (not public yet) carries this exact patch on top of 0.55.0 and builds its agent as a fully no_std component on wasm32-wasip3 with -Zbuild-std=core,alloc.

@alexcrichton alexcrichton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@alexcrichton alexcrichton added this pull request to the merge queue Apr 20, 2026
Merged via the queue into bytecodealliance:main with commit 1e3af2d Apr 20, 2026
29 checks passed
@mattwilkinsonn mattwilkinsonn deleted the nostd-async-spawn branch April 21, 2026 21:13
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.

Feature request: Make async-spawn feature no_std + alloc compatible

2 participants