Skip to content

Commit 60f7b13

Browse files
stefunctionalfMeow
authored andcommitted
Support impl blocks for types
This adds support for `impl Type` blocks to `maybe_async`, `must_be_async` and `must_be_sync`. The changes are minimal as this reuses the machinery already in place for `impl Trait for Type`. The main motivation for this change is better interoperability with macros from other crates that apply to impl blocks and need functions to be resolved to async/sync before they run. Resolves #18
1 parent 11a966e commit 60f7b13

File tree

5 files changed

+55
-12
lines changed

5 files changed

+55
-12
lines changed

src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,11 +323,17 @@ fn convert_async(input: &mut Item, async_trait_mode: AsyncTraitMode) -> TokenStr
323323
AsyncTraitMode::NotSend => quote!(#[async_trait::async_trait(?Send)]#item),
324324
AsyncTraitMode::Off => quote!(#item),
325325
},
326-
Item::Impl(item) => match async_trait_mode {
327-
AsyncTraitMode::Send => quote!(#[async_trait::async_trait]#item),
328-
AsyncTraitMode::NotSend => quote!(#[async_trait::async_trait(?Send)]#item),
329-
AsyncTraitMode::Off => quote!(#item),
330-
},
326+
Item::Impl(item) => {
327+
let async_trait_mode = item
328+
.trait_
329+
.as_ref()
330+
.map_or(AsyncTraitMode::Off, |_| async_trait_mode);
331+
match async_trait_mode {
332+
AsyncTraitMode::Send => quote!(#[async_trait::async_trait]#item),
333+
AsyncTraitMode::NotSend => quote!(#[async_trait::async_trait(?Send)]#item),
334+
AsyncTraitMode::Off => quote!(#item),
335+
}
336+
}
331337
Item::Fn(item) => quote!(#item),
332338
Item::Static(item) => quote!(#item),
333339
}

src/parse.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ impl Parse for Item {
2323
let attrs = input.call(Attribute::parse_outer)?;
2424
let mut fork;
2525
let item = if let Ok(mut item) = fork!(fork = input).parse::<ItemImpl>() {
26-
if item.trait_.is_none() {
27-
return Err(Error::new(Span::call_site(), "expected a trait impl"));
28-
}
2926
item.attrs = attrs;
3027
Item::Impl(item)
3128
} else if let Ok(mut item) = fork!(fork = input).parse::<ItemTrait>() {
@@ -38,10 +35,7 @@ impl Parse for Item {
3835
item.attrs = attrs;
3936
Item::Static(item)
4037
} else {
41-
return Err(Error::new(
42-
Span::call_site(),
43-
"expected trait impl, trait or fn",
44-
));
38+
return Err(Error::new(Span::call_site(), "expected impl, trait or fn"));
4539
};
4640
input.advance_to(&fork);
4741
Ok(item)

tests/ui/01-maybe-async.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ unsafe fn unsafe_fn() {}
6060

6161
struct Struct;
6262

63+
#[maybe_async]
64+
impl Struct {
65+
fn sync_fn_inherent() {}
66+
67+
async fn declare_async_inherent(&self) {}
68+
69+
async fn async_fn_inherent(&self) {
70+
async { self.declare_async_inherent().await }.await
71+
}
72+
}
73+
6374
#[maybe_async]
6475
impl Trait for Struct {
6576
fn sync_fn() {}
@@ -85,6 +96,8 @@ impl AfitTrait for Struct {
8596
#[cfg(feature = "is_sync")]
8697
fn main() -> std::result::Result<(), ()> {
8798
let s = Struct;
99+
s.declare_async_inherent();
100+
s.async_fn_inherent();
88101
s.declare_async();
89102
s.async_fn();
90103
s.declare_async_afit();
@@ -98,6 +111,8 @@ fn main() -> std::result::Result<(), ()> {
98111
#[async_std::main]
99112
async fn main() {
100113
let s = Struct;
114+
s.declare_async_inherent().await;
115+
s.async_fn_inherent().await;
101116
s.declare_async().await;
102117
s.async_fn().await;
103118
s.declare_async_afit().await;

tests/ui/02-must-be-async.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ unsafe fn unsafe_fn() {}
7171

7272
struct Struct;
7373

74+
#[cfg(not(feature = "is_sync"))]
75+
#[maybe_async::must_be_async]
76+
impl Struct {
77+
fn sync_fn_inherent() {}
78+
79+
async fn declare_async_inherent(&self) {}
80+
81+
async fn async_fn_inherent(&self) {
82+
async { self.declare_async_inherent().await }.await
83+
}
84+
}
85+
7486
#[cfg(not(feature = "is_sync"))]
7587
#[maybe_async::must_be_async]
7688
impl Trait for Struct {
@@ -111,6 +123,8 @@ fn main() {}
111123
#[async_std::main]
112124
async fn main() {
113125
let s = Struct;
126+
s.declare_async_inherent().await;
127+
s.async_fn_inherent().await;
114128
s.declare_async().await;
115129
s.async_fn().await;
116130
s.declare_async_afit().await;

tests/ui/03-must-be-sync.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ unsafe fn unsafe_fn() {}
4747

4848
struct Struct;
4949

50+
#[cfg(feature = "is_sync")]
51+
#[maybe_async::must_be_sync]
52+
impl Struct {
53+
fn sync_fn_inherent() {}
54+
55+
async fn declare_async_inherent(&self) {}
56+
57+
async fn async_fn_inherent(&self) {
58+
async { self.declare_async_inherent().await }.await
59+
}
60+
}
61+
5062
#[cfg(feature = "is_sync")]
5163
#[maybe_async::must_be_sync]
5264
impl Trait for Struct {
@@ -62,6 +74,8 @@ impl Trait for Struct {
6274
#[cfg(feature = "is_sync")]
6375
fn main() -> std::result::Result<(), ()> {
6476
let s = Struct;
77+
s.declare_async_inherent();
78+
s.async_fn_inherent();
6579
s.declare_async();
6680
s.async_fn();
6781
async_fn();

0 commit comments

Comments
 (0)