about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorCameron Steffen <cam.steffen94@gmail.com>2021-09-21 00:56:45 -0500
committerCameron Steffen <cam.steffen94@gmail.com>2021-09-21 10:04:44 -0500
commit09b37d743328bd497939bd27135f82350f1b0bd7 (patch)
tree48d14423db8c6c1d1fcd2049f25dc5b88db024c8 /compiler
parentdb1fb85cff63ad5fffe435e17128f99f9e1d970c (diff)
downloadrust-09b37d743328bd497939bd27135f82350f1b0bd7.tar.gz
rust-09b37d743328bd497939bd27135f82350f1b0bd7.zip
Use ZST for fmt unsafety
This allows the format_args! macro to keep the pre-expansion code out of
the unsafe block without doing gymnastics with nested `match`
expressions. This reduces codegen.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs32
-rw-r--r--compiler/rustc_span/src/symbol.rs1
2 files changed, 15 insertions, 18 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index c7626dec4d7..9b9adc2d7f3 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -845,8 +845,7 @@ impl<'a, 'b> Context<'a, 'b> {
             self.ecx.expr_match(self.macsp, head, vec![arm])
         };
 
-        let ident = Ident::from_str_and_span("args", self.macsp);
-        let args_slice = self.ecx.expr_ident(self.macsp, ident);
+        let args_slice = self.ecx.expr_addr_of(self.macsp, args_match);
 
         // Now create the fmt::Arguments struct with all our locals we created.
         let (fn_name, fn_args) = if self.all_pieces_simple {
@@ -856,25 +855,22 @@ impl<'a, 'b> Context<'a, 'b> {
             // nonstandard placeholders, if there are any.
             let fmt = self.ecx.expr_vec_slice(self.macsp, self.pieces);
 
-            ("new_v1_formatted", vec![pieces, args_slice, fmt])
+            let path = self.ecx.std_path(&[sym::fmt, sym::UnsafeArg, sym::new]);
+            let unsafe_arg = self.ecx.expr_call_global(self.macsp, path, Vec::new());
+            let unsafe_expr = self.ecx.expr_block(P(ast::Block {
+                stmts: vec![self.ecx.stmt_expr(unsafe_arg)],
+                id: ast::DUMMY_NODE_ID,
+                rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated),
+                span: self.macsp,
+                tokens: None,
+                could_be_bare_literal: false,
+            }));
+
+            ("new_v1_formatted", vec![pieces, args_slice, fmt, unsafe_expr])
         };
 
         let path = self.ecx.std_path(&[sym::fmt, sym::Arguments, Symbol::intern(fn_name)]);
-        let arguments = self.ecx.expr_call_global(self.macsp, path, fn_args);
-        let body = self.ecx.expr_block(P(ast::Block {
-            stmts: vec![self.ecx.stmt_expr(arguments)],
-            id: ast::DUMMY_NODE_ID,
-            rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated),
-            span: self.macsp,
-            tokens: None,
-            could_be_bare_literal: false,
-        }));
-
-        let ident = Ident::from_str_and_span("args", self.macsp);
-        let binding_mode = ast::BindingMode::ByRef(ast::Mutability::Not);
-        let pat = self.ecx.pat_ident_binding_mode(self.macsp, ident, binding_mode);
-        let arm = self.ecx.arm(self.macsp, pat, body);
-        self.ecx.expr_match(self.macsp, args_match, vec![arm])
+        self.ecx.expr_call_global(self.macsp, path, fn_args)
     }
 
     fn format_arg(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 322bea3806c..be6f5fc2978 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -253,6 +253,7 @@ symbols! {
         TyCtxt,
         TyKind,
         Unknown,
+        UnsafeArg,
         Vec,
         Yield,
         _DECLS,