diff options
| author | bors <bors@rust-lang.org> | 2015-04-13 05:55:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-04-13 05:55:50 +0000 |
| commit | 49798c597f810fbce14959bdbcdae0b635a5bde9 (patch) | |
| tree | 8ffc335bd4ce1c13b6d1ed59e3e0080bc43dd02a /src/libstd | |
| parent | 0cf99c3e06e84d20d68da649c888d63c72f33971 (diff) | |
| parent | ef25b7d5389a68d50904a8b4f4785287fc7c6ac3 (diff) | |
| download | rust-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.rs | 49 | ||||
| -rw-r--r-- | src/libstd/panicking.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rt/unwind.rs | 25 |
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 |
