Skip to content

Rollup of 10 pull requests #92826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 47 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
59df6c8
Try commiting again
seanchen1991 Oct 22, 2021
6a59d0e
Have `pretty` and `show_backtrace` accept booleans
seanchen1991 Oct 22, 2021
c6de413
Change `source` field to `error`
seanchen1991 Oct 22, 2021
c0f14cb
Attempt to fix tidy errors
seanchen1991 Oct 27, 2021
aa853bd
Add `rust` annotation to doctest
seanchen1991 Oct 27, 2021
d2f49ee
Format doctest
seanchen1991 Oct 27, 2021
32bcb81
Fix broken doctest
seanchen1991 Oct 27, 2021
1386a15
Update std::error::Report based on feedback
yaahc Dec 14, 2021
689a868
Remove some noise from opaque type errors around associated types
oli-obk Dec 16, 2021
5c46002
Eagerly instantiate opaque types
oli-obk Dec 16, 2021
bdeeb07
Prove obligations to termination instead of ignoring ambiguities.
oli-obk Dec 16, 2021
4420cc3
Update report output and fix examples
yaahc Dec 16, 2021
078b112
add a panicking example
yaahc Dec 16, 2021
9be1cc9
more docs improvements
yaahc Dec 16, 2021
5b3902f
attempt to make Report usable with Box dyn Error and fn main
yaahc Dec 17, 2021
341d65d
Add test case for #86177 and #85718
wesleywiser Dec 20, 2021
ef57f24
[code coverage] Fix missing dead code in modules that are never called
wesleywiser Dec 20, 2021
ebc0d0d
Address review comments
wesleywiser Dec 21, 2021
336c85a
rustdoc: Preserve rendering of macro_rules matchers when possible
dtolnay Dec 27, 2021
544a6bb
Replace &DocCtxt -> TyCtxt in macro matcher rendering
dtolnay Dec 28, 2021
0f8415b
Add a test of rustdoc on macro-generated macro
dtolnay Dec 28, 2021
579e8bc
Make rlib metadata strip works with MIPSr6 architecture
Fearyncess Jan 7, 2022
11f180f
rustc_codegen_ssa: set static lifetime for object::write::Object
Fearyncess Jan 7, 2022
9a337b6
update Cargo.lock and gimli-rs/object for rustc_codegen_ssa
Fearyncess Jan 7, 2022
72cb1bd
silence tidy errors
yaahc Jan 7, 2022
cf36c21
tidy: add `ahash` to permitted dep list
Fearyncess Jan 8, 2022
5ab40c8
Implement `#[rustc_must_implement_one_of]` attribute
WaffleLapkin Dec 21, 2021
e6bc0ac
Add test for misused `#[rustc_must_implement_one_of]`
WaffleLapkin Jan 3, 2022
268ae9a
Move `#[rustc_must_implement_one_of]` tests to fix tidy check
WaffleLapkin Jan 3, 2022
96b2f8a
Apply suggestions from code review
WaffleLapkin Jan 4, 2022
c4471b0
rustc_metadata: Stop passing `CrateMetadataRef` by reference
petrochenkov Dec 24, 2021
f64daff
Fix `#[rustc_must_implement_one_of]`
WaffleLapkin Jan 10, 2022
e9cac4c
Ignore `unused_mod.rs` file in code coverage results
wesleywiser Jan 10, 2022
4ccfa97
Add a test for ungated `#[rustc_must_implement_one_of]`
WaffleLapkin Jan 11, 2022
4193f2d
rustdoc: do not emit tuple variant fields if none are documented
euclio Dec 9, 2021
66f1e32
Update cargo
ehuss Jan 12, 2022
232f4b4
`std::path::absolute`
ChrisDenton Dec 8, 2021
4c95c6e
Rollup merge of #90001 - Fearyncess:master, r=alexcrichton
matthiaskrgr Jan 12, 2022
5d977c1
Rollup merge of #91673 - ChrisDenton:path-absolute, r=Mark-Simulacrum
matthiaskrgr Jan 12, 2022
35b66a7
Rollup merge of #91687 - euclio:tuple-variant-field-section, r=Guilla…
matthiaskrgr Jan 12, 2022
9bcfb54
Rollup merge of #91938 - yaahc:error-reporter, r=m-ou-se
matthiaskrgr Jan 12, 2022
ccfcf42
Rollup merge of #92006 - oli-obk:welcome_opaque_types_into_the_fold, …
matthiaskrgr Jan 12, 2022
219c5d3
Rollup merge of #92142 - wesleywiser:fix_codecoverage_partitioning, r…
matthiaskrgr Jan 12, 2022
faf8d66
Rollup merge of #92164 - WaffleLapkin:rustc_must_implement_one_of_att…
matthiaskrgr Jan 12, 2022
801a3b6
Rollup merge of #92277 - petrochenkov:cmrval2, r=jackh726
matthiaskrgr Jan 12, 2022
770f532
Rollup merge of #92334 - dtolnay:rustdocmatcher, r=camelid,GuillaumeG…
matthiaskrgr Jan 12, 2022
89bf361
Rollup merge of #92807 - ehuss:update-cargo, r=ehuss
matthiaskrgr Jan 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Try commiting again
  • Loading branch information
seanchen1991 committed Oct 22, 2021
commit 59df6c8eb917cba41c15e3366f29ee780c9c74df
245 changes: 244 additions & 1 deletion library/std/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<E> {
source: E,
show_backtrace: bool,
pretty: bool,
}

impl<E> Report<E>
where
E: Error,
{
/// Create a new `Report` from an input error.
#[unstable(feature = "error_reporter", issue = "90172")]
pub fn new(source: E) -> Report<E> {
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(<dyn Error>::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<E> From<E> for Report<E>
where
E: Error,
{
fn from(source: E) -> Self {
Report::new(source)
}
}

#[unstable(feature = "error_reporter", issue = "90172")]
impl<E> fmt::Display for Report<E>
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<E> fmt::Debug for Report<E>
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<D> 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, " ")
}
}
}
}
}