From 59df6c8eb917cba41c15e3366f29ee780c9c74df Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Fri, 22 Oct 2021 12:21:10 -0500 Subject: [PATCH 1/9] Try commiting again --- library/std/src/error.rs | 245 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 6ae0bc47a9462..9fb8f2b9b8bc5 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -25,7 +25,7 @@ use crate::backtrace::Backtrace; use crate::borrow::Cow; use crate::cell; use crate::char; -use crate::fmt::{self, Debug, Display}; +use crate::fmt::{self, Debug, Display, Write}; use crate::mem::transmute; use crate::num; use crate::str; @@ -807,3 +807,246 @@ impl dyn Error + Send + Sync { }) } } + +/// An error reporter that exposes the entire error chain for printing. +/// It also exposes options for formatting the error chain, either entirely on a single line, +/// or in multi-line format with each cause in the error chain on a new line. +/// +/// # Examples +/// +/// ``` +/// #![feature(error_reporter)] +/// +/// use std::error::{Error, Report}; +/// use std::fmt; +/// +/// #[derive(Debug)] +/// struct SuperError { +/// side: SuperErrorSideKick, +/// } +/// +/// impl fmt::Display for SuperError { +/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +/// write!(f, "SuperError is here!") +/// } +/// } +/// +/// impl Error for SuperError { +/// fn source(&self) -> Option<&(dyn Error + 'static)> { +/// Some(&self.side) +/// } +/// } +/// +/// #[derive(Debug)] +/// struct SuperErrorSideKick; +/// +/// impl fmt::Display for SuperErrorSideKick { +/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +/// write!(f, "SuperErrorSideKick is here!") +/// } +/// } +/// +/// impl Error for SuperErrorSideKick {} +/// +/// fn main() { +/// let error = SuperError { side: SuperErrorSideKick }; +/// let report = Report::new(&error).pretty(); +/// +/// println!("{}", report); +/// } +/// ``` +#[unstable(feature = "error_reporter", issue = "90172")] +pub struct Report { + source: E, + show_backtrace: bool, + pretty: bool, +} + +impl Report +where + E: Error, +{ + /// Create a new `Report` from an input error. + #[unstable(feature = "error_reporter", issue = "90172")] + pub fn new(source: E) -> Report { + Report { source, show_backtrace: false, pretty: false } + } + + /// Enable pretty-printing the report. + #[unstable(feature = "error_reporter", issue = "90172")] + pub fn pretty(mut self) -> Self { + self.pretty = true; + self + } + + /// Enable showing a backtrace for the report. + #[unstable(feature = "error_reporter", issue = "90172")] + pub fn show_backtrace(mut self) -> Self { + self.show_backtrace = true; + self + } + + /// Format the report as a single line. + #[unstable(feature = "error_reporter", issue = "90172")] + fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.source)?; + + let sources = self.source.source().into_iter().flat_map(::chain); + + for cause in sources { + write!(f, ": {}", cause)?; + } + + Ok(()) + } + + /// Format the report as multiple lines, with each error cause on its own line. + #[unstable(feature = "error_reporter", issue = "90172")] + fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = &self.source; + + write!(f, "{}", error)?; + + if let Some(cause) = error.source() { + write!(f, "\n\nCaused by:")?; + + let multiple = cause.source().is_some(); + let format = if multiple { + Format::Numbered { ind: 0 } + } else { + Format::Uniform { indentation: " " } + }; + + for error in cause.chain() { + writeln!(f)?; + + let mut indented = Indented { inner: f, needs_indent: true, format }; + + write!(indented, "{}", error)?; + } + } + + if self.show_backtrace { + let backtrace = error.backtrace(); + + if let Some(backtrace) = backtrace { + let mut backtrace = backtrace.to_string(); + + write!(f, "\n\n")?; + writeln!(f, "Stack backtrace:")?; + + backtrace.truncate(backtrace.trim_end().len()); + + write!(f, "{}", backtrace)?; + } + } + + Ok(()) + } +} + +#[unstable(feature = "error_reporter", issue = "90172")] +impl From for Report +where + E: Error, +{ + fn from(source: E) -> Self { + Report::new(source) + } +} + +#[unstable(feature = "error_reporter", issue = "90172")] +impl fmt::Display for Report +where + E: Error, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) } + } +} + +// This type intentionally outputs the same format for `Display` and `Debug`for +// situations where you unwrap a `Report` or return it from main. +#[unstable(feature = "error_reporter", issue = "90172")] +impl fmt::Debug for Report +where + E: Error, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +/// Encapsulates how error sources are indented and formatted. +struct Indented<'a, D: ?Sized> { + inner: &'a mut D, + needs_indent: bool, + format: Format, +} + +/// The possible variants that error sources can be formatted as. +#[derive(Clone, Copy)] +enum Format { + /// Insert uniform indentation before every line. + /// + /// This format takes a static string as input and inserts it after every newline. + Uniform { + /// The string to insert as indentation. + indentation: &'static str, + }, + /// Inserts a number before the first line. + /// + /// This format hard codes the indentation level to match the indentation from + /// `std::backtrace::Backtrace`. + Numbered { + /// The index to insert before the first line of output. + ind: usize, + }, +} + +impl Write for Indented<'_, D> +where + D: Write + ?Sized, +{ + fn write_str(&mut self, s: &str) -> fmt::Result { + for (ind, line) in s.split('\n').enumerate() { + if ind > 0 { + self.inner.write_char('\n')?; + self.needs_indent = true; + } + + if self.needs_indent { + if line.is_empty() { + continue; + } + + self.format.insert_indentation(ind, &mut self.inner)?; + self.needs_indent = false; + } + + self.inner.write_fmt(format_args!("{}", line))?; + } + + Ok(()) + } +} + +impl Format { + /// Write the specified formatting to the write buffer. + fn insert_indentation(&mut self, line: usize, f: &mut dyn Write) -> fmt::Result { + match self { + Format::Uniform { indentation } => { + write!(f, "{}", indentation) + } + Format::Numbered { ind } => { + if line == 0 { + write!(f, "{: >4}: ", ind)?; + *ind += 1; + Ok(()) + } else { + write!(f, " ") + } + } + } + } +} From 6a59d0e3aa26543fc4d3eaae1fa4cd48522045d2 Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Fri, 22 Oct 2021 13:43:42 -0500 Subject: [PATCH 2/9] Have `pretty` and `show_backtrace` accept booleans --- library/std/src/error.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 9fb8f2b9b8bc5..5988075836d54 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -850,7 +850,7 @@ impl dyn Error + Send + Sync { /// /// fn main() { /// let error = SuperError { side: SuperErrorSideKick }; -/// let report = Report::new(&error).pretty(); +/// let report = Report::new(&error).pretty(true); /// /// println!("{}", report); /// } @@ -874,15 +874,15 @@ where /// Enable pretty-printing the report. #[unstable(feature = "error_reporter", issue = "90172")] - pub fn pretty(mut self) -> Self { - self.pretty = true; + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = pretty; self } /// Enable showing a backtrace for the report. #[unstable(feature = "error_reporter", issue = "90172")] - pub fn show_backtrace(mut self) -> Self { - self.show_backtrace = true; + pub fn show_backtrace(mut self, show_backtrace: bool) -> Self { + self.show_backtrace = show_backtrace; self } From c6de41331c732a8f70088ceab12a5049e3db0caa Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Fri, 22 Oct 2021 13:47:05 -0500 Subject: [PATCH 3/9] Change `source` field to `error` --- library/std/src/error.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 5988075836d54..52f3ebbdee47e 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -857,7 +857,7 @@ impl dyn Error + Send + Sync { /// ``` #[unstable(feature = "error_reporter", issue = "90172")] pub struct Report { - source: E, + error: E, show_backtrace: bool, pretty: bool, } @@ -868,8 +868,8 @@ where { /// Create a new `Report` from an input error. #[unstable(feature = "error_reporter", issue = "90172")] - pub fn new(source: E) -> Report { - Report { source, show_backtrace: false, pretty: false } + pub fn new(error: E) -> Report { + Report { error, show_backtrace: false, pretty: false } } /// Enable pretty-printing the report. @@ -889,9 +889,9 @@ where /// Format the report as a single line. #[unstable(feature = "error_reporter", issue = "90172")] fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.source)?; + write!(f, "{}", self.error)?; - let sources = self.source.source().into_iter().flat_map(::chain); + let sources = self.error.source().into_iter().flat_map(::chain); for cause in sources { write!(f, ": {}", cause)?; @@ -903,7 +903,7 @@ where /// Format the report as multiple lines, with each error cause on its own line. #[unstable(feature = "error_reporter", issue = "90172")] fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let error = &self.source; + let error = &self.error; write!(f, "{}", error)?; @@ -950,8 +950,8 @@ impl From for Report where E: Error, { - fn from(source: E) -> Self { - Report::new(source) + fn from(error: E) -> Self { + Report::new(error) } } From c0f14cb9301eacb51fc660f1d461cbc783f4aaa7 Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Wed, 27 Oct 2021 13:03:53 -0500 Subject: [PATCH 4/9] Attempt to fix tidy errors --- library/std/src/error.rs | 133 ++++++--------- library/std/src/error/tests.rs | 291 +++++++++++++++++++++++++++++++++ 2 files changed, 345 insertions(+), 79 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 52f3ebbdee47e..d8859cf1e552e 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -25,7 +25,7 @@ use crate::backtrace::Backtrace; use crate::borrow::Cow; use crate::cell; use crate::char; -use crate::fmt::{self, Debug, Display, Write}; +use crate::fmt::{self, Debug, Display}; use crate::mem::transmute; use crate::num; use crate::str; @@ -816,6 +816,7 @@ impl dyn Error + Send + Sync { /// /// ``` /// #![feature(error_reporter)] +/// #![feature(negative_impls)] /// /// use std::error::{Error, Report}; /// use std::fmt; @@ -848,6 +849,10 @@ impl dyn Error + Send + Sync { /// /// impl Error for SuperErrorSideKick {} /// +/// // Note that the error doesn't need to be `Send` or `Sync`. +/// impl !Send for SuperError {} +/// impl !Sync for SuperError {} +/// /// fn main() { /// let error = SuperError { side: SuperErrorSideKick }; /// let report = Report::new(&error).pretty(true); @@ -855,10 +860,37 @@ impl dyn Error + Send + Sync { /// println!("{}", report); /// } /// ``` +/// +/// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the +/// wrapped error be `Send`, `Sync`, or `'static`. +/// +/// ```rust +/// # #![feature(error_reporter)] +/// # use std::fmt; +/// # use std::error::{Error, Report}; +/// #[derive(Debug)] +/// struct SuperError<'a> { +/// side: &'a str, +/// } +/// impl<'a> fmt::Display for SuperError<'a> { +/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +/// write!(f, "SuperError is here: {}", self.side) +/// } +/// } +/// impl<'a> Error for SuperError<'a> {} +/// fn main() { +/// let msg = String::from("Huzzah!"); +/// let report = Report::new(SuperError { side: &msg }); +/// println!("{}", report); +/// } +/// ``` #[unstable(feature = "error_reporter", issue = "90172")] pub struct Report { + /// The error being reported. error: E, + /// Whether a backtrace should be included as part of the report. show_backtrace: bool, + /// Whether the report should be pretty-printed. pretty: bool, } @@ -911,18 +943,15 @@ where write!(f, "\n\nCaused by:")?; let multiple = cause.source().is_some(); - let format = if multiple { - Format::Numbered { ind: 0 } - } else { - Format::Uniform { indentation: " " } - }; - for error in cause.chain() { + for (ind, error) in cause.chain().enumerate() { writeln!(f)?; - let mut indented = Indented { inner: f, needs_indent: true, format }; - - write!(indented, "{}", error)?; + if multiple { + write!(f, "{: >4}: {}", ind, Indented { source: error })?; + } else { + write!(f, " {}", error)?; + } } } @@ -930,14 +959,10 @@ where let backtrace = error.backtrace(); if let Some(backtrace) = backtrace { - let mut backtrace = backtrace.to_string(); - - write!(f, "\n\n")?; - writeln!(f, "Stack backtrace:")?; + let backtrace = backtrace.to_string(); - backtrace.truncate(backtrace.trim_end().len()); - - write!(f, "{}", backtrace)?; + f.write_str("\n\nStack backtrace:\n")?; + f.write_str(backtrace.trim_end())?; } } @@ -977,76 +1002,26 @@ where } } -/// Encapsulates how error sources are indented and formatted. -struct Indented<'a, D: ?Sized> { - inner: &'a mut D, - needs_indent: bool, - format: Format, -} - -/// The possible variants that error sources can be formatted as. -#[derive(Clone, Copy)] -enum Format { - /// Insert uniform indentation before every line. - /// - /// This format takes a static string as input and inserts it after every newline. - Uniform { - /// The string to insert as indentation. - indentation: &'static str, - }, - /// Inserts a number before the first line. - /// - /// This format hard codes the indentation level to match the indentation from - /// `std::backtrace::Backtrace`. - Numbered { - /// The index to insert before the first line of output. - ind: usize, - }, +/// Wrapper type for indenting the inner source. +struct Indented { + source: D, } -impl Write for Indented<'_, D> +impl fmt::Display for Indented where - D: Write + ?Sized, + D: fmt::Display, { - fn write_str(&mut self, s: &str) -> fmt::Result { - for (ind, line) in s.split('\n').enumerate() { - if ind > 0 { - self.inner.write_char('\n')?; - self.needs_indent = true; - } - - if self.needs_indent { - if line.is_empty() { - continue; - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let source = self.source.to_string(); - self.format.insert_indentation(ind, &mut self.inner)?; - self.needs_indent = false; + for (ind, line) in source.trim().split('\n').filter(|l| !l.is_empty()).enumerate() { + if ind > 0 { + write!(f, "\n {}", line)?; + } else { + write!(f, "{}", line)?; } - - self.inner.write_fmt(format_args!("{}", line))?; } Ok(()) } } - -impl Format { - /// Write the specified formatting to the write buffer. - fn insert_indentation(&mut self, line: usize, f: &mut dyn Write) -> fmt::Result { - match self { - Format::Uniform { indentation } => { - write!(f, "{}", indentation) - } - Format::Numbered { ind } => { - if line == 0 { - write!(f, "{: >4}: ", ind)?; - *ind += 1; - Ok(()) - } else { - write!(f, " ") - } - } - } - } -} diff --git a/library/std/src/error/tests.rs b/library/std/src/error/tests.rs index 66d6924f34d2b..c408915ca71a9 100644 --- a/library/std/src/error/tests.rs +++ b/library/std/src/error/tests.rs @@ -35,3 +35,294 @@ fn downcasting() { Err(e) => assert_eq!(*e.downcast::().unwrap(), A), } } + +use crate::backtrace; +use crate::env; +use crate::error::Report; + +#[derive(Debug)] +struct SuperError { + side: SuperErrorSideKick, +} + +impl fmt::Display for SuperError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SuperError is here!") + } +} + +impl Error for SuperError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.side) + } +} + +#[derive(Debug)] +struct SuperErrorSideKick; + +impl fmt::Display for SuperErrorSideKick { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SuperErrorSideKick is here!") + } +} + +impl Error for SuperErrorSideKick {} + +#[test] +fn single_line_formatting() { + let error = SuperError { side: SuperErrorSideKick }; + let report = Report::new(&error); + let actual = report.to_string(); + let expected = String::from("SuperError is here!: SuperErrorSideKick is here!"); + + assert_eq!(expected, actual); +} + +#[test] +fn multi_line_formatting() { + let error = SuperError { side: SuperErrorSideKick }; + let report = Report::new(&error).pretty(true); + let actual = report.to_string(); + let expected = + String::from("SuperError is here!\n\nCaused by:\n SuperErrorSideKick is here!"); + + assert_eq!(expected, actual); +} + +#[test] +fn error_with_no_sources_formats_single_line_correctly() { + let report = Report::new(SuperErrorSideKick); + let actual = report.to_string(); + let expected = String::from("SuperErrorSideKick is here!"); + + assert_eq!(expected, actual); +} + +#[test] +fn error_with_no_sources_formats_multi_line_correctly() { + let report = Report::new(SuperErrorSideKick).pretty(true); + let actual = report.to_string(); + let expected = String::from("SuperErrorSideKick is here!"); + + assert_eq!(expected, actual); +} + +#[test] +fn error_with_backtrace_outputs_correctly() { + use backtrace::Backtrace; + + env::remove_var("RUST_BACKTRACE"); + + #[derive(Debug)] + struct ErrorWithBacktrace<'a> { + msg: &'a str, + trace: Backtrace, + } + + impl<'a> fmt::Display for ErrorWithBacktrace<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Error with backtrace: {}", self.msg) + } + } + + impl<'a> Error for ErrorWithBacktrace<'a> { + fn backtrace(&self) -> Option<&Backtrace> { + Some(&self.trace) + } + } + + let msg = String::from("The source of the error"); + let report = Report::new(ErrorWithBacktrace { msg: &msg, trace: Backtrace::capture() }) + .pretty(true) + .show_backtrace(true); + + let expected = String::from( + "Error with backtrace: The source of the error\n\nStack backtrace:\ndisabled backtrace", + ); + + assert_eq!(expected, report.to_string()); +} + +#[derive(Debug)] +struct GenericError { + message: D, + source: Option>, +} + +impl GenericError { + fn new(message: D) -> GenericError { + Self { message, source: None } + } + + fn new_with_source(message: D, source: E) -> GenericError + where + E: Error + 'static, + { + let source: Box = Box::new(source); + let source = Some(source); + GenericError { message, source } + } +} + +impl fmt::Display for GenericError +where + D: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.message, f) + } +} + +impl Error for GenericError +where + D: fmt::Debug + fmt::Display, +{ + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.source.as_deref() + } +} + +#[test] +fn error_formats_single_line_with_rude_display_impl() { + #[derive(Debug)] + struct MyMessage; + + impl fmt::Display for MyMessage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("line 1\nline 2")?; + f.write_str("\nline 3\nline 4\n")?; + f.write_str("line 5\nline 6")?; + Ok(()) + } + } + + let error = GenericError::new(MyMessage); + let error = GenericError::new_with_source(MyMessage, error); + let error = GenericError::new_with_source(MyMessage, error); + let error = GenericError::new_with_source(MyMessage, error); + let report = Report::new(error); + let expected = r#"line 1 +line 2 +line 3 +line 4 +line 5 +line 6: line 1 +line 2 +line 3 +line 4 +line 5 +line 6: line 1 +line 2 +line 3 +line 4 +line 5 +line 6: line 1 +line 2 +line 3 +line 4 +line 5 +line 6"#; + + let actual = report.to_string(); + assert_eq!(expected, actual); +} + +#[test] +fn error_formats_multi_line_with_rude_display_impl() { + #[derive(Debug)] + struct MyMessage; + + impl fmt::Display for MyMessage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("line 1\nline 2")?; + f.write_str("\nline 3\nline 4\n")?; + f.write_str("line 5\nline 6")?; + Ok(()) + } + } + + let error = GenericError::new(MyMessage); + let error = GenericError::new_with_source(MyMessage, error); + let error = GenericError::new_with_source(MyMessage, error); + let error = GenericError::new_with_source(MyMessage, error); + let report = Report::new(error).pretty(true); + let expected = r#"line 1 +line 2 +line 3 +line 4 +line 5 +line 6 + +Caused by: + 0: line 1 + line 2 + line 3 + line 4 + line 5 + line 6 + 1: line 1 + line 2 + line 3 + line 4 + line 5 + line 6 + 2: line 1 + line 2 + line 3 + line 4 + line 5 + line 6"#; + + let actual = report.to_string(); + assert_eq!(expected, actual); +} + +#[test] +fn errors_that_start_with_newline_formats_correctly() { + #[derive(Debug)] + struct MyMessage; + + impl fmt::Display for MyMessage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("\nThe message\n") + } + } + + let error = GenericError::new(MyMessage); + let error = GenericError::new_with_source(MyMessage, error); + let error = GenericError::new_with_source(MyMessage, error); + let report = Report::new(error).pretty(true); + let expected = r#" +The message + + +Caused by: + 0: The message + 1: The message"#; + + let actual = report.to_string(); + assert_eq!(expected, actual); +} + +#[test] +fn errors_with_string_interpolation_formats_correctly() { + #[derive(Debug)] + struct MyMessage(usize); + + impl fmt::Display for MyMessage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Got an error code: ({}). ", self.0)?; + write!(f, "What would you like to do in response?") + } + } + + let error = GenericError::new(MyMessage(10)); + let error = GenericError::new_with_source(MyMessage(20), error); + let report = Report::new(error).pretty(true); + let expected = r#"Got an error code: (20). What would you like to do in response? + +Caused by: + Got an error code: (10). What would you like to do in response?"#; + let actual = report.to_string(); + assert_eq!(expected, actual); +} From aa853bd31775db7fcb5074f78d8b989053ae101d Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Wed, 27 Oct 2021 13:04:42 -0500 Subject: [PATCH 5/9] Add `rust` annotation to doctest --- library/std/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index d8859cf1e552e..a6d36dbe5c794 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -814,7 +814,7 @@ impl dyn Error + Send + Sync { /// /// # Examples /// -/// ``` +/// ```rust /// #![feature(error_reporter)] /// #![feature(negative_impls)] /// From d2f49eeb176a670c76f3c8c6005208a9d3cc30ee Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Wed, 27 Oct 2021 13:18:22 -0500 Subject: [PATCH 6/9] Format doctest --- library/std/src/error.rs | 55 ++++++++-------------------------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index a6d36dbe5c794..26fa6c38549d3 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -811,6 +811,8 @@ impl dyn Error + Send + Sync { /// An error reporter that exposes the entire error chain for printing. /// It also exposes options for formatting the error chain, either entirely on a single line, /// or in multi-line format with each cause in the error chain on a new line. +/// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the +/// wrapped error be `Send`, `Sync`, or `'static`. /// /// # Examples /// @@ -822,68 +824,31 @@ impl dyn Error + Send + Sync { /// use std::fmt; /// /// #[derive(Debug)] -/// struct SuperError { -/// side: SuperErrorSideKick, -/// } -/// -/// impl fmt::Display for SuperError { -/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -/// write!(f, "SuperError is here!") -/// } -/// } -/// -/// impl Error for SuperError { -/// fn source(&self) -> Option<&(dyn Error + 'static)> { -/// Some(&self.side) -/// } +/// struct SuperError<'a> { +/// side: &'a str, /// } /// -/// #[derive(Debug)] -/// struct SuperErrorSideKick; -/// -/// impl fmt::Display for SuperErrorSideKick { +/// impl<'a> fmt::Display for SuperError<'a> { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -/// write!(f, "SuperErrorSideKick is here!") +/// write!(f, "SuperError is here: {}", self.side) /// } /// } /// -/// impl Error for SuperErrorSideKick {} +/// impl<'a> Error for SuperError<'a> {} /// /// // Note that the error doesn't need to be `Send` or `Sync`. /// impl !Send for SuperError {} /// impl !Sync for SuperError {} /// /// fn main() { -/// let error = SuperError { side: SuperErrorSideKick }; +/// let msg = String::from("Huzzah!"); +/// let error = SuperError { side: &msg }; /// let report = Report::new(&error).pretty(true); /// /// println!("{}", report); /// } /// ``` -/// -/// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the -/// wrapped error be `Send`, `Sync`, or `'static`. -/// -/// ```rust -/// # #![feature(error_reporter)] -/// # use std::fmt; -/// # use std::error::{Error, Report}; -/// #[derive(Debug)] -/// struct SuperError<'a> { -/// side: &'a str, -/// } -/// impl<'a> fmt::Display for SuperError<'a> { -/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -/// write!(f, "SuperError is here: {}", self.side) -/// } -/// } -/// impl<'a> Error for SuperError<'a> {} -/// fn main() { -/// let msg = String::from("Huzzah!"); -/// let report = Report::new(SuperError { side: &msg }); -/// println!("{}", report); -/// } -/// ``` + #[unstable(feature = "error_reporter", issue = "90172")] pub struct Report { /// The error being reported. From 32bcb8113f750db36b9590b516a9fc40c0fa99df Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Wed, 27 Oct 2021 13:59:02 -0500 Subject: [PATCH 7/9] Fix broken doctest --- library/std/src/error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 26fa6c38549d3..b45cfa3450684 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -837,8 +837,8 @@ impl dyn Error + Send + Sync { /// impl<'a> Error for SuperError<'a> {} /// /// // Note that the error doesn't need to be `Send` or `Sync`. -/// impl !Send for SuperError {} -/// impl !Sync for SuperError {} +/// impl<'a> !Send for SuperError<'a> {} +/// impl<'a> !Sync for SuperError<'a> {} /// /// fn main() { /// let msg = String::from("Huzzah!"); From 840cb00dbe21b951ec3390dbf1f94fc1cf3e82e1 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Tue, 14 Dec 2021 11:11:49 -0800 Subject: [PATCH 8/9] Update library/std/src/error.rs Co-authored-by: Mara Bos --- library/std/src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index b45cfa3450684..a349d9531ff13 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -809,6 +809,7 @@ impl dyn Error + Send + Sync { } /// An error reporter that exposes the entire error chain for printing. +/// /// It also exposes options for formatting the error chain, either entirely on a single line, /// or in multi-line format with each cause in the error chain on a new line. /// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the From edd65f783f536fc6bb20f54ea2a9460374442e90 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Tue, 14 Dec 2021 11:12:17 -0800 Subject: [PATCH 9/9] Update library/std/src/error.rs Co-authored-by: Mara Bos --- library/std/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index a349d9531ff13..4f2b4a8011bfd 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -956,7 +956,7 @@ where } } -// This type intentionally outputs the same format for `Display` and `Debug`for +// This type intentionally outputs the same format for `Display` and `Debug` for // situations where you unwrap a `Report` or return it from main. #[unstable(feature = "error_reporter", issue = "90172")] impl fmt::Debug for Report