From b0a666105ccd5733162a03895563b8c0d26abd6d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Apr 2022 13:54:48 +0900 Subject: [PATCH 1/5] macros: ensure return type if it is unit --- .../tests/fail/macros_core_no_default.stderr | 2 +- .../tests/fail/macros_dead_code.stderr | 4 +- .../tests/fail/macros_invalid_input.rs | 2 + .../tests/fail/macros_invalid_input.stderr | 74 ++++++++++--------- .../tests/fail/macros_type_mismatch.rs | 8 ++ .../tests/fail/macros_type_mismatch.stderr | 14 +++- tokio-macros/src/entry.rs | 10 +-- 7 files changed, 68 insertions(+), 46 deletions(-) diff --git a/tests-build/tests/fail/macros_core_no_default.stderr b/tests-build/tests/fail/macros_core_no_default.stderr index 676acc8dbe3..c1a35af3c6e 100644 --- a/tests-build/tests/fail/macros_core_no_default.stderr +++ b/tests-build/tests/fail/macros_core_no_default.stderr @@ -1,5 +1,5 @@ error: The default runtime flavor is `multi_thread`, but the `rt-multi-thread` feature is disabled. - --> $DIR/macros_core_no_default.rs:3:1 + --> tests/fail/macros_core_no_default.rs:3:1 | 3 | #[tokio::main] | ^^^^^^^^^^^^^^ diff --git a/tests-build/tests/fail/macros_dead_code.stderr b/tests-build/tests/fail/macros_dead_code.stderr index 816c294bd31..19ea06e8f71 100644 --- a/tests-build/tests/fail/macros_dead_code.stderr +++ b/tests-build/tests/fail/macros_dead_code.stderr @@ -1,11 +1,11 @@ error: function is never used: `f` - --> $DIR/macros_dead_code.rs:6:10 + --> tests/fail/macros_dead_code.rs:6:10 | 6 | async fn f() {} | ^ | note: the lint level is defined here - --> $DIR/macros_dead_code.rs:1:9 + --> tests/fail/macros_dead_code.rs:1:9 | 1 | #![deny(dead_code)] | ^^^^^^^^^ diff --git a/tests-build/tests/fail/macros_invalid_input.rs b/tests-build/tests/fail/macros_invalid_input.rs index 5179bb6add2..3272757b9f0 100644 --- a/tests-build/tests/fail/macros_invalid_input.rs +++ b/tests-build/tests/fail/macros_invalid_input.rs @@ -1,3 +1,5 @@ +#![deny(duplicate_macro_attributes)] + use tests_build::tokio; #[tokio::main] diff --git a/tests-build/tests/fail/macros_invalid_input.stderr b/tests-build/tests/fail/macros_invalid_input.stderr index 5e492f8fd25..cd294dddf36 100644 --- a/tests-build/tests/fail/macros_invalid_input.stderr +++ b/tests-build/tests/fail/macros_invalid_input.stderr @@ -1,97 +1,101 @@ error: the `async` keyword is missing from the function declaration - --> $DIR/macros_invalid_input.rs:4:1 + --> tests/fail/macros_invalid_input.rs:6:1 | -4 | fn main_is_not_async() {} +6 | fn main_is_not_async() {} | ^^ error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate` - --> $DIR/macros_invalid_input.rs:6:15 + --> tests/fail/macros_invalid_input.rs:8:15 | -6 | #[tokio::main(foo)] +8 | #[tokio::main(foo)] | ^^^ error: Must have specified ident - --> $DIR/macros_invalid_input.rs:9:15 - | -9 | #[tokio::main(threadpool::bar)] - | ^^^^^^^^^^^^^^^ + --> tests/fail/macros_invalid_input.rs:11:15 + | +11 | #[tokio::main(threadpool::bar)] + | ^^^^^^^^^^^^^^^ error: the `async` keyword is missing from the function declaration - --> $DIR/macros_invalid_input.rs:13:1 + --> tests/fail/macros_invalid_input.rs:15:1 | -13 | fn test_is_not_async() {} +15 | fn test_is_not_async() {} | ^^ error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate` - --> $DIR/macros_invalid_input.rs:15:15 + --> tests/fail/macros_invalid_input.rs:17:15 | -15 | #[tokio::test(foo)] +17 | #[tokio::test(foo)] | ^^^ error: Unknown attribute foo is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate` - --> $DIR/macros_invalid_input.rs:18:15 + --> tests/fail/macros_invalid_input.rs:20:15 | -18 | #[tokio::test(foo = 123)] +20 | #[tokio::test(foo = 123)] | ^^^^^^^^^ error: Failed to parse value of `flavor` as string. - --> $DIR/macros_invalid_input.rs:21:24 + --> tests/fail/macros_invalid_input.rs:23:24 | -21 | #[tokio::test(flavor = 123)] +23 | #[tokio::test(flavor = 123)] | ^^^ error: No such runtime flavor `foo`. The runtime flavors are `current_thread` and `multi_thread`. - --> $DIR/macros_invalid_input.rs:24:24 + --> tests/fail/macros_invalid_input.rs:26:24 | -24 | #[tokio::test(flavor = "foo")] +26 | #[tokio::test(flavor = "foo")] | ^^^^^ error: The `start_paused` option requires the `current_thread` runtime flavor. Use `#[tokio::test(flavor = "current_thread")]` - --> $DIR/macros_invalid_input.rs:27:55 + --> tests/fail/macros_invalid_input.rs:29:55 | -27 | #[tokio::test(flavor = "multi_thread", start_paused = false)] +29 | #[tokio::test(flavor = "multi_thread", start_paused = false)] | ^^^^^ error: Failed to parse value of `worker_threads` as integer. - --> $DIR/macros_invalid_input.rs:30:57 + --> tests/fail/macros_invalid_input.rs:32:57 | -30 | #[tokio::test(flavor = "multi_thread", worker_threads = "foo")] +32 | #[tokio::test(flavor = "multi_thread", worker_threads = "foo")] | ^^^^^ error: The `worker_threads` option requires the `multi_thread` runtime flavor. Use `#[tokio::test(flavor = "multi_thread")]` - --> $DIR/macros_invalid_input.rs:33:59 + --> tests/fail/macros_invalid_input.rs:35:59 | -33 | #[tokio::test(flavor = "current_thread", worker_threads = 4)] +35 | #[tokio::test(flavor = "current_thread", worker_threads = 4)] | ^ error: Failed to parse value of `crate` as ident. - --> $DIR/macros_invalid_input.rs:36:23 + --> tests/fail/macros_invalid_input.rs:38:23 | -36 | #[tokio::test(crate = 456)] +38 | #[tokio::test(crate = 456)] | ^^^ error: Failed to parse value of `crate` as ident: "456" - --> $DIR/macros_invalid_input.rs:39:23 + --> tests/fail/macros_invalid_input.rs:41:23 | -39 | #[tokio::test(crate = "456")] +41 | #[tokio::test(crate = "456")] | ^^^^^ error: Failed to parse value of `crate` as ident: "abc::edf" - --> $DIR/macros_invalid_input.rs:42:23 + --> tests/fail/macros_invalid_input.rs:44:23 | -42 | #[tokio::test(crate = "abc::edf")] +44 | #[tokio::test(crate = "abc::edf")] | ^^^^^^^^^^ error: second test attribute is supplied - --> $DIR/macros_invalid_input.rs:46:1 + --> tests/fail/macros_invalid_input.rs:48:1 | -46 | #[test] +48 | #[test] | ^^^^^^^ error: duplicated attribute - --> $DIR/macros_invalid_input.rs:46:1 + --> tests/fail/macros_invalid_input.rs:48:1 | -46 | #[test] +48 | #[test] | ^^^^^^^ | - = note: `-D duplicate-macro-attributes` implied by `-D warnings` +note: the lint level is defined here + --> tests/fail/macros_invalid_input.rs:1:9 + | +1 | #![deny(duplicate_macro_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests-build/tests/fail/macros_type_mismatch.rs b/tests-build/tests/fail/macros_type_mismatch.rs index 0a5b9c4c727..f43ae790fe0 100644 --- a/tests-build/tests/fail/macros_type_mismatch.rs +++ b/tests-build/tests/fail/macros_type_mismatch.rs @@ -23,4 +23,12 @@ async fn extra_semicolon() -> Result<(), ()> { Ok(()); } +// https://github.com/tokio-rs/tokio/issues/4635 +#[allow(redundant_semicolons)] +#[tokio::main] +async fn issue_4635() { + return 1; + ; +} + fn main() {} diff --git a/tests-build/tests/fail/macros_type_mismatch.stderr b/tests-build/tests/fail/macros_type_mismatch.stderr index 304a37e0712..5ebaac7c4d6 100644 --- a/tests-build/tests/fail/macros_type_mismatch.stderr +++ b/tests-build/tests/fail/macros_type_mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/macros_type_mismatch.rs:5:5 + --> tests/fail/macros_type_mismatch.rs:5:5 | 4 | async fn missing_semicolon_or_return_type() { | - possibly return type missing here? @@ -12,7 +12,7 @@ error[E0308]: mismatched types found enum `Result<(), _>` error[E0308]: mismatched types - --> $DIR/macros_type_mismatch.rs:10:5 + --> tests/fail/macros_type_mismatch.rs:10:5 | 9 | async fn missing_return_type() { | - possibly return type missing here? @@ -23,7 +23,7 @@ error[E0308]: mismatched types found enum `Result<(), _>` error[E0308]: mismatched types - --> $DIR/macros_type_mismatch.rs:23:5 + --> tests/fail/macros_type_mismatch.rs:23:5 | 14 | async fn extra_semicolon() -> Result<(), ()> { | -------------- expected `Result<(), ()>` because of return type @@ -38,3 +38,11 @@ help: try adding an expression at the end of the block 23 ~ Ok(());; 24 + Ok(()) | + +error[E0308]: mismatched types + --> tests/fail/macros_type_mismatch.rs:28:1 + | +28 | #[tokio::main] + | ^^^^^^^^^^^^^^ expected integer, found `()` + | + = note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index eba636baf48..0141432e4db 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -383,16 +383,16 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To let body = &input.block; let brace_token = input.block.brace_token; - let (tail_return, tail_semicolon) = match body.stmts.last() { + let (tail_return_or_let, tail_semicolon) = match body.stmts.last() { Some(syn::Stmt::Semi(syn::Expr::Return(_), _)) => (quote! { return }, quote! { ; }), Some(syn::Stmt::Semi(..)) | Some(syn::Stmt::Local(..)) | None => { match &input.sig.output { syn::ReturnType::Type(_, ty) if matches!(&**ty, syn::Type::Tuple(ty) if ty.elems.is_empty()) => { - (quote! {}, quote! { ; }) // unit + (quote! { let () = }, quote! { ; }) // unit } - syn::ReturnType::Default => (quote! {}, quote! { ; }), // unit - syn::ReturnType::Type(..) => (quote! {}, quote! {}), // ! or another + syn::ReturnType::Default => (quote! { let () = }, quote! { ; }), // unit + syn::ReturnType::Type(..) => (quote! {}, quote! {}), // ! or another } } _ => (quote! {}, quote! {}), @@ -401,7 +401,7 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To { let body = async #body; #[allow(clippy::expect_used)] - #tail_return #rt + #tail_return_or_let #rt .enable_all() .build() .expect("Failed building the Runtime") From 40ac5bf19f84117c4731689e00c1d611bed72de7 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Apr 2022 14:42:14 +0900 Subject: [PATCH 2/5] macros: always emit return statement --- .../tests/fail/macros_type_mismatch.stderr | 24 +++++++++---------- tokio-macros/src/entry.rs | 18 ++------------ 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/tests-build/tests/fail/macros_type_mismatch.stderr b/tests-build/tests/fail/macros_type_mismatch.stderr index 5ebaac7c4d6..fe5042fec00 100644 --- a/tests-build/tests/fail/macros_type_mismatch.stderr +++ b/tests-build/tests/fail/macros_type_mismatch.stderr @@ -4,9 +4,7 @@ error[E0308]: mismatched types 4 | async fn missing_semicolon_or_return_type() { | - possibly return type missing here? 5 | Ok(()) - | ^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found enum `Result` + | ^^^^^^ expected `()`, found enum `Result` | = note: expected unit type `()` found enum `Result<(), _>` @@ -33,16 +31,18 @@ error[E0308]: mismatched types | = note: expected enum `Result<(), ()>` found unit type `()` -help: try adding an expression at the end of the block - | -23 ~ Ok(());; -24 + Ok(()) +help: try wrapping the expression in a variant of `Result` | +23 | Ok(Ok(());) + | +++ + +23 | Err(Ok(());) + | ++++ + error[E0308]: mismatched types - --> tests/fail/macros_type_mismatch.rs:28:1 - | -28 | #[tokio::main] - | ^^^^^^^^^^^^^^ expected integer, found `()` + --> tests/fail/macros_type_mismatch.rs:31:5 | - = note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info) +29 | async fn issue_4635() { + | - possibly return type missing here? +30 | return 1; +31 | ; + | ^ expected `()`, found integer diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index 0141432e4db..b615d8e19b8 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -383,29 +383,15 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To let body = &input.block; let brace_token = input.block.brace_token; - let (tail_return_or_let, tail_semicolon) = match body.stmts.last() { - Some(syn::Stmt::Semi(syn::Expr::Return(_), _)) => (quote! { return }, quote! { ; }), - Some(syn::Stmt::Semi(..)) | Some(syn::Stmt::Local(..)) | None => { - match &input.sig.output { - syn::ReturnType::Type(_, ty) if matches!(&**ty, syn::Type::Tuple(ty) if ty.elems.is_empty()) => - { - (quote! { let () = }, quote! { ; }) // unit - } - syn::ReturnType::Default => (quote! { let () = }, quote! { ; }), // unit - syn::ReturnType::Type(..) => (quote! {}, quote! {}), // ! or another - } - } - _ => (quote! {}, quote! {}), - }; input.block = syn::parse2(quote_spanned! {last_stmt_end_span=> { let body = async #body; #[allow(clippy::expect_used)] - #tail_return_or_let #rt + return #rt .enable_all() .build() .expect("Failed building the Runtime") - .block_on(body)#tail_semicolon + .block_on(body); } }) .expect("Parsing failure"); From 4d9a09f75aac58a03e204e5f63ec8e989fc9b0ff Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Apr 2022 17:17:11 +0900 Subject: [PATCH 3/5] fmt --- tests-build/tests/fail/macros_type_mismatch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests-build/tests/fail/macros_type_mismatch.rs b/tests-build/tests/fail/macros_type_mismatch.rs index f43ae790fe0..c292ee68f66 100644 --- a/tests-build/tests/fail/macros_type_mismatch.rs +++ b/tests-build/tests/fail/macros_type_mismatch.rs @@ -25,6 +25,7 @@ async fn extra_semicolon() -> Result<(), ()> { // https://github.com/tokio-rs/tokio/issues/4635 #[allow(redundant_semicolons)] +#[rustfmt::skip] #[tokio::main] async fn issue_4635() { return 1; From b5ab564b6ba6c38434e07b3c40ea261ea432a01f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Apr 2022 17:19:19 +0900 Subject: [PATCH 4/5] address clippy::diverging_sub_expression in generated code --- tokio-macros/src/entry.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index b615d8e19b8..68eb829176b 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -386,12 +386,14 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To input.block = syn::parse2(quote_spanned! {last_stmt_end_span=> { let body = async #body; - #[allow(clippy::expect_used)] - return #rt - .enable_all() - .build() - .expect("Failed building the Runtime") - .block_on(body); + #[allow(clippy::expect_used, clippy::diverging_sub_expression)] + { + return #rt + .enable_all() + .build() + .expect("Failed building the Runtime") + .block_on(body); + } } }) .expect("Parsing failure"); From 98fc8a866744338791075972dad150ee4bec9c91 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Apr 2022 17:23:08 +0900 Subject: [PATCH 5/5] fix line number in ui test output --- tests-build/tests/fail/macros_type_mismatch.stderr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests-build/tests/fail/macros_type_mismatch.stderr b/tests-build/tests/fail/macros_type_mismatch.stderr index fe5042fec00..9e1bd5ca0c3 100644 --- a/tests-build/tests/fail/macros_type_mismatch.stderr +++ b/tests-build/tests/fail/macros_type_mismatch.stderr @@ -39,10 +39,10 @@ help: try wrapping the expression in a variant of `Result` | ++++ + error[E0308]: mismatched types - --> tests/fail/macros_type_mismatch.rs:31:5 + --> tests/fail/macros_type_mismatch.rs:32:5 | -29 | async fn issue_4635() { +30 | async fn issue_4635() { | - possibly return type missing here? -30 | return 1; -31 | ; +31 | return 1; +32 | ; | ^ expected `()`, found integer