diff options
| author | bors <bors@rust-lang.org> | 2019-02-13 05:14:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-02-13 05:14:12 +0000 |
| commit | 827a141466e7bb85eb3c030600878a2c606019e9 (patch) | |
| tree | cbbbb0b46cf4a3694316b2462ae2dcf7321468e4 /src/libstd | |
| parent | 0f949c2fcc696d0260a99196d5e5400c59a26a54 (diff) | |
| parent | 6562c2860730aee4497f58b00c298d054ff2e0b7 (diff) | |
| download | rust-827a141466e7bb85eb3c030600878a2c606019e9.tar.gz rust-827a141466e7bb85eb3c030600878a2c606019e9.zip | |
Auto merge of #58415 - Centril:rollup, r=Centril
Rollup of 12 pull requests Successful merges: - #57693 (Doc rewording) - #57815 (Speed up the fast path for assert_eq! and assert_ne!) - #58034 (Stabilize the time_checked_add feature) - #58057 (Stabilize linker-plugin based LTO (aka cross-language LTO)) - #58137 (Cleanup: rename node_id_to_type(_opt)) - #58166 (allow shorthand syntax for deprecation reason) - #58200 (fix str mutating through a ptr derived from &self) - #58273 (Rename rustc_errors dependency in rust 2018 crates) - #58289 (impl iter() for dyn Error) - #58387 (Disallow `auto` trait alias syntax) - #58404 (use Ubuntu keyserver for CloudABI ports) - #58405 (Remove some dead code from libcore) Failed merges: r? @ghost
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/error.rs | 152 | ||||
| -rw-r--r-- | src/libstd/macros.rs | 2 | ||||
| -rw-r--r-- | src/libstd/time.rs | 16 |
3 files changed, 161 insertions, 9 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs index f792ff56179..6348b411a4c 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -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 { diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index dfe3079bb6c..b9204d27f53 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -8,7 +8,7 @@ /// /// This allows a program to terminate immediately and provide feedback /// to the caller of the program. `panic!` should be used when a program reaches -/// an unrecoverable problem. +/// an unrecoverable state. /// /// This macro is the perfect way to assert conditions in example code and in /// tests. `panic!` is closely tied with the `unwrap` method of both [`Option`] diff --git a/src/libstd/time.rs b/src/libstd/time.rs index c258e3f1a55..47a963bcca9 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -245,17 +245,17 @@ impl Instant { /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option<Instant> { - self.0.checked_add_duration(&duration).map(|t| Instant(t)) + self.0.checked_add_duration(&duration).map(Instant) } /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option<Instant> { - self.0.checked_sub_duration(&duration).map(|t| Instant(t)) + self.0.checked_sub_duration(&duration).map(Instant) } } @@ -418,17 +418,17 @@ impl SystemTime { /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> { - self.0.checked_add_duration(&duration).map(|t| SystemTime(t)) + self.0.checked_add_duration(&duration).map(SystemTime) } /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> { - self.0.checked_sub_duration(&duration).map(|t| SystemTime(t)) + self.0.checked_sub_duration(&duration).map(SystemTime) } } |
