Use call-site span for future Send check in debug_handler

This commit is contained in:
Jonas Platte
2023-01-30 21:47:57 +01:00
parent 4a5dc4391c
commit bdfaedb344
3 changed files with 21 additions and 26 deletions
+12 -12
View File
@@ -373,7 +373,7 @@ fn check_future_send(item_fn: &ItemFn) -> TokenStream {
}; };
} }
let span = item_fn.span(); let span = item_fn.sig.ident.span();
let handler_name = &item_fn.sig.ident; let handler_name = &item_fn.sig.ident;
@@ -383,28 +383,28 @@ fn check_future_send(item_fn: &ItemFn) -> TokenStream {
let name = format_ident!("__axum_macros_check_{}_future", item_fn.sig.ident); let name = format_ident!("__axum_macros_check_{}_future", item_fn.sig.ident);
let do_check = quote! {
fn check<T>(_: T)
where T: ::std::future::Future + Send
{}
check(future);
};
if let Some(receiver) = self_receiver(item_fn) { if let Some(receiver) = self_receiver(item_fn) {
quote_spanned! {span=> quote! {
#[allow(warnings)] #[allow(warnings)]
fn #name() { fn #name() {
let future = #receiver #handler_name(#(#args),*); let future = #receiver #handler_name(#(#args),*);
fn check<T>(_: T) #do_check
where T: ::std::future::Future + Send
{}
check(future);
} }
} }
} else { } else {
quote_spanned! {span=> quote! {
#[allow(warnings)] #[allow(warnings)]
fn #name() { fn #name() {
#item_fn #item_fn
let future = #handler_name(#(#args),*); let future = #handler_name(#(#args),*);
fn check<T>(_: T) #do_check
where T: ::std::future::Future + Send
{}
check(future);
} }
} }
} }
@@ -1,11 +1,8 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> tests/debug_handler/fail/not_send.rs:4:1 --> tests/debug_handler/fail/not_send.rs:3:1
| |
4 | / async fn handler() { 3 | #[debug_handler]
5 | | let rc = std::rc::Rc::new(()); | ^^^^^^^^^^^^^^^^ future returned by `handler` is not `Send`
6 | | async {}.await;
7 | | }
| |_^ future returned by `handler` is not `Send`
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
@@ -18,10 +15,8 @@ note: future is not `Send` as this value is used across an await
7 | } 7 | }
| - `rc` is later dropped here | - `rc` is later dropped here
note: required by a bound in `check` note: required by a bound in `check`
--> tests/debug_handler/fail/not_send.rs:4:1 --> tests/debug_handler/fail/not_send.rs:3:1
| |
4 | / async fn handler() { 3 | #[debug_handler]
5 | | let rc = std::rc::Rc::new(()); | ^^^^^^^^^^^^^^^^ required by this bound in `check`
6 | | async {}.await; = note: this error originates in the attribute macro `debug_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
7 | | }
| |_^ required by this bound in `check`
@@ -13,9 +13,9 @@ error[E0277]: the trait bound `bool: IntoResponse` is not satisfied
(Response<()>, T1, R) (Response<()>, T1, R)
(Response<()>, T1, T2, R) (Response<()>, T1, T2, R)
(Response<()>, T1, T2, T3, R) (Response<()>, T1, T2, T3, R)
and 124 others and $N others
note: required by a bound in `__axum_macros_check_handler_into_response::{closure#0}::check` note: required by a bound in `__axum_macros_check_handler_into_response::{closure#0}::check`
--> tests/debug_handler/fail/wrong_return_type.rs:4:23 --> tests/debug_handler/fail/wrong_return_type.rs:4:23
| |
4 | async fn handler() -> bool { 4 | async fn handler() -> bool {
| ^^^^ required by this bound in `__axum_macros_check_handler_into_response::{closure#0}::check` | ^^^^ required by this bound in `check`