Repository navigation
wit-bindgen generates invalid Rust on async + sized list #1728
Description
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