From cbee2a1ec44dcc49a0a10b713d6b5dac66cd7ba6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 7 Nov 2022 13:16:25 -0800 Subject: [PATCH 1/3] Add ui test to reproduce non-Send panic temporary --- tests/ui/macros/panic-temporaries.rs | 19 +++++++++++++++++ tests/ui/macros/panic-temporaries.stderr | 27 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tests/ui/macros/panic-temporaries.rs create mode 100644 tests/ui/macros/panic-temporaries.stderr diff --git a/tests/ui/macros/panic-temporaries.rs b/tests/ui/macros/panic-temporaries.rs new file mode 100644 index 00000000000..5ca139daf4e --- /dev/null +++ b/tests/ui/macros/panic-temporaries.rs @@ -0,0 +1,19 @@ +// check-fail +// edition:2021 + +#![allow(unreachable_code)] + +async fn f(_: u8) {} + +async fn g() { + // Todo returns `!`, so the await is never reached, and in particular the + // temporaries inside the formatting machinery are not still alive at the + // await point. + f(todo!("...")).await; +} + +fn require_send(_: impl Send) {} + +fn main() { + require_send(g()); //~ future cannot be sent between threads safely +} diff --git a/tests/ui/macros/panic-temporaries.stderr b/tests/ui/macros/panic-temporaries.stderr new file mode 100644 index 00000000000..425409dda69 --- /dev/null +++ b/tests/ui/macros/panic-temporaries.stderr @@ -0,0 +1,27 @@ +error: future cannot be sent between threads safely + --> $DIR/panic-temporaries.rs:18:18 + | +LL | require_send(g()); + | ^^^ future returned by `g` is not `Send` + | + = help: the trait `Sync` is not implemented for `core::fmt::Opaque` +note: future is not `Send` as this value is used across an await + --> $DIR/panic-temporaries.rs:12:20 + | +LL | f(todo!("...")).await; + | ------------ ^^^^^^ await occurs here, with `$crate::format_args!($($arg)+)` maybe used later + | | + | has type `ArgumentV1<'_>` which is not `Send` +note: `$crate::format_args!($($arg)+)` is later dropped here + --> $DIR/panic-temporaries.rs:12:26 + | +LL | f(todo!("...")).await; + | ^ +note: required by a bound in `require_send` + --> $DIR/panic-temporaries.rs:15:25 + | +LL | fn require_send(_: impl Send) {} + | ^^^^ required by this bound in `require_send` + +error: aborting due to previous error + From cb109a672d161ee305d21c98edb84ef50c6f997b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 7 Nov 2022 13:23:16 -0800 Subject: [PATCH 2/3] Shorten lifetime of panic temporaries in panic_fmt case --- library/core/src/panic.rs | 16 ++++++----- library/std/src/panic.rs | 4 ++- tests/ui/macros/panic-temporaries.rs | 4 +-- tests/ui/macros/panic-temporaries.stderr | 27 ------------------- ...ming-methods-have-optimized-codegen.stdout | 18 ++++++------- 5 files changed, 24 insertions(+), 45 deletions(-) delete mode 100644 tests/ui/macros/panic-temporaries.stderr diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 8338a5d7e5a..ebcce79b0f8 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -35,9 +35,11 @@ pub macro panic_2015 { ("{}", $arg:expr $(,)?) => ( $crate::panicking::panic_display(&$arg) ), - ($fmt:expr, $($arg:tt)+) => ( - $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+)) - ), + ($fmt:expr, $($arg:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+)); + }), } #[doc(hidden)] @@ -53,9 +55,11 @@ pub macro panic_2021 { ("{}", $arg:expr $(,)?) => ( $crate::panicking::panic_display(&$arg) ), - ($($t:tt)+) => ( - $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)) - ), + ($($t:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)); + }), } #[doc(hidden)] diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 345d72ef867..a2ffd8b1e7e 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -26,7 +26,9 @@ pub macro panic_2015 { $crate::rt::panic_display(&$arg) }), ($fmt:expr, $($arg:tt)+) => ({ - $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+)) + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+)); }), } diff --git a/tests/ui/macros/panic-temporaries.rs b/tests/ui/macros/panic-temporaries.rs index 5ca139daf4e..5b5b8b7c2d9 100644 --- a/tests/ui/macros/panic-temporaries.rs +++ b/tests/ui/macros/panic-temporaries.rs @@ -1,4 +1,4 @@ -// check-fail +// check-pass // edition:2021 #![allow(unreachable_code)] @@ -15,5 +15,5 @@ async fn g() { fn require_send(_: impl Send) {} fn main() { - require_send(g()); //~ future cannot be sent between threads safely + require_send(g()); } diff --git a/tests/ui/macros/panic-temporaries.stderr b/tests/ui/macros/panic-temporaries.stderr deleted file mode 100644 index 425409dda69..00000000000 --- a/tests/ui/macros/panic-temporaries.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error: future cannot be sent between threads safely - --> $DIR/panic-temporaries.rs:18:18 - | -LL | require_send(g()); - | ^^^ future returned by `g` is not `Send` - | - = help: the trait `Sync` is not implemented for `core::fmt::Opaque` -note: future is not `Send` as this value is used across an await - --> $DIR/panic-temporaries.rs:12:20 - | -LL | f(todo!("...")).await; - | ------------ ^^^^^^ await occurs here, with `$crate::format_args!($($arg)+)` maybe used later - | | - | has type `ArgumentV1<'_>` which is not `Send` -note: `$crate::format_args!($($arg)+)` is later dropped here - --> $DIR/panic-temporaries.rs:12:26 - | -LL | f(todo!("...")).await; - | ^ -note: required by a bound in `require_send` - --> $DIR/panic-temporaries.rs:15:25 - | -LL | fn require_send(_: impl Send) {} - | ^^^^ required by this bound in `require_send` - -error: aborting due to previous error - diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout index ad97f7a4a75..b69b5bc3b53 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout @@ -26,7 +26,7 @@ fn arbitrary_consuming_method_for_demonstration_purposes() { { ::std::rt::panic_fmt(format_args!("Assertion failed: elem as usize\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -42,7 +42,7 @@ fn addr_of() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: &elem\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -58,7 +58,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem == 1\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -71,7 +71,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem >= 1\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -84,7 +84,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem > 0\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -97,7 +97,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem < 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -110,7 +110,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem <= 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -123,7 +123,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem != 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -139,7 +139,7 @@ fn unary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: *elem\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; From 4be97e0b24246891eefe5eef90509b5c0450b313 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 14 May 2023 07:58:06 -0700 Subject: [PATCH 3/3] Exposes false negative in clippy's diverging_sub_expression --- .../clippy/tests/ui/diverging_sub_expression.stderr | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr index 9c91d935716..51a3b0d972e 100644 --- a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr +++ b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr @@ -30,19 +30,11 @@ error: sub-expression diverges LL | 3 => true || diverge(), | ^^^^^^^^^ -error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:36:30 - | -LL | _ => true || panic!("boo"), - | ^^^^^^^^^^^^^ - | - = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - error: sub-expression diverges --> $DIR/diverging_sub_expression.rs:38:26 | LL | _ => true || break, | ^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors