Skip to content

Commit 1c08e2b

Browse files
Pauanalexcrichton
authored andcommitted
Adding in async support for start (#1905)
* Adding in async support for start * Adding in another test case * Refactoring the Start trait to be cleaner
1 parent b71b136 commit 1c08e2b

File tree

4 files changed

+88
-6
lines changed

4 files changed

+88
-6
lines changed

crates/backend/src/codegen.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -447,17 +447,37 @@ impl TryToTokens for ast::Export {
447447
// since we're returning a promise to JS, and this will implicitly
448448
// require that the function returns a `Future<Output = Result<...>>`
449449
let (ret_ty, ret_expr) = if self.function.r#async {
450+
if self.start {
451+
(
452+
quote! { () },
453+
quote! {
454+
wasm_bindgen_futures::spawn_local(async move {
455+
<#syn_ret as wasm_bindgen::__rt::Start>::start(#ret.await);
456+
})
457+
},
458+
)
459+
460+
} else {
461+
(
462+
quote! { wasm_bindgen::JsValue },
463+
quote! {
464+
wasm_bindgen_futures::future_to_promise(async move {
465+
<#syn_ret as wasm_bindgen::__rt::IntoJsResult>::into_js_result(#ret.await)
466+
}).into()
467+
},
468+
)
469+
}
470+
471+
} else if self.start {
450472
(
451-
quote! { wasm_bindgen::JsValue },
452-
quote! {
453-
wasm_bindgen_futures::future_to_promise(async {
454-
wasm_bindgen::__rt::IntoJsResult::into_js_result(#ret.await)
455-
}).into()
456-
},
473+
quote! { () },
474+
quote! { <#syn_ret as wasm_bindgen::__rt::Start>::start(#ret) },
457475
)
476+
458477
} else {
459478
(quote! { #syn_ret }, quote! { #ret })
460479
};
480+
461481
let projection = quote! { <#ret_ty as wasm_bindgen::convert::ReturnWasmAbi> };
462482
let convert_ret = quote! { #projection::return_abi(#ret_expr) };
463483
let describe_ret = quote! {

crates/macro/ui-tests/start-function.rs

+21
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,25 @@ pub fn foo2(x: u32) {}
99
#[wasm_bindgen(start)]
1010
pub fn foo3<T>() {}
1111

12+
#[wasm_bindgen(start)]
13+
pub fn foo4() -> Result<(), JsValue> { Ok(()) }
14+
15+
#[wasm_bindgen(start)]
16+
pub fn foo5() -> Result<JsValue, ()> { Err(()) }
17+
18+
#[wasm_bindgen(start)]
19+
pub fn foo6() -> Result<JsValue, JsValue> { Ok(JsValue::from(1u32)) }
20+
21+
#[wasm_bindgen(start)]
22+
pub async fn foo_async1() {}
23+
24+
#[wasm_bindgen(start)]
25+
pub async fn foo_async2() -> Result<(), JsValue> { Ok(()) }
26+
27+
#[wasm_bindgen(start)]
28+
pub async fn foo_async3() -> Result<JsValue, ()> { Err(()) }
29+
30+
#[wasm_bindgen(start)]
31+
pub async fn foo_async4() -> Result<JsValue, JsValue> { Ok(JsValue::from(1u32)) }
32+
1233
fn main() {}

crates/macro/ui-tests/start-function.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,23 @@ error: the start function cannot have generics
99
|
1010
10 | pub fn foo3<T>() {}
1111
| ^^^
12+
13+
error[E0277]: the trait bound `std::result::Result<wasm_bindgen::JsValue, ()>: wasm_bindgen::__rt::Start` is not satisfied
14+
--> $DIR/start-function.rs:27:1
15+
|
16+
27 | #[wasm_bindgen(start)]
17+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `wasm_bindgen::__rt::Start` is not implemented for `std::result::Result<wasm_bindgen::JsValue, ()>`
18+
|
19+
= help: the following implementations were found:
20+
<std::result::Result<(), E> as wasm_bindgen::__rt::Start>
21+
= note: required by `wasm_bindgen::__rt::Start::start`
22+
23+
error[E0277]: the trait bound `std::result::Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>: wasm_bindgen::__rt::Start` is not satisfied
24+
--> $DIR/start-function.rs:30:1
25+
|
26+
30 | #[wasm_bindgen(start)]
27+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `wasm_bindgen::__rt::Start` is not implemented for `std::result::Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>`
28+
|
29+
= help: the following implementations were found:
30+
<std::result::Result<(), E> as wasm_bindgen::__rt::Start>
31+
= note: required by `wasm_bindgen::__rt::Start::start`

src/lib.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,27 @@ pub mod __rt {
11161116
}
11171117
}
11181118
}
1119+
1120+
1121+
/// An internal helper trait for usage in `#[wasm_bindgen(start)]`
1122+
/// functions to throw the error (if it is `Err`).
1123+
pub trait Start {
1124+
fn start(self);
1125+
}
1126+
1127+
impl Start for () {
1128+
#[inline]
1129+
fn start(self) {}
1130+
}
1131+
1132+
impl<E: Into<JsValue>> Start for Result<(), E> {
1133+
#[inline]
1134+
fn start(self) {
1135+
if let Err(e) = self {
1136+
crate::throw_val(e.into());
1137+
}
1138+
}
1139+
}
11191140
}
11201141

11211142
/// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`

0 commit comments

Comments
 (0)