diff options
| author | Jorge Aparicio <jorge@japaric.io> | 2018-05-16 14:07:58 +0200 |
|---|---|---|
| committer | Jorge Aparicio <jorge@japaric.io> | 2018-06-03 13:46:19 +0200 |
| commit | 430ad769008c0aaa40949a1d98a6f0e18e35ec65 (patch) | |
| tree | deae3f6dbdfd4fd0313086c27beac54df75ce38b /src/libstd | |
| parent | eb1936141611afa8ad9034c4093e1539df36548c (diff) | |
| download | rust-430ad769008c0aaa40949a1d98a6f0e18e35ec65.tar.gz rust-430ad769008c0aaa40949a1d98a6f0e18e35ec65.zip | |
undo payload in core::panic! changes
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/panicking.rs | 109 |
1 files changed, 30 insertions, 79 deletions
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 |
