From 80bda3bf5f27778edff5e5b0d762932af2a0896b Mon Sep 17 00:00:00 2001 From: Fedorenko Dmitrij Date: Wed, 25 Aug 2021 20:59:41 +0300 Subject: [PATCH] macros: fix wrong error messages (#4067) --- .../tests/fail/macros_type_mismatch.rs | 14 --------- .../tests/fail/macros_type_mismatch.stderr | 31 ++++++------------- tests-build/tests/macros.rs | 6 ++++ tests-build/tests/macros_clippy.rs | 7 +++++ tests-build/tests/pass/macros_main_loop.rs | 14 +++++++++ tests-build/tests/pass/macros_main_return.rs | 6 ++++ tokio-macros/src/entry.rs | 16 ++++++++-- 7 files changed, 56 insertions(+), 38 deletions(-) create mode 100644 tests-build/tests/macros_clippy.rs create mode 100644 tests-build/tests/pass/macros_main_loop.rs create mode 100644 tests-build/tests/pass/macros_main_return.rs diff --git a/tests-build/tests/fail/macros_type_mismatch.rs b/tests-build/tests/fail/macros_type_mismatch.rs index 086244c9fd3..47e34938ea0 100644 --- a/tests-build/tests/fail/macros_type_mismatch.rs +++ b/tests-build/tests/fail/macros_type_mismatch.rs @@ -7,25 +7,11 @@ async fn missing_semicolon_or_return_type() { #[tokio::main] async fn missing_return_type() { - /* TODO(taiki-e): one of help messages still wrong - help: consider using a semicolon here - | - 16 | return Ok(());; - | - */ return Ok(()); } #[tokio::main] async fn extra_semicolon() -> Result<(), ()> { - /* TODO(taiki-e): help message still wrong - help: try using a variant of the expected enum - | - 29 | Ok(Ok(());) - | - 29 | Err(Ok(());) - | - */ Ok(()); } diff --git a/tests-build/tests/fail/macros_type_mismatch.stderr b/tests-build/tests/fail/macros_type_mismatch.stderr index 4d573181523..978dfc13ae6 100644 --- a/tests-build/tests/fail/macros_type_mismatch.stderr +++ b/tests-build/tests/fail/macros_type_mismatch.stderr @@ -16,36 +16,23 @@ help: try adding a return type | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/macros_type_mismatch.rs:16:5 + --> $DIR/macros_type_mismatch.rs:10:5 | -16 | return Ok(()); +9 | async fn missing_return_type() { + | - help: try adding a return type: `-> Result<(), _>` +10 | return Ok(()); | ^^^^^^^^^^^^^^ expected `()`, found enum `Result` | = note: expected unit type `()` found enum `Result<(), _>` -help: consider using a semicolon here - | -16 | return Ok(());; - | ^ -help: try adding a return type - | -9 | async fn missing_return_type() -> Result<(), _> { - | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/macros_type_mismatch.rs:29:5 + --> $DIR/macros_type_mismatch.rs:14:31 | -20 | async fn extra_semicolon() -> Result<(), ()> { - | -------------- expected `Result<(), ()>` because of return type -... -29 | Ok(()); - | ^^^^^^^ expected enum `Result`, found `()` +14 | async fn extra_semicolon() -> Result<(), ()> { + | --------------- ^^^^^^^^^^^^^^ expected enum `Result`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected enum `Result<(), ()>` found unit type `()` -help: try using a variant of the expected enum - | -29 | Ok(Ok(());) - | -29 | Err(Ok(());) - | diff --git a/tests-build/tests/macros.rs b/tests-build/tests/macros.rs index d2330cb6e18..0a180dfb74f 100644 --- a/tests-build/tests/macros.rs +++ b/tests-build/tests/macros.rs @@ -5,6 +5,12 @@ fn compile_fail_full() { #[cfg(feature = "full")] t.pass("tests/pass/forward_args_and_output.rs"); + #[cfg(feature = "full")] + t.pass("tests/pass/macros_main_return.rs"); + + #[cfg(feature = "full")] + t.pass("tests/pass/macros_main_loop.rs"); + #[cfg(feature = "full")] t.compile_fail("tests/fail/macros_invalid_input.rs"); diff --git a/tests-build/tests/macros_clippy.rs b/tests-build/tests/macros_clippy.rs new file mode 100644 index 00000000000..0f3f4bb0b8b --- /dev/null +++ b/tests-build/tests/macros_clippy.rs @@ -0,0 +1,7 @@ +#[cfg(feature = "full")] +#[tokio::test] +async fn test_with_semicolon_without_return_type() { + #![deny(clippy::semicolon_if_nothing_returned)] + + dbg!(0); +} diff --git a/tests-build/tests/pass/macros_main_loop.rs b/tests-build/tests/pass/macros_main_loop.rs new file mode 100644 index 00000000000..d7d51982c36 --- /dev/null +++ b/tests-build/tests/pass/macros_main_loop.rs @@ -0,0 +1,14 @@ +use tests_build::tokio; + +#[tokio::main] +async fn main() -> Result<(), ()> { + loop { + if !never() { + return Ok(()); + } + } +} + +fn never() -> bool { + std::time::Instant::now() > std::time::Instant::now() +} diff --git a/tests-build/tests/pass/macros_main_return.rs b/tests-build/tests/pass/macros_main_return.rs new file mode 100644 index 00000000000..d4d34ec26d3 --- /dev/null +++ b/tests-build/tests/pass/macros_main_return.rs @@ -0,0 +1,6 @@ +use tests_build::tokio; + +#[tokio::main] +async fn main() -> Result<(), ()> { + return Ok(()); +} diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index 8816a43af54..9da0d61f427 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -323,15 +323,27 @@ fn parse_knobs( let body = &input.block; let brace_token = input.block.brace_token; + let (tail_return, tail_semicolon) = match body.stmts.last() { + Some(syn::Stmt::Semi(expr, _)) => ( + match expr { + syn::Expr::Return(_) => quote! { return }, + _ => quote! {}, + }, + quote! { + ; + }, + ), + _ => (quote! {}, quote! {}), + }; input.block = syn::parse2(quote_spanned! {last_stmt_end_span=> { let body = async #body; #[allow(clippy::expect_used)] - #rt + #tail_return #rt .enable_all() .build() .expect("Failed building the Runtime") - .block_on(body) + .block_on(body)#tail_semicolon } }) .expect("Parsing failure");