Skip to content

It's not possible to return Vec<T> if T only implements IntoWasmAbi #3824

@bes

Description

@bes

Describe the Bug

It is not possible to return Vec<T: IntoWasmAbi>, but it is allowed to return just T.

Steps to Reproduce

Given this code

use serde::{Deserialize, Serialize};
use tsify::Tsify;
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen(js_name = TestClass)]
pub struct TestClass;

#[wasm_bindgen(js_class = TestClass)]
impl TestClass {
    #[wasm_bindgen]
    pub fn get_dummy_vec(&self) -> Vec<Dummy> {
        vec![Dummy {
            data: "abc".to_string(),
        }]
    }
}

#[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Dummy {
    data: String,
}
error[E0277]: the trait bound `Dummy: JsObject` is not satisfied
   --> src/test_bindgen.rs:8:1
    |
8   | #[wasm_bindgen(js_class = TestClass)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `JsObject` is not implemented for `Dummy`
    |
    = help: the following other types implement trait `JsObject`:
              Array
              ArrayBuffer
            and 71 others
    = note: required for `Dummy` to implement `WasmDescribeVector`
    = note: required for `Box<[Dummy]>` to implement `wasm_bindgen::describe::WasmDescribe`
    = note: 1 redundant requirement hidden
    = note: required for `Vec<Dummy>` to implement `wasm_bindgen::describe::WasmDescribe`
note: required by a bound in `ReturnWasmAbi`
   --> /Users/bes/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-bindgen-0.2.90/src/convert/traits.rs:177:26
    |
177 | pub trait ReturnWasmAbi: WasmDescribe {
    |                          ^^^^^^^^^^^^ required by this bound in `ReturnWasmAbi`
    = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` (in Nightly builds, run with -Z macro-backtrace for more info)

But, if we wrap the Vec in something that itself implements IntoWasmAbi everything works:

use serde::{Deserialize, Serialize};
use tsify::Tsify;
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen(js_name = TestClass)]
pub struct TestClass;

#[wasm_bindgen(js_class = TestClass)]
impl TestClass {
    // #[wasm_bindgen]
    // pub fn get_dummy_vec(&self) -> Vec<Dummy> {
    //     vec![Dummy {
    //         data: "abc".to_string(),
    //     }]
    // }
    //
    #[wasm_bindgen]
    pub fn get_dummy_collection(&self) -> DummyCollection {
        let dummies = vec![Dummy {
            data: "abc".to_string(),
        }];
        DummyCollection(dummies)
    }
}

#[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Dummy {
    data: String,
}

#[derive(Tsify, Serialize, Deserialize)]
#[tsify(from_wasm_abi, into_wasm_abi)]
pub struct DummyCollection(Vec<Dummy>);

Expected Behavior

I expect it to be possible to return Vec<T> where T: IntoWasmAbi.

Actual Behavior

It isn't possible to return Vec<T> where T: IntoWasmAbi, but it is perfectly possible to return the Vec when a wrapper type is added.

Additional Context

See also

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions