about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-13 05:55:50 +0000
committerbors <bors@rust-lang.org>2015-04-13 05:55:50 +0000
commit49798c597f810fbce14959bdbcdae0b635a5bde9 (patch)
tree8ffc335bd4ce1c13b6d1ed59e3e0080bc43dd02a /src/libstd
parent0cf99c3e06e84d20d68da649c888d63c72f33971 (diff)
parentef25b7d5389a68d50904a8b4f4785287fc7c6ac3 (diff)
downloadrust-49798c597f810fbce14959bdbcdae0b635a5bde9.tar.gz
rust-49798c597f810fbce14959bdbcdae0b635a5bde9.zip
Auto merge of #24323 - rprichard:panic-line-type, r=alexcrichton
There are syntax extensions that call `std::rt::begin_unwind` passing it a `usize`.  I updated the syntax extension to instead pass `u32`, but for bootstrapping reasons, I needed to create a `#[cfg(stage0)]` version of `std::rt::begin_unwind` and therefore also `panic!`.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/macros.rs49
-rw-r--r--src/libstd/panicking.rs2
-rw-r--r--src/libstd/rt/unwind.rs25
3 files changed, 70 insertions, 6 deletions
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 3d10c151f80..f3e99a8541a 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -38,6 +38,7 @@
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable]
+#[cfg(stage0)]
 macro_rules! panic {
     () => ({
         panic!("explicit panic")
@@ -55,7 +56,53 @@ macro_rules! panic {
             // used inside a dead function. Just `#[allow(dead_code)]` is
             // insufficient, since the user may have
             // `#[forbid(dead_code)]` and which cannot be overridden.
-            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
+            static _FILE_LINE: (&'static str, u32) = (file!(), line!());
+            &_FILE_LINE
+        })
+    });
+}
+
+/// The entry point for panic of Rust tasks.
+///
+/// This macro is used to inject panic into a Rust task, causing the task to
+/// unwind and panic entirely. Each task's panic can be reaped as the
+/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
+/// the value which is transmitted.
+///
+/// The multi-argument form of this macro panics with a string and has the
+/// `format!` syntax for building a string.
+///
+/// # Examples
+///
+/// ```should_panic
+/// # #![allow(unreachable_code)]
+/// panic!();
+/// panic!("this is a terrible mistake!");
+/// panic!(4); // panic with the value of 4 to be collected elsewhere
+/// panic!("this is a {} {message}", "fancy", message = "message");
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
+#[cfg(not(stage0))]
+macro_rules! panic {
+    () => ({
+        panic!("explicit panic")
+    });
+    ($msg:expr) => ({
+        $crate::rt::begin_unwind($msg, {
+            // static requires less code at runtime, more constant data
+            static _FILE_LINE: (&'static str, u32) = (file!(), line!());
+            &_FILE_LINE
+        })
+    });
+    ($fmt:expr, $($arg:tt)+) => ({
+        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
+            // The leading _'s are to avoid dead code warnings if this is
+            // used inside a dead function. Just `#[allow(dead_code)]` is
+            // insufficient, since the user may have
+            // `#[forbid(dead_code)]` and which cannot be overridden.
+            static _FILE_LINE: (&'static str, u32) = (file!(), line!());
             &_FILE_LINE
         })
     });
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 3e0584d9ab4..a498e634185 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -26,7 +26,7 @@ thread_local! {
     }
 }
 
-pub fn on_panic(obj: &(Any+Send), file: &'static str, line: usize) {
+pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 2f58a437eb4..b118010a0cc 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -78,7 +78,7 @@ struct Exception {
     cause: Option<Box<Any + Send + 'static>>,
 }
 
-pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: usize);
+pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: u32);
 
 // Variables used for invoking callbacks when a thread starts to unwind.
 //
@@ -484,7 +484,7 @@ pub mod eabi {
 /// Entry point of panic from the libcore crate.
 #[lang = "panic_fmt"]
 pub extern fn rust_begin_unwind(msg: fmt::Arguments,
-                                file: &'static str, line: usize) -> ! {
+                                file: &'static str, line: u32) -> ! {
     begin_unwind_fmt(msg, &(file, line))
 }
 
@@ -495,7 +495,7 @@ pub extern fn rust_begin_unwind(msg: fmt::Arguments,
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
 #[inline(never)] #[cold]
-pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, usize)) -> ! {
+pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
     use fmt::Write;
 
     // We do two allocations here, unfortunately. But (a) they're
@@ -510,6 +510,7 @@ pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, usize))
 
 /// This is the entry point of unwinding for panic!() and assert!().
 #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
+#[cfg(stage0)]
 pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, usize)) -> ! {
     // Note that this should be the only allocation performed in this code path.
     // Currently this means that panic!() on OOM will invoke this code path,
@@ -519,6 +520,22 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, usize)) ->
     // panicking.
 
     // see below for why we do the `Any` coercion here.
+    let (file, line) = *file_line;
+    begin_unwind_inner(Box::new(msg), &(file, line as u32))
+}
+
+/// This is the entry point of unwinding for panic!() and assert!().
+#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
+#[cfg(not(stage0))]
+pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
+    // Note that this should be the only allocation performed in this code path.
+    // Currently this means that panic!() on OOM will invoke this code path,
+    // but then again we're not really ready for panic on OOM anyway. If
+    // we do start doing this, then we should propagate this allocation to
+    // be performed in the parent of this thread instead of the thread that's
+    // panicking.
+
+    // see below for why we do the `Any` coercion here.
     begin_unwind_inner(Box::new(msg), file_line)
 }
 
@@ -533,7 +550,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, usize)) ->
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
 fn begin_unwind_inner(msg: Box<Any + Send>,
-                      file_line: &(&'static str, usize)) -> ! {
+                      file_line: &(&'static str, u32)) -> ! {
     // Make sure the default failure handler is registered before we look at the
     // callbacks. We also use a raw sys-based mutex here instead of a
     // `std::sync` one as accessing TLS can cause weird recursive problems (and