diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/macros.rs | 22 | ||||
| -rw-r--r-- | src/libcore/panicking.rs | 32 | ||||
| -rw-r--r-- | src/libstd/panicking.rs | 109 |
3 files changed, 37 insertions, 126 deletions
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f98626d939d..c830c22ee5f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -9,7 +9,6 @@ // except according to those terms. /// Entry point of thread panic, for details, see std::macros -#[cfg(stage0)] #[macro_export] #[allow_internal_unstable] #[stable(feature = "core", since = "1.6.0")] @@ -29,27 +28,6 @@ macro_rules! panic { }); } -/// Entry point of thread panic, for details, see std::macros -#[cfg(not(stage0))] -#[macro_export] -#[allow_internal_unstable] -#[stable(feature = "core", since = "1.6.0")] -macro_rules! panic { - () => ( - panic!("explicit panic") - ); - ($msg:expr) => ({ - $crate::panicking::panic_payload($msg, &(file!(), line!(), __rust_unstable_column!())) - }); - ($msg:expr,) => ( - panic!($msg) - ); - ($fmt:expr, $($arg:tt)+) => ({ - $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), - &(file!(), line!(), __rust_unstable_column!())) - }); -} - /// Asserts that two expressions are equal to each other (using [`PartialEq`]). /// /// On panic, this macro will print the values of the expressions with their diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 4b4fa73c478..0d4f8d1141e 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -36,35 +36,10 @@ and related macros", issue = "0")] -#[cfg(not(stage0))] -use any::Any; use fmt; #[cfg(not(stage0))] use panic::{Location, PanicInfo}; -// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call -#[cfg(not(stage0))] -#[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe -extern "Rust" { - #[lang = "panic_impl"] - fn panic_impl(pi: &PanicInfo) -> !; -} - -#[cfg(not(stage0))] -#[cold] #[inline(never)] -pub fn panic_payload<M>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! -where - M: Any + Send, -{ - let (file, line, col) = *file_line_col; - let mut pi = PanicInfo::internal_constructor( - None, - Location::internal_constructor(file, line, col), - ); - pi.set_payload(&msg); - unsafe { panic_impl(&pi) } -} - #[cold] #[inline(never)] // this is the slow path, always #[lang = "panic"] pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! { @@ -102,6 +77,13 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) #[cfg(not(stage0))] #[cold] #[inline(never)] pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! { + // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call + #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe + extern "Rust" { + #[lang = "panic_impl"] + fn panic_impl(pi: &PanicInfo) -> !; + } + let (file, line, col) = *file_line_col; let pi = PanicInfo::internal_constructor( Some(&fmt), diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 1f80fb6f738..9d8052143b9 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -186,7 +186,7 @@ fn default_hook(info: &PanicInfo) { let location = info.location().unwrap(); // The current implementation always returns Some - let msg = match info.payload().downcast_ref::<&str>() { + let msg = match info.payload().downcast_ref::<&'static str>() { Some(s) => *s, None => match info.payload().downcast_ref::<String>() { Some(s) => &s[..], @@ -351,44 +351,45 @@ pub fn rust_begin_panic(info: &PanicInfo) -> ! { #[inline(never)] #[cold] pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! { - use fmt::Write; - // We do two allocations here, unfortunately. But (a) they're // required with the current scheme, and (b) we don't handle // panic + OOM properly anyway (see comment in begin_panic // below). rust_panic_with_hook(&mut PanicPayload::new(msg), Some(msg), file_line_col); +} + +// NOTE(stage0) move into `continue_panic_fmt` on next stage0 update +struct PanicPayload<'a> { + inner: &'a fmt::Arguments<'a>, + string: Option<String>, +} - struct PanicPayload<'a> { - inner: &'a fmt::Arguments<'a>, - string: Option<String>, +impl<'a> PanicPayload<'a> { + fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> { + PanicPayload { inner, string: None } } - impl<'a> PanicPayload<'a> { - fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> { - PanicPayload { inner, string: None } - } + fn fill(&mut self) -> &mut String { + use fmt::Write; - fn fill(&mut self) -> &mut String { - let inner = self.inner; - self.string.get_or_insert_with(|| { - let mut s = String::new(); - drop(s.write_fmt(*inner)); - s - }) - } + let inner = self.inner; + self.string.get_or_insert_with(|| { + let mut s = String::new(); + drop(s.write_fmt(*inner)); + s + }) } +} - unsafe impl<'a> BoxMeUp for PanicPayload<'a> { - fn box_me_up(&mut self) -> *mut (Any + Send) { - let contents = mem::replace(self.fill(), String::new()); - Box::into_raw(Box::new(contents)) - } +unsafe impl<'a> BoxMeUp for PanicPayload<'a> { + fn box_me_up(&mut self) -> *mut (Any + Send) { + let contents = mem::replace(self.fill(), String::new()); + Box::into_raw(Box::new(contents)) + } - fn get(&mut self) -> &(Any + Send) { - self.fill() - } + fn get(&mut self) -> &(Any + Send) { + self.fill() } } @@ -415,68 +416,18 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments, #[cfg(not(stage0))] fn continue_panic_fmt(info: &PanicInfo) -> ! { - use fmt::Write; - // We do two allocations here, unfortunately. But (a) they're // required with the current scheme, and (b) we don't handle // panic + OOM properly anyway (see comment in begin_panic // below). let loc = info.location().unwrap(); // The current implementation always returns Some + let msg = info.message().unwrap(); // The current implementation always returns Some let file_line_col = (loc.file(), loc.line(), loc.column()); rust_panic_with_hook( - &mut PanicPayload::new(info.payload(), info.message()), + &mut PanicPayload::new(msg), info.message(), &file_line_col); - - struct PanicPayload<'a> { - payload: &'a (Any + Send), - msg: Option<&'a fmt::Arguments<'a>>, - string: Option<String>, - } - - impl<'a> PanicPayload<'a> { - fn new(payload: &'a (Any + Send), msg: Option<&'a fmt::Arguments<'a>>) -> PanicPayload<'a> { - PanicPayload { payload, msg, string: None } - } - - fn fill(&mut self) -> Option<&mut String> { - if let Some(msg) = self.msg.cloned() { - Some(self.string.get_or_insert_with(|| { - let mut s = String::new(); - drop(s.write_fmt(msg)); - s - })) - } else { - None - } - } - } - - unsafe impl<'a> BoxMeUp for PanicPayload<'a> { - fn box_me_up(&mut self) -> *mut (Any + Send) { - if let Some(string) = self.fill() { - let contents = mem::replace(string, String::new()); - Box::into_raw(Box::new(contents)) - } else if let Some(s) = self.payload.downcast_ref::<&str>() { - Box::into_raw(Box::new(s.to_owned())) - } else if let Some(s) = self.payload.downcast_ref::<String>() { - Box::into_raw(Box::new(s.clone())) - } else { - // We can't go from &(Any+Send) to Box<Any+Send> so the payload is lost here - struct NoPayload; - Box::into_raw(Box::new(NoPayload)) - } - } - - fn get(&mut self) -> &(Any + Send) { - if let Some(s) = self.fill() { - s - } else { - self.payload - } - } - } } /// This is the entry point of panicking for panic!() and assert!(). @@ -484,7 +435,7 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! { reason = "used by the panic! macro", issue = "0")] #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible -pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&str, u32, u32)) -> ! { +pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, 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 |
