From 06e4ff4d61f44d7e239e02256829ecf1e5598657 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Fri, 27 Sep 2019 17:15:17 -0400 Subject: [PATCH] Scope format! temporaries This places the temporaries that `format!` generates to refer to its arguments (through `&dyn Trait`) in a short-lived scope surrounding just the invocation of `format!`. This enables `format!` to be used in generators without the temporaries preventing the generator from being `Send` (due to `dyn Trait` not being `Sync`). See rust-lang/rust#64477 for details. --- src/liballoc/macros.rs | 5 ++++- src/test/ui/fmt/issue-64477.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/fmt/issue-64477.rs diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index 2f2cdc39c633d..422d3486f92b2 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -98,5 +98,8 @@ macro_rules! vec { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! format { - ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*))) + ($($arg:tt)*) => {{ + let res = $crate::fmt::format($crate::__export::format_args!($($arg)*)); + res + }} } diff --git a/src/test/ui/fmt/issue-64477.rs b/src/test/ui/fmt/issue-64477.rs new file mode 100644 index 0000000000000..b7c8cf17c3148 --- /dev/null +++ b/src/test/ui/fmt/issue-64477.rs @@ -0,0 +1,16 @@ +// In the past, the code generated by `format!` produced temporaries in the surrounding scope that +// borrowed the arguments through `&dyn Trait`. These temporaries do not implement `Send`, which +// meant that when `format!` was used in an async block, the resulting generator was not `Send`. +// See https://github.com/rust-lang/rust/issues/64477#issuecomment-534669068 for details +// and https://github.com/rust-lang/rust/issues/64477#issuecomment-531882958 for an example. +async fn foo(_: String) {} + +fn bar() -> impl Send { + async move { + foo(format!("{}:{}", 1, 2)).await; + } +} + +fn main() { + let _ = bar(); +}