1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

copy original route macro input with compile errors (#2410)

This commit is contained in:
Rob Ede 2021-10-14 18:06:31 +01:00 committed by GitHub
parent 99985fc4ec
commit 6b3ea4fc61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 8 deletions

View File

@ -1,6 +1,9 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
* Improve error recovery potential when macro input is invalid. [#2410]
[#2410]: https://github.com/actix/actix-web/pull/2410
## 0.5.0-beta.4 - 2021-09-09 ## 0.5.0-beta.4 - 2021-09-09

View File

@ -21,6 +21,7 @@ actix-router = "0.5.0-beta.2"
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-macros = "0.2.2"
actix-test = "0.1.0-beta.3" actix-test = "0.1.0-beta.3"
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-web = "4.0.0-beta.9" actix-web = "4.0.0-beta.9"

View File

@ -349,8 +349,21 @@ pub(crate) fn with_method(
input: TokenStream, input: TokenStream,
) -> TokenStream { ) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
match Route::new(args, input, method) { match Route::new(args, input.clone(), method) {
Ok(route) => route.into_token_stream().into(), Ok(route) => route.into_token_stream().into(),
Err(err) => err.to_compile_error().into(), // on parse err, make IDEs happy; see fn docs
Err(err) => input_and_compile_error(input, err),
} }
} }
/// Converts the error to a token stream and appends it to the original input.
///
/// Returning the original input in addition to the error is good for IDEs which can gracefully
/// recover and show more precise errors within the macro body.
///
/// See <https://github.com/rust-analyzer/rust-analyzer/issues/10468> for more info.
fn input_and_compile_error(mut item: TokenStream, err: syn::Error) -> TokenStream {
let compile_err = TokenStream::from(err.to_compile_error());
item.extend(compile_err);
return item;
}

View File

@ -4,8 +4,8 @@ error: HTTP method defined more than once: `GET`
3 | #[route("/", method="GET", method="GET")] 3 | #[route("/", method="GET", method="GET")]
| ^^^^^ | ^^^^^
error[E0425]: cannot find value `index` in this scope error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
--> $DIR/route-duplicate-method-fail.rs:12:55 --> $DIR/route-duplicate-method-fail.rs:12:55
| |
12 | let srv = actix_test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`

View File

@ -6,8 +6,8 @@ error: The #[route(..)] macro requires at least one `method` attribute
| |
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0425]: cannot find value `index` in this scope error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
--> $DIR/route-missing-method-fail.rs:12:55 --> $DIR/route-missing-method-fail.rs:12:55
| |
12 | let srv = actix_test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`

View File

@ -4,8 +4,8 @@ error: Unexpected HTTP method: `UNEXPECTED`
3 | #[route("/", method="UNEXPECTED")] 3 | #[route("/", method="UNEXPECTED")]
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0425]: cannot find value `index` in this scope error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
--> $DIR/route-unexpected-method-fail.rs:12:55 --> $DIR/route-unexpected-method-fail.rs:12:55
| |
12 | let srv = actix_test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`