Skip to content

Rollup of 12 pull requests #58415

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

Merged
merged 34 commits into from
Feb 13, 2019
Merged
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5a7cd84
Speed up the fast path for assert_eq! and assert_ne!
dotdash Jan 21, 2019
f841ff4
Stabilize the time_checked_add feature
faern Jan 31, 2019
2f2d495
Simplify lambdas
faern Jan 31, 2019
346dc37
fix str mutating through a ptr derived from &self
RalfJung Feb 5, 2019
113b7f7
allow shorthand syntax for deprecation reason
euclio Feb 4, 2019
13bbba2
remove now-unneeded raw ptr casts
RalfJung Feb 6, 2019
a996f2c
add tracking issue
RalfJung Feb 6, 2019
66c894e
also fix bad use of shared ref in split_at_mut
RalfJung Feb 7, 2019
f06af1f
impl iter_sources() and iter_chain() for dyn Error
haraldh Feb 7, 2019
3a1a704
cleanup: rename node_id_to_type(_opt)
ljedrz Feb 4, 2019
eb669b3
cleanup: remove hir_path_str
ljedrz Feb 7, 2019
aafbf74
Disallow `auto` trait alias syntax.
alexreg Feb 12, 2019
b284c8d
Doc rewording
king6cong Jan 17, 2019
04f425d
Stabilize linker-plugin based LTO.
michaelwoerister Feb 1, 2019
370f1f2
Added tests.
alexreg Feb 12, 2019
8b21a55
use Ubuntu keyserver for CloudABI ports
euclio Feb 12, 2019
3733b32
Add documentation about -Clinker-plugin-lto to rustc book.
michaelwoerister Feb 12, 2019
1431c21
Remove some dead code from libcore
gnzlbg Feb 12, 2019
3216c76
Rename rustc_errors dependency in rust 2018 crates
taiki-e Feb 7, 2019
c360ba2
Cleanup imports
taiki-e Feb 9, 2019
c08b5ca
Fix rebase fail
taiki-e Feb 10, 2019
3a9d171
Fix some rebasing fallout regarding xLTO.
michaelwoerister Feb 12, 2019
734cc3e
Rollup merge of #57693 - king6cong:word, r=Centril
Centril Feb 13, 2019
0ed894a
Rollup merge of #57815 - dotdash:asserts, r=sfackler
Centril Feb 13, 2019
0ab1057
Rollup merge of #58034 - faern:stabilize-time-checked-add, r=alexcric…
Centril Feb 13, 2019
1c1d2e4
Rollup merge of #58057 - michaelwoerister:stabilize-xlto, r=alexcrichton
Centril Feb 13, 2019
81434cb
Rollup merge of #58137 - ljedrz:cleanup_node_id_to_type, r=estebank
Centril Feb 13, 2019
856e411
Rollup merge of #58166 - euclio:deprecation-shorthand, r=petrochenkov
Centril Feb 13, 2019
ecb6503
Rollup merge of #58200 - RalfJung:str-as-mut-ptr, r=SimonSapin
Centril Feb 13, 2019
0bc8f6f
Rollup merge of #58273 - taiki-e:rename-dependency, r=matthewjasper
Centril Feb 13, 2019
5aa260a
Rollup merge of #58289 - haraldh:master, r=sfackler
Centril Feb 13, 2019
a5e869e
Rollup merge of #58387 - alexreg:fix-trait-alias-2, r=centril
Centril Feb 13, 2019
f3c4652
Rollup merge of #58404 - euclio:cloudabi-keyserver, r=alexcrichton
Centril Feb 13, 2019
6562c28
Rollup merge of #58405 - gnzlbg:remove_unused_macros, r=alexcrichton
Centril Feb 13, 2019
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
Prev Previous commit
Next Next commit
impl iter_sources() and iter_chain() for dyn Error
Examples:

```rust
let next_error_type_a = err
    .iter_chain()
    .filter_map(Error::downcast_ref::<ErrorTypeA>)
    .next();
```

```rust
let source_root_error = err.iter_chain().last();
```

Credit for the ErrorIter goes to Tim Diekmann
https://www.reddit.com/r/rust/comments/aj3lpg/is_an_iterator_impl_over_errorsource_possible/
  • Loading branch information
haraldh committed Feb 9, 2019
commit f06af1ff178014dadd62391a4a06e7fff8f2a6a1
152 changes: 152 additions & 0 deletions src/libstd/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,158 @@ impl dyn Error {
Err(self)
}
}

/// Returns an iterator starting with the current error and continuing with
/// recursively calling [`source`].
///
/// # Examples
///
/// ```
/// #![feature(error_iter)]
/// use std::error::Error;
/// use std::fmt;
///
/// #[derive(Debug)]
/// struct A;
///
/// #[derive(Debug)]
/// struct B(Option<Box<dyn Error + 'static>>);
///
/// impl fmt::Display for A {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "A")
/// }
/// }
///
/// impl fmt::Display for B {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "B")
/// }
/// }
///
/// impl Error for A {}
///
/// impl Error for B {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
/// self.0.as_ref().map(|e| e.as_ref())
/// }
/// }
///
/// let b = B(Some(Box::new(A)));
///
/// // let err : Box<Error> = b.into(); // or
/// let err = &b as &(dyn Error);
///
/// let mut iter = err.iter_chain();
///
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
/// assert!(iter.next().is_none());
/// assert!(iter.next().is_none());
/// ```
///
/// [`source`]: trait.Error.html#method.source
#[unstable(feature = "error_iter", issue = "58289")]
#[inline]
pub fn iter_chain(&self) -> ErrorIter {
ErrorIter {
current: Some(self),
}
}

/// Returns an iterator starting with the [`source`] of this error
/// and continuing with recursively calling [`source`].
///
/// # Examples
///
/// ```
/// #![feature(error_iter)]
/// use std::error::Error;
/// use std::fmt;
///
/// #[derive(Debug)]
/// struct A;
///
/// #[derive(Debug)]
/// struct B(Option<Box<dyn Error + 'static>>);
///
/// #[derive(Debug)]
/// struct C(Option<Box<dyn Error + 'static>>);
///
/// impl fmt::Display for A {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "A")
/// }
/// }
///
/// impl fmt::Display for B {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "B")
/// }
/// }
///
/// impl fmt::Display for C {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "C")
/// }
/// }
///
/// impl Error for A {}
///
/// impl Error for B {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
/// self.0.as_ref().map(|e| e.as_ref())
/// }
/// }
///
/// impl Error for C {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
/// self.0.as_ref().map(|e| e.as_ref())
/// }
/// }
///
/// let b = B(Some(Box::new(A)));
/// let c = C(Some(Box::new(b)));
///
/// // let err : Box<Error> = c.into(); // or
/// let err = &c as &(dyn Error);
///
/// let mut iter = err.iter_sources();
///
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
/// assert!(iter.next().is_none());
/// assert!(iter.next().is_none());
/// ```
///
/// [`source`]: trait.Error.html#method.source
#[inline]
#[unstable(feature = "error_iter", issue = "58289")]
pub fn iter_sources(&self) -> ErrorIter {
ErrorIter {
current: self.source(),
}
}
}

/// An iterator over [`Error`]
///
/// [`Error`]: trait.Error.html
#[unstable(feature = "error_iter", issue = "58289")]
#[derive(Copy, Clone, Debug)]
pub struct ErrorIter<'a> {
current: Option<&'a (dyn Error + 'static)>,
}

#[unstable(feature = "error_iter", issue = "58289")]
impl<'a> Iterator for ErrorIter<'a> {
type Item = &'a (dyn Error + 'static);

fn next(&mut self) -> Option<Self::Item> {
let current = self.current;
self.current = self.current.and_then(Error::source);
current
}
}

impl dyn Error + Send {
Expand Down