diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-24 03:16:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-24 03:16:57 +0100 |
| commit | d845e6fc8d293cf8cf0c0ac987b9c917a1eb6fab (patch) | |
| tree | b9f05528a4a6e990c566649ca3924e892a005fb4 | |
| parent | ad808d95c4839caedc2be76d0ed059dc920ab4b6 (diff) | |
| parent | 31fc42b7f778accb21db8daaf0f0e725948c9d6d (diff) | |
| download | rust-d845e6fc8d293cf8cf0c0ac987b9c917a1eb6fab.tar.gz rust-d845e6fc8d293cf8cf0c0ac987b9c917a1eb6fab.zip | |
Rollup merge of #64856 - jonhoo:format-temporaries, r=sfackler
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.
| -rw-r--r-- | src/liballoc/macros.rs | 5 | ||||
| -rw-r--r-- | src/test/pretty/issue-4264.pp | 56 | ||||
| -rw-r--r-- | src/test/ui/async-await/issues/issue-64477-2.rs | 22 |
3 files changed, 56 insertions, 27 deletions
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index 2f2cdc39c63..422d3486f92 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/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index b545146c964..8aa4cdeb539 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -29,33 +29,37 @@ pub fn bar() ({ - ((::alloc::fmt::format as - for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1 - as - fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test" - as - &'static str)] - as - [&str; 1]) - as - &[&str; 1]), - (&(match (() + ({ + let res = + ((::alloc::fmt::format as + for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1 + as + fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test" + as + &'static str)] + as + [&str; 1]) as - ()) - { - () - => - ([] - as - [std::fmt::ArgumentV1<'_>; 0]), - } - as - [std::fmt::ArgumentV1<'_>; 0]) - as - &[std::fmt::ArgumentV1<'_>; 0])) - as - std::fmt::Arguments<'_>)) - as std::string::String); + &[&str; 1]), + (&(match (() + as + ()) + { + () + => + ([] + as + [std::fmt::ArgumentV1<'_>; 0]), + } + as + [std::fmt::ArgumentV1<'_>; 0]) + as + &[std::fmt::ArgumentV1<'_>; 0])) + as + std::fmt::Arguments<'_>)) + as std::string::String); + (res as std::string::String) + } as std::string::String); } as ()) pub type Foo = [i32; (3 as usize)]; pub struct Bar { diff --git a/src/test/ui/async-await/issues/issue-64477-2.rs b/src/test/ui/async-await/issues/issue-64477-2.rs new file mode 100644 index 00000000000..2360b57cc45 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-64477-2.rs @@ -0,0 +1,22 @@ +// Another regression test for #64477. +// +// 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. +// +// check-pass +// edition:2018 + +async fn foo(_: String) {} + +fn bar() -> impl Send { + async move { + foo(format!("{}:{}", 1, 2)).await; + } +} + +fn main() { + let _ = bar(); +} |
