Stream: git-wasmtime

Topic: wasmtime / issue #11247 `wit-bindgen` async directives ar...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 15 2025 at 16:14):

rvolosatovs opened issue #11247:

Feature

For the most part, whether or not a function should be generated as async should be dictated by WIT (refs https://github.com/bytecodealliance/wasmtime/issues/11246), however wasmtime-wasi might require generating some bindings as async even if they are not marked as such in WIT. See https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/bindings.rs#L21-L62 for a full list of bindings generated as async in wasip3-prototyping. An example of a use case is e.g. wasi:sockets implementation, which relies on a (Rust) async socket address check hook https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/mod.rs#L52-L58 https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/host/types/tcp.rs#L220

We need a way to "inherit" async directives from the WIT, while being able to "mark" additional ones as async

Benefit

This will drastically cut down the amount of boilerplate required to generate bindings, since currently passing only_imports to async bindgen argument is the only way to choose imports to be async. Note, that at least with current implementation, users of bindgen relying on generated bindings using with, e.g. embedders extending wasmtime_wasi with additional bindings MUST inherit the complete only_imports list from bindings depended upon (e.g. https://github.com/rvolosatovs/wasmtime/blob/c822293b26a1f2720d5a4cd035a59a66d4512e90/crates/wasi/src/p3/bindings.rs#L36-L83), otherwise compilation fails with:

error[E0277]: the trait bound `D: HostConcurrent` is not satisfied
   --> crates/wasi/src/p3/bindings.rs:20:1
    |
8   | / wasmtime::component::bindgen!({
9   | |     inline: "
10  | |         package example:wasi;
...   |
29  | |     concurrent_imports: true,
30  | | });
    | |__^ unsatisfied trait bound
    |
    = help: the trait `wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent` is not implemented for `D`
note: required by a bound in `wasmtime_wasi::p3::bindings::sockets::types::add_to_linker`
   --> /Users/rvolosatovs/src/github.com/bytecodealliance/wasmtime/crates/wasi/src/p3/bindings.rs:73:5
    |
73  | /     wasmtime::component::bindgen!({
74  | |         path: "src/p3/wit",
75  | |         world: "wasi:cli/command",
...   |
125 | |         },
126 | |     });
    | |______^ required by this bound in `add_to_linker`
    = note: the full name for the type has been written to '/var/folders/bq/thy1_b7x29l7s2wqw39r62yw0000gn/T/rustdoctestObmR6k/rust_out.long-type-7090683266425947309.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `D` with trait `HostConcurrent`
    |
30  | }), D: wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent;
    |   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Implementation

The simplest approach that comes to mind is something like:

Alternatives

we could require bindgen macro users who need extensibility to only rely on only_imports as such, but that seems pretty tedious.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 15 2025 at 16:16):

rvolosatovs edited issue #11247:

Feature

For the most part, whether or not a function should be generated as async should be dictated by WIT (refs https://github.com/bytecodealliance/wasmtime/issues/11246), however wasmtime-wasi might require generating some bindings as async even if they are not marked as such in WIT. See https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/bindings.rs#L21-L62 for a full list of bindings generated as async in wasip3-prototyping. An example of a use case is e.g. wasi:sockets implementation, which relies on a (Rust) async socket address check hook https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/mod.rs#L52-L58 https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/host/types/tcp.rs#L220

We need a way to "inherit" async directives from the WIT, while being able to "mark" additional ones as async

Benefit

This will drastically cut down the amount of boilerplate required to generate bindings, since currently passing only_imports to async bindgen argument is the only way to choose imports to be async. Note, that at least with current implementation, users of bindgen relying on generated bindings using with, e.g. embedders extending wasmtime_wasi with additional bindings MUST inherit the complete only_imports list from bindings depended upon (e.g. https://github.com/rvolosatovs/wasmtime/blob/c822293b26a1f2720d5a4cd035a59a66d4512e90/crates/wasi/src/p3/bindings.rs#L36-L83), otherwise compilation fails with:

error[E0277]: the trait bound `D: HostConcurrent` is not satisfied
   --> crates/wasi/src/p3/bindings.rs:20:1
    |
8   | / wasmtime::component::bindgen!({
9   | |     inline: "
10  | |         package example:wasi;
...   |
29  | |     concurrent_imports: true,
30  | | });
    | |__^ unsatisfied trait bound
    |
    = help: the trait `wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent` is not implemented for `D`
note: required by a bound in `wasmtime_wasi::p3::bindings::sockets::types::add_to_linker`
   --> /Users/rvolosatovs/src/github.com/bytecodealliance/wasmtime/crates/wasi/src/p3/bindings.rs:73:5
    |
73  | /     wasmtime::component::bindgen!({
74  | |         path: "src/p3/wit",
75  | |         world: "wasi:cli/command",
...   |
125 | |         },
126 | |     });
    | |______^ required by this bound in `add_to_linker`
    = note: the full name for the type has been written to '/var/folders/bq/thy1_b7x29l7s2wqw39r62yw0000gn/T/rustdoctestObmR6k/rust_out.long-type-7090683266425947309.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `D` with trait `HostConcurrent`
    |
30  | }), D: wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent;
    |   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Implementation

The simplest approach that comes to mind is something like:

Alternatives

we could require bindgen macro users who need extensibility to only rely on only_imports and such, but that seems pretty tedious.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 15 2025 at 16:18):

rvolosatovs edited issue #11247:

Feature

For the most part, whether or not a function should be generated as async should be dictated by WIT (refs https://github.com/bytecodealliance/wasmtime/issues/11246), however wasmtime-wasi might require generating some bindings as async even if they are not marked as such in WIT. See https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/bindings.rs#L21-L62 for a full list of bindings generated as async in wasip3-prototyping. An example of a use case is e.g. wasi:sockets implementation, which relies on a (Rust) async socket address check hook https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/mod.rs#L52-L58 https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/host/types/tcp.rs#L220

We need a way to "inherit" async directives from the WIT, while being able to "mark" additional ones as async

Benefit

This will drastically cut down the amount of boilerplate required to generate bindings, since currently passing only_imports to async bindgen argument is the only way to choose imports to be async. Note, that at least with current implementation, users of bindgen relying on generated bindings using with, e.g. embedders extending wasmtime_wasi with additional bindings MUST inherit the complete only_imports list from bindings depended upon (e.g. https://github.com/rvolosatovs/wasmtime/blob/c822293b26a1f2720d5a4cd035a59a66d4512e90/crates/wasi/src/p3/bindings.rs#L36-L83), otherwise compilation fails with:

error[E0277]: the trait bound `D: HostConcurrent` is not satisfied
   --> crates/wasi/src/p3/bindings.rs:20:1
    |
8   | / wasmtime::component::bindgen!({
9   | |     inline: "
10  | |         package example:wasi;
...   |
29  | |     concurrent_imports: true,
30  | | });
    | |__^ unsatisfied trait bound
    |
    = help: the trait `wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent` is not implemented for `D`
note: required by a bound in `wasmtime_wasi::p3::bindings::sockets::types::add_to_linker`
   --> /Users/rvolosatovs/src/github.com/bytecodealliance/wasmtime/crates/wasi/src/p3/bindings.rs:73:5
    |
73  | /     wasmtime::component::bindgen!({
74  | |         path: "src/p3/wit",
75  | |         world: "wasi:cli/command",
...   |
125 | |         },
126 | |     });
    | |______^ required by this bound in `add_to_linker`
    = note: the full name for the type has been written to '/var/folders/bq/thy1_b7x29l7s2wqw39r62yw0000gn/T/rustdoctestObmR6k/rust_out.long-type-7090683266425947309.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `D` with trait `HostConcurrent`
    |
30  | }), D: wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent;
    |   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Implementation

The simplest approach that comes to mind is something like:

Alternatives

we could require bindgen macro users who need extensibility to only rely on only_imports and such, but that seems pretty tedious.

add_imports or something like that, which would be mutually exclusive with only_imports is another option, but IMO just imports would be the least surprising option

inherit_exports and inherit_imports split is also possible, but IMO for use cases so niche, users should simply not use the "inheritance" at all and just manually specify the function names

view this post on Zulip Wasmtime GitHub notifications bot (Jul 15 2025 at 22:06):

alexcrichton added the wasm-proposal:component-model-async label to Issue #11247.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 18 2025 at 20:11):

badeend commented on issue #11247:

In case it makes your life easier: all the problematic wasi-sockets IP address hooks can IMO be removed or refactored such that the WIT async-ness matches the generated bindings' async-ness:

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2025 at 13:39):

rvolosatovs commented on issue #11247:

Thanks for the analysis @badeend !
Another reason we need the "artificial" async right now is the fact that we can't actually create stream or future handles from within sync bindings

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2025 at 13:41):

rvolosatovs edited a comment on issue #11247:

Thanks for the analysis @badeend !
Another reason we need the "artificial" async right now is the fact that we can't actually create stream or future handles from within sync bindings, so that's what drives the need for async receive, for example

view this post on Zulip Wasmtime GitHub notifications bot (Jul 25 2025 at 19:24):

alexcrichton assigned alexcrichton to issue #11247.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2025 at 18:55):

alexcrichton closed issue #11247:

Feature

For the most part, whether or not a function should be generated as async should be dictated by WIT (refs https://github.com/bytecodealliance/wasmtime/issues/11246), however wasmtime-wasi might require generating some bindings as async even if they are not marked as such in WIT. See https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/bindings.rs#L21-L62 for a full list of bindings generated as async in wasip3-prototyping. An example of a use case is e.g. wasi:sockets implementation, which relies on a (Rust) async socket address check hook https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/mod.rs#L52-L58 https://github.com/bytecodealliance/wasip3-prototyping/blob/3ce9ccb3efd3d15dc3ff55e31d0b85869847cf3f/crates/wasi/src/p3/sockets/host/types/tcp.rs#L220

We need a way to "inherit" async directives from the WIT, while being able to "mark" additional ones as async

Benefit

This will drastically cut down the amount of boilerplate required to generate bindings, since currently passing only_imports to async bindgen argument is the only way to choose imports to be async. Note, that at least with current implementation, users of bindgen relying on generated bindings using with, e.g. embedders extending wasmtime_wasi with additional bindings MUST inherit the complete only_imports list from bindings depended upon (e.g. https://github.com/rvolosatovs/wasmtime/blob/c822293b26a1f2720d5a4cd035a59a66d4512e90/crates/wasi/src/p3/bindings.rs#L36-L83), otherwise compilation fails with:

error[E0277]: the trait bound `D: HostConcurrent` is not satisfied
   --> crates/wasi/src/p3/bindings.rs:20:1
    |
8   | / wasmtime::component::bindgen!({
9   | |     inline: "
10  | |         package example:wasi;
...   |
29  | |     concurrent_imports: true,
30  | | });
    | |__^ unsatisfied trait bound
    |
    = help: the trait `wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent` is not implemented for `D`
note: required by a bound in `wasmtime_wasi::p3::bindings::sockets::types::add_to_linker`
   --> /Users/rvolosatovs/src/github.com/bytecodealliance/wasmtime/crates/wasi/src/p3/bindings.rs:73:5
    |
73  | /     wasmtime::component::bindgen!({
74  | |         path: "src/p3/wit",
75  | |         world: "wasi:cli/command",
...   |
125 | |         },
126 | |     });
    | |______^ required by this bound in `add_to_linker`
    = note: the full name for the type has been written to '/var/folders/bq/thy1_b7x29l7s2wqw39r62yw0000gn/T/rustdoctestObmR6k/rust_out.long-type-7090683266425947309.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `D` with trait `HostConcurrent`
    |
30  | }), D: wasmtime_wasi::p3::bindings::sockets::types::HostConcurrent;
    |   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Implementation

The simplest approach that comes to mind is something like:

Alternatives

we could require bindgen macro users who need extensibility to only rely on only_imports and such, but that seems pretty tedious.

add_imports or something like that, which would be mutually exclusive with only_imports is another option, but IMO just imports would be the least surprising option

inherit_exports and inherit_imports split is also possible, but IMO for use cases so niche, users should simply not use the "inheritance" at all and just manually specify the function names


Last updated: Dec 06 2025 at 07:03 UTC