Skip to content

Commit b7d7bbd

Browse files
committed
Relax async_runtime check on impl blocks
It used to error out if there were any non-async functions, now it only errors if there are no async functions in the impl block.
1 parent b18d6b7 commit b7d7bbd

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

fixtures/futures/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,23 @@ impl Megaphone {
171171
}
172172
}
173173

174+
// The async_runtime attribute used to error when *any* function in the impl block was not async,
175+
// now it should work as long as at least one function *is* async.
176+
#[uniffi::export(async_runtime = "tokio")]
177+
impl Megaphone {
178+
/// A sync method that yells something immediately.
179+
pub fn say_now(&self, who: String) -> String {
180+
format!("Hello, {who}!").to_uppercase()
181+
}
182+
183+
/// An async method that yells something after a certain time.
184+
///
185+
/// Uses tokio's timer functionality.
186+
pub async fn say_after_with_tokio(self: Arc<Self>, ms: u16, who: String) -> String {
187+
say_after_with_tokio(ms, who).await.to_uppercase()
188+
}
189+
}
190+
174191
// Say something after a certain amount of time, by using `tokio::time::sleep`
175192
// instead of our own `TimerFuture`.
176193
#[uniffi::export(async_runtime = "tokio")]

uniffi_macros/src/export.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ pub(crate) fn expand_export(
4242
match metadata {
4343
ExportItem::Function { sig } => gen_fn_scaffolding(sig, &args),
4444
ExportItem::Impl { items, self_ident } => {
45+
if let Some(rt) = &args.async_runtime {
46+
if items
47+
.iter()
48+
.all(|item| !matches!(item, ImplItem::Method(sig) if sig.is_async))
49+
{
50+
return Err(syn::Error::new_spanned(
51+
rt,
52+
"no async methods in this impl block",
53+
));
54+
}
55+
}
56+
4557
let item_tokens: TokenStream = items
4658
.into_iter()
4759
.map(|item| match item {

uniffi_macros/src/export/scaffolding.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ pub(super) fn gen_fn_scaffolding(
1919
"Unexpected self param (Note: uniffi::export must be used on the impl block, not its containing fn's)"
2020
));
2121
}
22+
if !sig.is_async {
23+
if let Some(async_runtime) = &arguments.async_runtime {
24+
return Err(syn::Error::new_spanned(
25+
async_runtime,
26+
"this attribute is only allowed on async functions",
27+
));
28+
}
29+
}
2230
let metadata_items = sig.metadata_items()?;
2331
let scaffolding_func = gen_ffi_function(&sig, arguments)?;
2432
Ok(quote! {
@@ -157,13 +165,6 @@ fn gen_ffi_function(
157165
let return_ty = &sig.return_ty;
158166

159167
Ok(if !sig.is_async {
160-
if let Some(async_runtime) = &arguments.async_runtime {
161-
return Err(syn::Error::new_spanned(
162-
async_runtime,
163-
"this attribute is only allowed on async functions",
164-
));
165-
}
166-
167168
quote! {
168169
#[doc(hidden)]
169170
#[no_mangle]

0 commit comments

Comments
 (0)