about summary refs log tree commit diff
path: root/src/libstd/macros.rs
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2014-01-27 22:37:55 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2014-01-27 23:58:03 +1100
commitb4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212 (patch)
tree9fb5bc2209efd91a825d791caa029b8184c167e2 /src/libstd/macros.rs
parente5abe669831a59c48faa85e88ed8859b6dc63f49 (diff)
downloadrust-b4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212.tar.gz
rust-b4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212.zip
std: add begin_unwind_fmt that reduces codesize for formatted fail!().
This ends up saving a single `call` instruction in the optimised code,
but saves a few hundred lines of non-optimised IR for `fn main() {
fail!("foo {}", "bar"); }` (comparing against the minimal generic
baseline from the parent commit).
Diffstat (limited to 'src/libstd/macros.rs')
-rw-r--r--src/libstd/macros.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index e7844101c5f..4032b63790b 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -48,8 +48,18 @@ macro_rules! fail(
         ::std::rt::begin_unwind($msg, file!(), line!())
     );
     ($fmt:expr, $($arg:tt)*) => (
-        ::std::rt::begin_unwind(format!($fmt, $($arg)*), file!(), line!())
-    )
+        {
+            // a closure can't have return type !, so we need a full
+            // function to pass to format_args!, *and* we need the
+            // file and line numbers right here; so an inner bare fn
+            // is our only choice.
+            #[inline]
+            fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
+                ::std::rt::begin_unwind_fmt(fmt, file!(), line!())
+            }
+            format_args!(run_fmt, $fmt, $($arg)*)
+        }
+        )
 )
 
 #[macro_export]