Skip to content

Commit 0cbc412

Browse files
authored
feat: Emit an error if #[pavex::methods] is used on an impl block with no Pavex-annotated methods
1 parent e728b32 commit 0cbc412

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ We contributors to Pavex:
2020
- Oliver Barnes (@oliverbarnes)
2121
- Joe Hasson (@joehasson)
2222
- Peter Wischer (@peddermaster2)
23+
- Paras Sharma (@duckaet)

runtime/pavex_macros/src/methods.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub fn methods(_metadata: TokenStream, input: TokenStream) -> Result<TokenStream
2020
let mut impl_: syn::ItemImpl = syn::parse(input).map_err(|e| e.into_compile_error())?;
2121
let mut new_items: Vec<proc_macro2::TokenStream> = Vec::new();
2222

23+
let mut no_pavex_method = true;
24+
2325
for item in impl_.items.iter_mut() {
2426
let ImplItem::Fn(method) = item else {
2527
continue;
@@ -31,6 +33,7 @@ pub fn methods(_metadata: TokenStream, input: TokenStream) -> Result<TokenStream
3133
else {
3234
continue;
3335
};
36+
no_pavex_method = false;
3437
let attr = method.attrs.remove(attr_index);
3538
let metadata = match attr.meta {
3639
// No arguments, just the path—e.g. `#[error_handler]`.
@@ -74,6 +77,18 @@ pub fn methods(_metadata: TokenStream, input: TokenStream) -> Result<TokenStream
7477
method.attrs.extend(new_attributes);
7578
}
7679

80+
if no_pavex_method {
81+
return Err(syn::Error::new(
82+
proc_macro2::Span::call_site(),
83+
"`#[pavex::methods]` is used to provide context for Pavex attributes on methods \
84+
(e.g., `#[pavex::get]`, `#[pavex::post]`, `#[pavex::error_handler]`, etc.).\n\
85+
This `impl` block contains no methods with Pavex attributes, so `#[pavex::methods]` \
86+
is unnecessary.",
87+
)
88+
.into_compile_error()
89+
.into());
90+
}
91+
7792
PxStripper.visit_item_impl_mut(&mut impl_);
7893

7994
Ok(quote! {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub struct A;
2+
3+
#[pavex::methods]
4+
impl A {
5+
}
6+
7+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: `#[pavex::methods]` is used to provide context for Pavex attributes on methods (e.g., `#[pavex::get]`, `#[pavex::post]`, `#[pavex::error_handler]`, etc.).
2+
This `impl` block contains no methods with Pavex attributes, so `#[pavex::methods]` is unnecessary.
3+
--> tests/methods/fail/empty_impl.rs:3:1
4+
|
5+
3 | #[pavex::methods]
6+
| ^^^^^^^^^^^^^^^^^
7+
|
8+
= note: this error originates in the attribute macro `pavex::methods` (in Nightly builds, run with -Z macro-backtrace for more info)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
pub struct A;
2+
3+
#[pavex::methods]
4+
impl A {
5+
pub fn new() -> Self {
6+
A
7+
}
8+
9+
pub fn regular_method(&self) -> i32 {
10+
42
11+
}
12+
}
13+
14+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: `#[pavex::methods]` is used to provide context for Pavex attributes on methods (e.g., `#[pavex::get]`, `#[pavex::post]`, `#[pavex::error_handler]`, etc.).
2+
This `impl` block contains no methods with Pavex attributes, so `#[pavex::methods]` is unnecessary.
3+
--> tests/methods/fail/no_pavex_methods.rs:3:1
4+
|
5+
3 | #[pavex::methods]
6+
| ^^^^^^^^^^^^^^^^^
7+
|
8+
= note: this error originates in the attribute macro `pavex::methods` (in Nightly builds, run with -Z macro-backtrace for more info)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
pub struct A;
2+
3+
#[pavex::methods]
4+
impl A {
5+
#[pavex::get(path = "/test")]
6+
pub fn handler(&self) -> String {
7+
"Hello".to_string()
8+
}
9+
10+
pub fn regular_method(&self) -> i32 {
11+
42
12+
}
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)