diff --git a/tests/ui/macros/panic-temporaries-2018.rs b/tests/ui/macros/panic-temporaries-2018.rs new file mode 100644 index 00000000000..d914df38062 --- /dev/null +++ b/tests/ui/macros/panic-temporaries-2018.rs @@ -0,0 +1,55 @@ +// check-pass +// edition:2018 + +#![allow(non_fmt_panics, unreachable_code)] + +use std::fmt::{self, Display}; +use std::marker::PhantomData; + +struct NotSend { + marker: PhantomData<*const u8>, +} + +const NOT_SEND: NotSend = NotSend { marker: PhantomData }; + +impl Display for NotSend { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("this value does not implement Send") + } +} + +async fn f(_: u8) {} + +// Exercises this matcher in panic_2015: +// ($fmt:expr, $($arg:tt)+) => $crate::panicking::panic_fmt(...) +async fn panic_fmt() { + // Panic returns `!`, so the await is never reached, and in particular the + // temporaries inside the formatting machinery are not still alive at the + // await point. + let todo = "..."; + f(panic!("not yet implemented: {}", todo)).await; +} + +// Exercises ("{}", $arg:expr) => $crate::panicking::panic_display(&$arg) +async fn panic_display() { + f(panic!("{}", NOT_SEND)).await; +} + +// Exercises ($msg:expr) => $crate::panicking::panic_str($msg) +async fn panic_str() { + f(panic!((NOT_SEND, "...").1)).await; +} + +// Exercises ($msg:expr) => $crate::panicking::unreachable_display(&$msg) +async fn unreachable_display() { + f(unreachable!(NOT_SEND)).await; +} + +fn require_send(_: impl Send) {} + +fn main() { + require_send(panic_fmt()); + require_send(panic_display()); + require_send(panic_str()); + require_send(unreachable_display()); +} diff --git a/tests/ui/macros/panic-temporaries.rs b/tests/ui/macros/panic-temporaries.rs index 5b5b8b7c2d9..db65601fb73 100644 --- a/tests/ui/macros/panic-temporaries.rs +++ b/tests/ui/macros/panic-temporaries.rs @@ -3,17 +3,41 @@ #![allow(unreachable_code)] +use std::fmt::{self, Display}; +use std::marker::PhantomData; + +struct NotSend { + marker: PhantomData<*const u8>, +} + +const NOT_SEND: NotSend = NotSend { marker: PhantomData }; + +impl Display for NotSend { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("this value does not implement Send") + } +} + async fn f(_: u8) {} -async fn g() { - // Todo returns `!`, so the await is never reached, and in particular the +// Exercises this matcher in panic_2021: +// ($($t:tt)+) => $crate::panicking::panic_fmt(...) +async fn panic_fmt() { + // Panic 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; + let todo = "..."; + f(panic!("not yet implemented: {}", todo)).await; +} + +// Exercises ("{}", $arg:expr) => $crate::panicking::panic_display(&$arg) +async fn panic_display() { + f(panic!("{}", NOT_SEND)).await; } fn require_send(_: impl Send) {} fn main() { - require_send(g()); + require_send(panic_fmt()); + require_send(panic_display()); }