mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-14 12:02:23 +03:00
Fix codegen for descriptors of async fn returns (#1782)
They erroneously reported returning the original return type, not the promise! Let's also add a bunch of positive tests while we're at it. Closes #1781
This commit is contained in:
parent
8ba0142dd2
commit
9c330529f2
@ -44,6 +44,7 @@ cfg-if = "0.1.9"
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
js-sys = { path = 'crates/js-sys', version = '0.3.27' }
|
||||
wasm-bindgen-test = { path = 'crates/test', version = '=0.3.0' }
|
||||
wasm-bindgen-futures = { path = 'crates/futures', version = '=0.4.0' }
|
||||
serde_derive = "1.0"
|
||||
wasm-bindgen-test-crate-a = { path = 'tests/crates/a', version = '0.1' }
|
||||
wasm-bindgen-test-crate-b = { path = 'tests/crates/b', version = '0.1' }
|
||||
|
@ -446,36 +446,31 @@ impl TryToTokens for ast::Export {
|
||||
// For an `async` function we always run it through `future_to_promise`
|
||||
// since we're returning a promise to JS, and this will implicitly
|
||||
// require that the function returns a `Future<Output = Result<...>>`
|
||||
let (ret_expr, projection) = if self.function.r#async {
|
||||
let (ret_ty, ret_expr) = if self.function.r#async {
|
||||
(
|
||||
quote! { wasm_bindgen::JsValue },
|
||||
quote! {
|
||||
wasm_bindgen_futures::future_to_promise(async {
|
||||
wasm_bindgen::__rt::IntoJsResult::into_js_result(#ret.await)
|
||||
}).into()
|
||||
},
|
||||
quote! {
|
||||
<wasm_bindgen::JsValue as wasm_bindgen::convert::ReturnWasmAbi>
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote! { #syn_ret },
|
||||
quote! { #ret },
|
||||
quote! {
|
||||
<#syn_ret as wasm_bindgen::convert::ReturnWasmAbi>
|
||||
},
|
||||
)
|
||||
};
|
||||
let projection = quote! { <#ret_ty as wasm_bindgen::convert::ReturnWasmAbi> };
|
||||
let convert_ret = quote! { #projection::return_abi(#ret_expr) };
|
||||
let describe_ret = quote! {
|
||||
<#syn_ret as WasmDescribe>::describe();
|
||||
<#ret_ty as WasmDescribe>::describe();
|
||||
};
|
||||
let nargs = self.function.arguments.len() as u32;
|
||||
let attrs = &self.function.rust_attrs;
|
||||
|
||||
let start_check = if self.start {
|
||||
quote! {
|
||||
const _ASSERT: fn() = || -> #projection::Abi { loop {} };
|
||||
}
|
||||
quote! { const _ASSERT: fn() = || -> #projection::Abi { loop {} }; }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
16
tests/wasm/futures.js
Normal file
16
tests/wasm/futures.js
Normal file
@ -0,0 +1,16 @@
|
||||
const assert = require('assert');
|
||||
const wasm = require('wasm-bindgen-test');
|
||||
|
||||
exports.call_exports = async function() {
|
||||
await wasm.async_do_nothing();
|
||||
assert.strictEqual(1, await wasm.async_return_1());
|
||||
assert.strictEqual(2, await wasm.async_return_2());
|
||||
await wasm.async_nothing_again();
|
||||
assert.strictEqual(3, await wasm.async_return_3());
|
||||
assert.strictEqual(4, await wasm.async_return_4());
|
||||
assert.strictEqual(5, (await wasm.async_return_5()).val);
|
||||
assert.strictEqual(6, (await wasm.async_return_6()).val);
|
||||
assert.strictEqual(7, (await wasm.async_return_7()).val);
|
||||
assert.strictEqual(8, (await wasm.async_return_8()).val);
|
||||
await assert.rejects(wasm.async_throw(), /async message/);
|
||||
};
|
70
tests/wasm/futures.rs
Normal file
70
tests/wasm/futures.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/futures.js")]
|
||||
extern "C" {
|
||||
fn call_exports() -> js_sys::Promise;
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn smoke() {
|
||||
wasm_bindgen_futures::JsFuture::from(call_exports()).await.unwrap();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_do_nothing() {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_1() -> JsValue {
|
||||
1.into()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_2() -> u32 {
|
||||
2
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_nothing_again() -> Result<(), JsValue> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_3() -> Result<u32, JsValue> {
|
||||
Ok(3)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_4() -> Result<JsValue, JsValue> {
|
||||
Ok(4.into())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct AsyncCustomReturn {
|
||||
pub val: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_5() -> AsyncCustomReturn {
|
||||
AsyncCustomReturn { val: 5 }
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_6() -> Result<AsyncCustomReturn, JsValue> {
|
||||
Ok(AsyncCustomReturn { val: 6 })
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_7() -> Result<AsyncCustomReturn, u32> {
|
||||
Ok(AsyncCustomReturn { val: 7 })
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_return_8() -> Result<AsyncCustomReturn, AsyncCustomReturn> {
|
||||
Ok(AsyncCustomReturn { val: 8 })
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn async_throw() -> Result<(), js_sys::Error> {
|
||||
Err(js_sys::Error::new("async message"))
|
||||
}
|
@ -23,6 +23,7 @@ pub mod duplicates;
|
||||
pub mod enums;
|
||||
#[path = "final.rs"]
|
||||
pub mod final_;
|
||||
pub mod futures;
|
||||
pub mod getters_and_setters;
|
||||
pub mod import_class;
|
||||
pub mod imports;
|
||||
|
Loading…
Reference in New Issue
Block a user