Add support for #[wasm_bindgen] on async fn (#1754)

This commit adds support to attach `#[wasm_bindgen]` on an `async fn`
which will change the return value into a `Promise` in JS. This in
theory has the exact same semantics as an `async` function in JS where
you call it with all the arguments, nothing happens and you get a
promise back, and then later the promise actually resolves.

This commit also adds a helper trait, `IntoJsResult`, to allow `async`
functions with multiple kinds of return values instead of requiring
everything to be `Result<JsValue, JsValue>`.
This commit is contained in:
Alex Crichton
2019-09-06 13:47:16 -05:00
committed by GitHub
parent 7fd6702c6d
commit 88618116ac
10 changed files with 236 additions and 18 deletions

View File

@ -0,0 +1,39 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct MyType;
#[wasm_bindgen]
pub async fn good1() { loop {} }
#[wasm_bindgen]
pub async fn good2() -> JsValue { loop {} }
#[wasm_bindgen]
pub async fn good3() -> u32 { loop {} }
#[wasm_bindgen]
pub async fn good4() -> MyType { loop {} }
#[wasm_bindgen]
pub async fn good5() -> Result<(), JsValue> { loop {} }
#[wasm_bindgen]
pub async fn good6() -> Result<JsValue, JsValue> { loop {} }
#[wasm_bindgen]
pub async fn good7() -> Result<u32, JsValue> { loop {} }
#[wasm_bindgen]
pub async fn good8() -> Result<MyType, JsValue> { loop {} }
#[wasm_bindgen]
pub async fn good9() -> Result<MyType, u32> { loop {} }
#[wasm_bindgen]
pub async fn good10() -> Result<MyType, MyType> { loop {} }
pub struct BadType;
#[wasm_bindgen]
pub async fn bad1() -> Result<(), ()> { loop {} }
#[wasm_bindgen]
pub async fn bad2() -> Result<(), BadType> { loop {} }
#[wasm_bindgen]
pub async fn bad3() -> BadType { loop {} }
#[wasm_bindgen]
pub async fn bad4() -> Result<BadType, JsValue> { loop {} }
fn main() {}

View File

@ -0,0 +1,50 @@
error[E0277]: the trait bound `std::result::Result<(), ()>: wasm_bindgen::__rt::IntoJsResult` is not satisfied
--> $DIR/async-errors.rs:29:1
|
29 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `wasm_bindgen::__rt::IntoJsResult` is not implemented for `std::result::Result<(), ()>`
|
= help: the following implementations were found:
<std::result::Result<(), E> as wasm_bindgen::__rt::IntoJsResult>
<std::result::Result<T, E> as wasm_bindgen::__rt::IntoJsResult>
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
error[E0277]: the trait bound `std::result::Result<(), BadType>: wasm_bindgen::__rt::IntoJsResult` is not satisfied
--> $DIR/async-errors.rs:31:1
|
31 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `wasm_bindgen::__rt::IntoJsResult` is not implemented for `std::result::Result<(), BadType>`
|
= help: the following implementations were found:
<std::result::Result<(), E> as wasm_bindgen::__rt::IntoJsResult>
<std::result::Result<T, E> as wasm_bindgen::__rt::IntoJsResult>
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
error[E0277]: the trait bound `wasm_bindgen::JsValue: std::convert::From<BadType>` is not satisfied
--> $DIR/async-errors.rs:33:1
|
33 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `std::convert::From<BadType>` is not implemented for `wasm_bindgen::JsValue`
|
= help: the following implementations were found:
<wasm_bindgen::JsValue as std::convert::From<&'a T>>
<wasm_bindgen::JsValue as std::convert::From<&'a std::string::String>>
<wasm_bindgen::JsValue as std::convert::From<&'a str>>
<wasm_bindgen::JsValue as std::convert::From<MyType>>
and 62 others
= note: required because of the requirements on the impl of `std::convert::Into<wasm_bindgen::JsValue>` for `BadType`
= note: required because of the requirements on the impl of `wasm_bindgen::__rt::IntoJsResult` for `BadType`
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
error[E0277]: the trait bound `std::result::Result<BadType, wasm_bindgen::JsValue>: wasm_bindgen::__rt::IntoJsResult` is not satisfied
--> $DIR/async-errors.rs:35:1
|
35 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `wasm_bindgen::__rt::IntoJsResult` is not implemented for `std::result::Result<BadType, wasm_bindgen::JsValue>`
|
= help: the following implementations were found:
<std::result::Result<(), E> as wasm_bindgen::__rt::IntoJsResult>
<std::result::Result<T, E> as wasm_bindgen::__rt::IntoJsResult>
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
For more information about this error, try `rustc --explain E0277`.