]> git.lizzy.rs Git - rust.git/commitdiff
Scope format! temporaries
authorJon Gjengset <jon@thesquareplanet.com>
Fri, 27 Sep 2019 21:15:17 +0000 (17:15 -0400)
committerJon Gjengset <jon@thesquareplanet.com>
Fri, 27 Sep 2019 21:36:45 +0000 (17:36 -0400)
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
src/test/ui/fmt/issue-64477.rs [new file with mode: 0644]

index 2f2cdc39c633db3f763d302db11cfdb6c0602031..422d3486f92b29cc860cc33f4868590c7562f5e7 100644 (file)
@@ -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 (file)
index 0000000..b7c8cf1
--- /dev/null
@@ -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();
+}