Skip to content

wit-bindgen generates invalid Rust on async + sized list #1728

Open

Description

@swankjesse

Hey folks! I’m a big fan of Wasm components and we’re building a new implementation in Kotlin called Brevity. There’s a lot to do! Wasm components is a big, capable system. I’m thankful to you all for all of the thorough documentation.

We’re using wit-bindgen as our reference implementation and writing lots of tests to confirm that we’re consistent. Today I ran into a case where wit-bindgen produced invalid Rust.

Here’s a little .wit declaration that uses async on a function that returns a sized list.

package brevity:testing;

world brevity-test {
  export async-return-value-sized-list-string: async func(
    index: s32,
  ) -> list<string, 2>;
}

Here’s some Rust that runs wit-bindgen on that function.

mod bindings {
    wit_bindgen::generate!({
        path: "./wit/async-sized-lists.wit",
    });

    use super::BrevityTesting;
    export!(BrevityTesting);
}

struct BrevityTesting;

impl bindings::Guest for BrevityTesting {
    async fn async_return_value_sized_list_string(
        index: i32
    ) -> [String; 2] {
        match index {
            0 => (["hello", "world"].map(String::from)).to_owned(),
            1 => (["", "abc\u{0000}def"].map(String::from)).to_owned(),
            2 => (["emoji", "🍩"].map(String::from)).to_owned(),
            _ => panic!("unexpected index {}", index)
        }
    }
}

The cargo.toml file is straightforward:

[package]
name = "brevity-testing-sizedLists"
version = "0.1.0"
edition = "2024"

[dependencies]
wit-bindgen = "0.62.0"
futures = "0.3.34"

[lib]
path = "src/async-sized-lists.rs"
crate-type = ['cdylib']

Expected

Program compiles!

Actual

wit-bindgen generated invalid Rust source. Removing async from both the .wit and the .rs file causes it to compile again.

$ cargo build --target=wasm32-wasip2 --release
    Updating crates.io index
     Locking 44 packages to latest Rust 1.95.0 compatible versions
   Compiling brevity-testing-sizedLists v0.1.0 (/Volumes/Development/brevity/brevity-integration-tests/build/BrevityExecutionTester/sizedLists/rust)
error[E0508]: cannot move out of type `[String; 2]`, a non-copy array
 --> src/async-sized-lists.rs:2:5
  |
2 | /     wit_bindgen::generate!({
3 | |         path: "./wit/async-sized-lists.wit",
4 | |     });
  | |      ^
  | |      |
  | |______cannot move out of here
  |        move occurs because value has type `String`, which does not implement the `Copy` trait
  |
  = note: this error originates in the macro `wit_bindgen::generate` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider borrowing here
  |
2 |     &wit_bindgen::generate!({
  |     +

For more information about this error, try `rustc --explain E0508`.
error: could not compile `brevity-testing-sizedLists` (lib) due to 1 previous error

Here’s the expanded Macro of the invalid code.

#[doc(hidden)]
#[allow(non_snake_case, unused_unsafe)]
pub unsafe fn _export_async_return_value_sized_list_string_cabi<T_: Guest>(arg0: i32 ) -> i32 {
    unsafe {
        #[cfg(target_arch = "wasm32")] _rt::run_ctors_once();
        wit_bindgen::rt::async_support::start_task(async move {
            let _task_cancel = wit_bindgen::rt::async_support::TaskCancelOnDrop::new();
            let result0 = &{ T_::async_return_value_sized_list_string(arg0).await };
            let vec1 = result0[0]; // ❌
            let ptr1 = vec1.as_ptr().cast::<u8>();
            let len1 = vec1.len();
            let vec2 = result0[1]; // ❌
            let ptr2 = vec2.as_ptr().cast::<u8>();
            let len2 = vec2.len();   #[cfg(target_arch = "wasm32")]
            #[link(wasm_import_module = "[export]$root")]
            unsafe extern "C" {
                #[link_name = "[task-return]async-return-value-sized-list-string"]
                fn wit_import3(_: *mut u8, _: usize, _: *mut u8, _: usize );
            }
            #[cfg(not(target_arch = "wasm32"))]
            unsafe extern "C" fn wit_import3(_: *mut u8, _: usize, _: *mut u8, _: usize ) { unreachable!() }
            _task_cancel.forget();
            wit_import3(ptr1.cast_mut(), len1, ptr2.cast_mut(), len2);
        })
    }
}

This isn’t blocking us. Thanks!

Activity

  1. added
    gen-rustRelated to bindings for Rust-compiled-to-WebAssembly
    asyncRelated to async/streams in the component model.
    on Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    asyncRelated to async/streams in the component model.gen-rustRelated to bindings for Rust-compiled-to-WebAssembly

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions