summaryrefslogtreecommitdiffstats
path: root/third_party/rust/error-chain/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/error-chain/src')
-rw-r--r--third_party/rust/error-chain/src/backtrace.rs111
-rw-r--r--third_party/rust/error-chain/src/error_chain.rs564
-rw-r--r--third_party/rust/error-chain/src/example_generated.rs38
-rw-r--r--third_party/rust/error-chain/src/impl_error_chain_kind.rs383
-rw-r--r--third_party/rust/error-chain/src/lib.rs824
-rw-r--r--third_party/rust/error-chain/src/quick_main.rs81
6 files changed, 2001 insertions, 0 deletions
diff --git a/third_party/rust/error-chain/src/backtrace.rs b/third_party/rust/error-chain/src/backtrace.rs
new file mode 100644
index 0000000000..14be75ce1b
--- /dev/null
+++ b/third_party/rust/error-chain/src/backtrace.rs
@@ -0,0 +1,111 @@
+pub use self::imp::{Backtrace, InternalBacktrace};
+
+#[cfg(feature = "backtrace")]
+mod imp {
+ extern crate backtrace;
+
+ use std::cell::UnsafeCell;
+ use std::env;
+ use std::fmt;
+ use std::sync::atomic::{AtomicUsize, Ordering};
+ use std::sync::{Arc, Mutex};
+
+ /// Internal representation of a backtrace
+ #[doc(hidden)]
+ #[derive(Clone)]
+ pub struct InternalBacktrace {
+ backtrace: Option<Arc<MaybeResolved>>,
+ }
+
+ struct MaybeResolved {
+ resolved: Mutex<bool>,
+ backtrace: UnsafeCell<Backtrace>,
+ }
+
+ unsafe impl Send for MaybeResolved {}
+ unsafe impl Sync for MaybeResolved {}
+
+ pub use self::backtrace::Backtrace;
+
+ impl InternalBacktrace {
+ /// Returns a backtrace of the current call stack if `RUST_BACKTRACE`
+ /// is set to anything but ``0``, and `None` otherwise. This is used
+ /// in the generated error implementations.
+ #[doc(hidden)]
+ pub fn new() -> InternalBacktrace {
+ static ENABLED: AtomicUsize = AtomicUsize::new(0);
+
+ match ENABLED.load(Ordering::SeqCst) {
+ 0 => {
+ let enabled = match env::var_os("RUST_BACKTRACE") {
+ Some(ref val) if val != "0" => true,
+ _ => false,
+ };
+ ENABLED.store(enabled as usize + 1, Ordering::SeqCst);
+ if !enabled {
+ return InternalBacktrace { backtrace: None };
+ }
+ }
+ 1 => return InternalBacktrace { backtrace: None },
+ _ => {}
+ }
+
+ InternalBacktrace {
+ backtrace: Some(Arc::new(MaybeResolved {
+ resolved: Mutex::new(false),
+ backtrace: UnsafeCell::new(Backtrace::new_unresolved()),
+ })),
+ }
+ }
+
+ /// Acquire the internal backtrace
+ #[doc(hidden)]
+ pub fn as_backtrace(&self) -> Option<&Backtrace> {
+ let bt = match self.backtrace {
+ Some(ref bt) => bt,
+ None => return None,
+ };
+ let mut resolved = bt.resolved.lock().unwrap();
+ unsafe {
+ if !*resolved {
+ (*bt.backtrace.get()).resolve();
+ *resolved = true;
+ }
+ Some(&*bt.backtrace.get())
+ }
+ }
+ }
+
+ impl fmt::Debug for InternalBacktrace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("InternalBacktrace")
+ .field("backtrace", &self.as_backtrace())
+ .finish()
+ }
+ }
+}
+
+#[cfg(not(feature = "backtrace"))]
+mod imp {
+ /// Dummy type used when the `backtrace` feature is disabled.
+ pub type Backtrace = ();
+
+ /// Internal representation of a backtrace
+ #[doc(hidden)]
+ #[derive(Clone, Debug)]
+ pub struct InternalBacktrace {}
+
+ impl InternalBacktrace {
+ /// Returns a new backtrace
+ #[doc(hidden)]
+ pub fn new() -> InternalBacktrace {
+ InternalBacktrace {}
+ }
+
+ /// Returns the internal backtrace
+ #[doc(hidden)]
+ pub fn as_backtrace(&self) -> Option<&Backtrace> {
+ None
+ }
+ }
+}
diff --git a/third_party/rust/error-chain/src/error_chain.rs b/third_party/rust/error-chain/src/error_chain.rs
new file mode 100644
index 0000000000..8382709621
--- /dev/null
+++ b/third_party/rust/error-chain/src/error_chain.rs
@@ -0,0 +1,564 @@
+#[doc(hidden)]
+#[macro_export]
+#[cfg(not(has_error_source))]
+macro_rules! impl_error_chain_cause_or_source {
+ (
+ types {
+ $error_kind_name:ident
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+ ) => {
+ #[allow(unknown_lints, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn cause(&self) -> Option<&::std::error::Error> {
+ match self.1.next_error {
+ Some(ref c) => Some(&**c),
+ None => {
+ match self.0 {
+ $(
+ $(#[$meta_foreign_links])*
+ $error_kind_name::$foreign_link_variant(ref foreign_err) => {
+ foreign_err.cause()
+ }
+ ) *
+ _ => None
+ }
+ }
+ }
+ }
+ };
+}
+
+#[cfg(has_error_source)]
+#[doc(hidden)]
+#[macro_export]
+macro_rules! impl_error_chain_cause_or_source {
+ (
+ types {
+ $error_kind_name:ident
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+ ) => {
+ #[allow(unknown_lints, renamed_and_removed_lints, bare_trait_objects)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn source(&self) -> Option<&(std::error::Error + 'static)> {
+ match self.1.next_error {
+ Some(ref c) => Some(&**c),
+ None => {
+ match self.0 {
+ $(
+ $(#[$meta_foreign_links])*
+ $error_kind_name::$foreign_link_variant(ref foreign_err) => {
+ foreign_err.source()
+ }
+ ) *
+ _ => None
+ }
+ }
+ }
+ }
+ };
+}
+
+/// Conditional usage of deprecated Error::description
+#[doc(hidden)]
+#[cfg(has_error_description_deprecated)]
+#[macro_export(local_inner_macros)]
+macro_rules! call_to_deprecated_description {
+ ($e:ident) => {
+ ""
+ };
+}
+
+#[doc(hidden)]
+#[cfg(not(has_error_description_deprecated))]
+#[macro_export(local_inner_macros)]
+macro_rules! call_to_deprecated_description {
+ ($e:ident) => {
+ ::std::error::Error::description($e)
+ };
+}
+
+/// Prefer to use `error_chain` instead of this macro.
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! impl_error_chain_processed {
+ // Default values for `types`.
+ (
+ types {}
+ $( $rest: tt )*
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+ $( $rest )*
+ }
+ };
+ // With `Result` wrapper.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident,
+ $result_ext_name:ident, $result_name:ident;
+ }
+ $( $rest: tt )*
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ $error_name, $error_kind_name,
+ $result_ext_name;
+ }
+ $( $rest )*
+ }
+ /// Convenient wrapper around `std::Result`.
+ #[allow(unused)]
+ pub type $result_name<T> = ::std::result::Result<T, $error_name>;
+ };
+
+ // With `Msg` variant.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident, $($types:tt)*
+ }
+ links $links:tt
+ foreign_links $foreign_links:tt
+ errors { $($errors:tt)* }
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ $error_name, $error_kind_name, $($types)*
+ }
+ skip_msg_variant
+ links $links
+ foreign_links $foreign_links
+ errors {
+ /// A convenient variant for String.
+ Msg(s: String) {
+ description(&s)
+ display("{}", s)
+ }
+
+ $($errors)*
+ }
+ }
+
+ impl<'a> From<&'a str> for $error_kind_name {
+ fn from(s: &'a str) -> Self {
+ $error_kind_name::Msg(s.into())
+ }
+ }
+
+ impl From<String> for $error_kind_name {
+ fn from(s: String) -> Self {
+ $error_kind_name::Msg(s)
+ }
+ }
+
+ impl<'a> From<&'a str> for $error_name {
+ fn from(s: &'a str) -> Self {
+ Self::from_kind(s.into())
+ }
+ }
+
+ impl From<String> for $error_name {
+ fn from(s: String) -> Self {
+ Self::from_kind(s.into())
+ }
+ }
+ };
+
+ // Without `Result` wrapper or `Msg` variant.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident,
+ $result_ext_name:ident;
+ }
+
+ skip_msg_variant
+
+ links {
+ $( $link_variant:ident ( $link_error_path:path, $link_kind_path:path )
+ $( #[$meta_links:meta] )*; ) *
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+
+ errors {
+ $( $error_chunks:tt ) *
+ }
+
+ ) => {
+ /// The Error type.
+ ///
+ /// This tuple struct is made of two elements:
+ ///
+ /// - an `ErrorKind` which is used to determine the type of the error.
+ /// - An internal `State`, not meant for direct use outside of `error_chain`
+ /// internals, containing:
+ /// - a backtrace, generated when the error is created.
+ /// - an error chain, used for the implementation of `Error::cause()`.
+ #[derive(Debug)]
+ pub struct $error_name(
+ // The members must be `pub` for `links`.
+ /// The kind of the error.
+ pub $error_kind_name,
+ /// Contains the error chain and the backtrace.
+ #[doc(hidden)]
+ pub $crate::State,
+ );
+
+ impl $crate::ChainedError for $error_name {
+ type ErrorKind = $error_kind_name;
+
+ fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
+ $error_name(kind, state)
+ }
+
+ fn from_kind(kind: Self::ErrorKind) -> Self {
+ Self::from_kind(kind)
+ }
+
+ fn with_chain<E, K>(error: E, kind: K)
+ -> Self
+ where E: ::std::error::Error + Send + 'static,
+ K: Into<Self::ErrorKind>
+ {
+ Self::with_chain(error, kind)
+ }
+
+ fn kind(&self) -> &Self::ErrorKind {
+ self.kind()
+ }
+
+ fn iter(&self) -> $crate::Iter {
+ $crate::Iter::new(Some(self))
+ }
+
+ fn chain_err<F, EK>(self, error: F) -> Self
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.chain_err(error)
+ }
+
+ fn backtrace(&self) -> Option<&$crate::Backtrace> {
+ self.backtrace()
+ }
+
+ impl_extract_backtrace!($error_name
+ $error_kind_name
+ $([$link_error_path, $(#[$meta_links])*])*);
+ }
+
+ #[allow(dead_code)]
+ impl $error_name {
+ /// Constructs an error from a kind, and generates a backtrace.
+ pub fn from_kind(kind: $error_kind_name) -> $error_name {
+ $error_name(
+ kind,
+ $crate::State::default(),
+ )
+ }
+
+ /// Constructs a chained error from another error and a kind, and generates a backtrace.
+ pub fn with_chain<E, K>(error: E, kind: K)
+ -> $error_name
+ where E: ::std::error::Error + Send + 'static,
+ K: Into<$error_kind_name>
+ {
+ $error_name::with_boxed_chain(Box::new(error), kind)
+ }
+
+ /// Construct a chained error from another boxed error and a kind, and generates a backtrace
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send>, kind: K)
+ -> $error_name
+ where K: Into<$error_kind_name>
+ {
+ $error_name(
+ kind.into(),
+ $crate::State::new::<$error_name>(error, ),
+ )
+ }
+
+ /// Returns the kind of the error.
+ pub fn kind(&self) -> &$error_kind_name {
+ &self.0
+ }
+
+ /// Iterates over the error chain.
+ pub fn iter(&self) -> $crate::Iter {
+ $crate::ChainedError::iter(self)
+ }
+
+ /// Returns the backtrace associated with this error.
+ pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
+ self.1.backtrace()
+ }
+
+ /// Extends the error chain with a new entry.
+ pub fn chain_err<F, EK>(self, error: F) -> $error_name
+ where F: FnOnce() -> EK, EK: Into<$error_kind_name> {
+ $error_name::with_chain(self, Self::from_kind(error().into()))
+ }
+
+ /// A short description of the error.
+ /// This method is identical to [`Error::description()`](https://doc.rust-lang.org/nightly/std/error/trait.Error.html#tymethod.description)
+ pub fn description(&self) -> &str {
+ self.0.description()
+ }
+ }
+
+ impl ::std::error::Error for $error_name {
+ #[cfg(not(has_error_description_deprecated))]
+ fn description(&self) -> &str {
+ self.description()
+ }
+
+ impl_error_chain_cause_or_source!{
+ types {
+ $error_kind_name
+ }
+ foreign_links {
+ $( $foreign_link_variant ( $foreign_link_error_path )
+ $( #[$meta_foreign_links] )*; )*
+ }
+ }
+ }
+
+ impl ::std::fmt::Display for $error_name {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ ::std::fmt::Display::fmt(&self.0, f)
+ }
+ }
+
+ $(
+ $(#[$meta_links])*
+ impl From<$link_error_path> for $error_name {
+ fn from(e: $link_error_path) -> Self {
+ $error_name(
+ $error_kind_name::$link_variant(e.0),
+ e.1,
+ )
+ }
+ }
+ ) *
+
+ $(
+ $(#[$meta_foreign_links])*
+ impl From<$foreign_link_error_path> for $error_name {
+ fn from(e: $foreign_link_error_path) -> Self {
+ $error_name::from_kind(
+ $error_kind_name::$foreign_link_variant(e)
+ )
+ }
+ }
+ ) *
+
+ impl From<$error_kind_name> for $error_name {
+ fn from(e: $error_kind_name) -> Self {
+ $error_name::from_kind(e)
+ }
+ }
+
+ // The ErrorKind type
+ // --------------
+
+ impl_error_chain_kind! {
+ /// The kind of an error.
+ #[derive(Debug)]
+ pub enum $error_kind_name {
+ $(
+ $(#[$meta_links])*
+ $link_variant(e: $link_kind_path) {
+ description(e.description())
+ display("{}", e)
+ }
+ ) *
+
+ $(
+ $(#[$meta_foreign_links])*
+ $foreign_link_variant(err: $foreign_link_error_path) {
+ description(call_to_deprecated_description!(err))
+ display("{}", err)
+ }
+ ) *
+
+ $($error_chunks)*
+ }
+ }
+
+ $(
+ $(#[$meta_links])*
+ impl From<$link_kind_path> for $error_kind_name {
+ fn from(e: $link_kind_path) -> Self {
+ $error_kind_name::$link_variant(e)
+ }
+ }
+ ) *
+
+ impl From<$error_name> for $error_kind_name {
+ fn from(e: $error_name) -> Self {
+ e.0
+ }
+ }
+
+ // The ResultExt trait defines the `chain_err` method.
+
+ /// Additional methods for `Result`, for easy interaction with this crate.
+ pub trait $result_ext_name<T> {
+ /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
+ /// which returns *some type that can be converted to `ErrorKind`*, boxes
+ /// the original error to store as the cause, then returns a new error
+ /// containing the original error.
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name>;
+ }
+
+ impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.map_err(move |e| {
+ let state = $crate::State::new::<$error_name>(Box::new(e), );
+ $crate::ChainedError::new(callback().into(), state)
+ })
+ }
+ }
+
+ impl<T> $result_ext_name<T> for ::std::option::Option<T> {
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.ok_or_else(move || {
+ $crate::ChainedError::from_kind(callback().into())
+ })
+ }
+ }
+
+
+ };
+}
+
+/// Internal macro used for reordering of the fields.
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! error_chain_processing {
+ (
+ ({}, $($rest:tt)*)
+ types $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, {}, $($rest:tt)*)
+ links $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, {}, $($rest:tt)*)
+ foreign_links $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, $c:tt, {}, $($rest:tt)*)
+ errors $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $c, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, $c:tt, $d:tt, {}, $($rest:tt)*)
+ skip_msg_variant
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $c, $d, {skip_msg_variant}, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ ( ($a:tt, $b:tt, $c:tt, $d:tt, {$($e:tt)*},) ) => {
+ impl_error_chain_processed! {
+ types $a
+ $($e)*
+ links $b
+ foreign_links $c
+ errors $d
+ }
+ };
+}
+
+/// Macro for generating error types and traits. See crate level documentation for details.
+#[macro_export(local_inner_macros)]
+macro_rules! error_chain {
+ ( $($args:tt)* ) => {
+ error_chain_processing! {
+ ({}, {}, {}, {}, {},)
+ $($args)*
+ }
+ };
+}
+
+/// Macro used to manage the `backtrace` feature.
+///
+/// See
+/// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
+/// for more details.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! impl_extract_backtrace {
+ ($error_name: ident
+ $error_kind_name: ident
+ $([$link_error_path: path, $(#[$meta_links: meta])*])*) => {
+ #[allow(unknown_lints, renamed_and_removed_lints, bare_trait_objects)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
+ -> Option<$crate::InternalBacktrace> {
+ if let Some(e) = e.downcast_ref::<$error_name>() {
+ return Some(e.1.backtrace.clone());
+ }
+ $(
+ $( #[$meta_links] )*
+ {
+ if let Some(e) = e.downcast_ref::<$link_error_path>() {
+ return Some(e.1.backtrace.clone());
+ }
+ }
+ ) *
+ None
+ }
+ }
+}
diff --git a/third_party/rust/error-chain/src/example_generated.rs b/third_party/rust/error-chain/src/example_generated.rs
new file mode 100644
index 0000000000..c0f4d23014
--- /dev/null
+++ b/third_party/rust/error-chain/src/example_generated.rs
@@ -0,0 +1,38 @@
+//! These modules show an example of code generated by the macro. **IT MUST NOT BE
+//! USED OUTSIDE THIS CRATE**.
+//!
+//! This is the basic error structure. You can see that `ErrorKind`
+//! has been populated in a variety of ways. All `ErrorKind`s get a
+//! `Msg` variant for basic errors. When strings are converted to
+//! `ErrorKind`s they become `ErrorKind::Msg`. The "links" defined in
+//! the macro are expanded to the `Inner` variant, and the
+//! "foreign links" to the `Io` variant.
+//!
+//! Both types come with a variety of `From` conversions as well:
+//! `Error` can be created from `ErrorKind`, `&str` and `String`,
+//! and the `links` and `foreign_links` error types. `ErrorKind`
+//! can be created from the corresponding `ErrorKind`s of the link
+//! types, as well as from `&str` and `String`.
+//!
+//! `into()` and `From::from` are used heavily to massage types into
+//! the right shape. Which one to use in any specific case depends on
+//! the influence of type inference, but there are some patterns that
+//! arise frequently.
+
+/// Another code generated by the macro.
+pub mod inner {
+ error_chain! {}
+}
+
+error_chain! {
+ links {
+ Inner(inner::Error, inner::ErrorKind) #[doc = "Link to another `ErrorChain`."];
+ }
+ foreign_links {
+ Io(::std::io::Error) #[doc = "Link to a `std::io::Error` type."];
+ }
+ errors {
+ #[doc = "A custom error kind."]
+ Custom
+ }
+}
diff --git a/third_party/rust/error-chain/src/impl_error_chain_kind.rs b/third_party/rust/error-chain/src/impl_error_chain_kind.rs
new file mode 100644
index 0000000000..4acf8435b2
--- /dev/null
+++ b/third_party/rust/error-chain/src/impl_error_chain_kind.rs
@@ -0,0 +1,383 @@
+/// From https://github.com/tailhook/quick-error
+/// Changes:
+/// - replace `impl Error` by `impl Item::description`
+/// - $imeta
+
+/// Because of the `#[macro_export(local_inner_macros)]` usage on `impl_error_chain_kind` that macro
+/// will only look inside this crate for macros to invoke. So using `stringify` or `write` from
+/// the standard library will fail. Thus we here create simple wrappers for them that are not
+/// exported as `local_inner_macros`, and thus they can in turn use the standard library macros.
+#[macro_export]
+macro_rules! stringify_internal {
+ ($($t:tt)*) => { stringify!($($t)*) }
+}
+
+/// Macro used interally for output expanding an expression
+#[macro_export]
+macro_rules! write_internal {
+ ($dst:expr, $($arg:tt)*) => (write!($dst, $($arg)*))
+}
+
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! impl_error_chain_kind {
+ ( $(#[$meta:meta])*
+ pub enum $name:ident { $($chunks:tt)* }
+ ) => {
+ impl_error_chain_kind!(SORT [pub enum $name $(#[$meta])* ]
+ items [] buf []
+ queue [ $($chunks)* ]);
+ };
+ // Queue is empty, can do the work
+ (SORT [pub enum $name:ident $( #[$meta:meta] )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [ ]
+ queue [ ]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
+ body []
+ queue [$($( #[$imeta] )*
+ => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+ );
+ impl_error_chain_kind!(IMPLEMENTATIONS $name {$(
+ $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+ )*});
+ $(
+ impl_error_chain_kind!(ERROR_CHECK $imode $($ifuncs)*);
+ )*
+ };
+ // Add meta to buffer
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*]
+ queue [ #[$qmeta:meta] $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* #[$qmeta] ]
+ queue [$( $tail )*]);
+ };
+ // Add ident to buffer
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*]
+ queue [ $qitem:ident $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])*
+ => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$(#[$bmeta])* => $qitem : UNIT [ ] ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on meta after ident
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ #[$qmeta:meta] $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ enum [$(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ #[$qmeta] ]
+ queue [$( $tail )*]);
+ };
+ // Add tuple enum-variant
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]
+ );
+ };
+ // Add struct enum-variant - e.g. { descr: &'static str }
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]);
+ };
+ // Add struct enum-variant, with excess comma - e.g. { descr: &'static str, }
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]);
+ };
+ // Add braces and flush always on braces
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ {$( $qfuncs:tt )*} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ]
+ buf [ ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on double ident
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ $qitem:ident $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ => $qitem : UNIT [ ] ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on end
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ ]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ ]
+ queue [ ]);
+ };
+ // Public enum (Queue Empty)
+ (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [ ]
+ ) => {
+ $(#[$meta])*
+ pub enum $name {
+ $(
+ $(#[$imeta])*
+ $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*,
+ )*
+
+ #[doc(hidden)]
+ __Nonexhaustive {}
+ }
+ };
+ // Unit variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: UNIT [ ] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem () {} ]
+ queue [ $($queue)* ]
+ );
+ };
+ // Tuple variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem (($( $qtyp ),+)) {} ]
+ queue [ $($queue)* ]
+ );
+ };
+ // Struct variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ]
+ queue [ $($queue)* ]
+ );
+ };
+ (IMPLEMENTATIONS
+ $name:ident {$(
+ $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
+ )*}
+ ) => {
+ #[allow(unknown_lints, unused, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ impl ::std::fmt::Display for $name {
+ fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
+ -> ::std::fmt::Result
+ {
+ match *self {
+ $(
+ $(#[$imeta])*
+ impl_error_chain_kind!(ITEM_PATTERN
+ $name $item: $imode [$( ref $var ),*]
+ ) => {
+ let display_fn = impl_error_chain_kind!(FIND_DISPLAY_IMPL
+ $name $item: $imode
+ {$( $funcs )*});
+
+ display_fn(self, fmt)
+ }
+ )*
+
+ _ => Ok(())
+ }
+ }
+ }
+ #[allow(unknown_lints, unused, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ impl $name {
+ /// A string describing the error kind.
+ pub fn description(&self) -> &str {
+ match *self {
+ $(
+ $(#[$imeta])*
+ impl_error_chain_kind!(ITEM_PATTERN
+ $name $item: $imode [$( ref $var ),*]
+ ) => {
+ impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
+ $item: $imode self fmt [$( $var ),*]
+ {$( $funcs )*})
+ }
+ )*
+
+ _ => "",
+ }
+ }
+ }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
+ ) => {
+ |impl_error_chain_kind!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| {
+ write_internal!(f, $( $exprs )*)
+ }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($pattern:expr) $( $tail:tt )*}
+ ) => {
+ |_, f: &mut ::std::fmt::Formatter| { write_internal!(f, $pattern) }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
+ ) => {
+ |_, f: &mut ::std::fmt::Formatter| { write_internal!(f, $pattern, $( $exprs )*) }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { $t:tt $( $tail:tt )*}
+ ) => {
+ impl_error_chain_kind!(FIND_DISPLAY_IMPL
+ $name $item: $imode
+ {$( $tail )*})
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { }
+ ) => {
+ |self_: &$name, f: &mut ::std::fmt::Formatter| {
+ write_internal!(f, "{}", self_.description())
+ }
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { description($expr:expr) $( $tail:tt )*}
+ ) => {
+ $expr
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { $t:tt $( $tail:tt )*}
+ ) => {
+ impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
+ $item: $imode $me $fmt [$( $var ),*]
+ {$( $tail )*})
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { }
+ ) => {
+ stringify_internal!($item)
+ };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT
+ ) => { };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE
+ [$( $typ:ty ),*]
+ ) => {
+ ($( $typ ),*)
+ };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT
+ [$( $var:ident: $typ:ty ),*]
+ ) => {
+ {$( $var:$typ ),*}
+ };
+ (ITEM_PATTERN $name:ident $item:ident: UNIT []
+ ) => {
+ $name::$item
+ };
+ (ITEM_PATTERN $name:ident $item:ident: TUPLE
+ [$( ref $var:ident ),*]
+ ) => {
+ $name::$item ($( ref $var ),*)
+ };
+ (ITEM_PATTERN $name:ident $item:ident: STRUCT
+ [$( ref $var:ident ),*]
+ ) => {
+ $name::$item {$( ref $var ),*}
+ };
+ // This one should match all allowed sequences in "funcs" but not match
+ // anything else.
+ // This is to contrast FIND_* clauses which just find stuff they need and
+ // skip everything else completely
+ (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt ) => {};
+ (ERROR_CHECK_COMMA $imode:tt , $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
+ (ERROR_CHECK_COMMA $imode:tt $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
+ // Utility functions
+ (IDENT $ident:ident) => { $ident }
+}
diff --git a/third_party/rust/error-chain/src/lib.rs b/third_party/rust/error-chain/src/lib.rs
new file mode 100644
index 0000000000..43d2d5f479
--- /dev/null
+++ b/third_party/rust/error-chain/src/lib.rs
@@ -0,0 +1,824 @@
+#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/error-chain/0.12.4")]
+
+//! A library for consistent and reliable error handling
+//!
+//! error-chain makes it easy to take full advantage of Rust's
+//! powerful error handling features without the overhead of
+//! maintaining boilerplate error types and conversions. It implements
+//! an opinionated strategy for defining your own error types, as well
+//! as conversions from others' error types.
+//!
+//! ## Quick start
+//!
+//! If you just want to set up your new project with error-chain,
+//! follow the [quickstart.rs] template, and read this [intro]
+//! to error-chain.
+//!
+//! [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
+//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+//!
+//! ## Why error chain?
+//!
+//! * error-chain is easy to configure. Handle errors robustly with minimal
+//! effort.
+//! * Basic error handling requires no maintenance of custom error types
+//! nor the [`From`] conversions that make `?` work.
+//! * error-chain scales from simple error handling strategies to more
+//! rigorous. Return formatted strings for simple errors, only
+//! introducing error variants and their strong typing as needed for
+//! advanced error recovery.
+//! * error-chain makes it trivial to correctly manage the [cause] of
+//! the errors generated by your own code. This is the "chaining"
+//! in "error-chain".
+//!
+//! [cause]: https://doc.rust-lang.org/std/error/trait.Error.html#method.cause
+//!
+//! ## Principles of error-chain
+//!
+//! error-chain is based on the following principles:
+//!
+//! * No error should ever be discarded. This library primarily
+//! makes it easy to "chain" errors with the [`chain_err`] method.
+//! * Introducing new errors is trivial. Simple errors can be introduced
+//! at the error site with just a string.
+//! * Handling errors is possible with pattern matching.
+//! * Conversions between error types are done in an automatic and
+//! consistent way - [`From`] conversion behavior is never specified
+//! explicitly.
+//! * Errors implement [`Send`].
+//! * Errors can carry backtraces.
+//!
+//! Similar to other libraries like [error-type] and [quick-error],
+//! this library introduces the error chaining mechanism originally
+//! employed by Cargo. The [`error_chain!`] macro declares the types
+//! and implementation boilerplate necessary for fulfilling a
+//! particular error-handling strategy. Most importantly it defines a
+//! custom error type (called [`Error`] by convention) and the [`From`]
+//! conversions that let the `?` operator work.
+//!
+//! This library differs in a few ways from previous error libs:
+//!
+//! * Instead of defining the custom [`Error`] type as an enum, it is a
+//! struct containing an [`ErrorKind`][] (which defines the
+//! [`description`] and [`display_chain`] methods for the error), an opaque,
+//! optional, boxed [`std::error::Error`]` + `[`Send`]` + 'static` object
+//! (which defines the [`cause`], and establishes the links in the
+//! error chain), and a [`Backtrace`].
+//! * The macro also defines a [`ResultExt`] trait that defines a
+//! [`chain_err`] method. This method on all [`std::error::Error`]` + `[`Send`]` + 'static`
+//! types extends the error chain by boxing the current
+//! error into an opaque object and putting it inside a new concrete
+//! error.
+//! * It provides automatic [`From`] conversions between other error types
+//! defined by the [`error_chain!`] that preserve type information,
+//! and facilitate seamless error composition and matching of composed
+//! errors.
+//! * It provides automatic [`From`] conversions between any other error
+//! type that hides the type of the other error in the [`cause`] box.
+//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
+//! the earliest opportunity and propagates it down the stack through
+//! [`From`] and [`ResultExt`] conversions.
+//!
+//! To accomplish its goals it makes some tradeoffs:
+//!
+//! * The split between the [`Error`] and [`ErrorKind`] types can make it
+//! slightly more cumbersome to instantiate new (unchained) errors,
+//! requiring an [`Into`] or [`From`] conversion; as well as slightly
+//! more cumbersome to match on errors with another layer of types
+//! to match.
+//! * Because the error type contains [`std::error::Error`]` + `[`Send`]` + 'static` objects,
+//! it can't implement [`PartialEq`] for easy comparisons.
+//!
+//! ## Declaring error types
+//!
+//! Generally, you define one family of error types per crate, though
+//! it's also perfectly fine to define error types on a finer-grained
+//! basis, such as per module.
+//!
+//! Assuming you are using crate-level error types, typically you will
+//! define an `errors` module and inside it call [`error_chain!`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod other_error {
+//! error_chain! {}
+//! }
+//!
+//! error_chain! {
+//! // The type defined for this error. These are the conventional
+//! // and recommended names, but they can be arbitrarily chosen.
+//! //
+//! // It is also possible to leave this section out entirely, or
+//! // leave it empty, and these names will be used automatically.
+//! types {
+//! Error, ErrorKind, ResultExt, Result;
+//! }
+//!
+//! // Without the `Result` wrapper:
+//! //
+//! // types {
+//! // Error, ErrorKind, ResultExt;
+//! // }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error chains. In this case, it will e.g. generate an
+//! // `ErrorKind` variant called `Another` which in turn contains
+//! // the `other_error::ErrorKind`, with conversions from
+//! // `other_error::Error`.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! links {
+//! Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
+//! }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error types not defined by the `error_chain!`. These will be
+//! // wrapped in a new error with, in the first case, the
+//! // `ErrorKind::Fmt` variant. The description and cause will
+//! // forward to the description and cause of the original error.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! foreign_links {
+//! Fmt(::std::fmt::Error);
+//! Io(::std::io::Error) #[cfg(unix)];
+//! }
+//!
+//! // Define additional `ErrorKind` variants. Define custom responses with the
+//! // `description` and `display` calls.
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//!
+//! // You can also add commas after description/display.
+//! // This may work better with some editor auto-indentation modes:
+//! UnknownToolchainVersion(v: String) {
+//! description("unknown toolchain version"), // note the ,
+//! display("unknown toolchain version: '{}'", v), // trailing comma is allowed
+//! }
+//! }
+//!
+//! // If this annotation is left off, a variant `Msg(s: String)` will be added, and `From`
+//! // impls will be provided for `String` and `&str`
+//! skip_msg_variant
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! Each section, `types`, `links`, `foreign_links`, and `errors` may
+//! be omitted if it is empty.
+//!
+//! This populates the module with a number of definitions,
+//! the most important of which are the [`Error`] type
+//! and the [`ErrorKind`] type. An example of generated code can be found in the
+//! [example_generated](example_generated/index.html) module.
+//!
+//! ## Returning new errors
+//!
+//! Introducing new error chains, with a string message:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! fn foo() -> Result<()> {
+//! Err("foo error!".into())
+//! }
+//! ```
+//!
+//! Introducing new error chains, with an [`ErrorKind`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! error_chain! {
+//! errors { FooError }
+//! }
+//!
+//! fn foo() -> Result<()> {
+//! Err(ErrorKind::FooError.into())
+//! }
+//! ```
+//!
+//! Note that the return type is the typedef [`Result`], which is
+//! defined by the macro as `pub type Result<T> =
+//! ::std::result::Result<T, Error>`. Note that in both cases
+//! [`.into()`] is called to convert a type into the [`Error`] type; both
+//! strings and [`ErrorKind`] have [`From`] conversions to turn them into
+//! [`Error`].
+//!
+//! When the error is emitted behind the `?` operator, the explicit conversion
+//! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
+//! So the below is equivalent to the previous:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! Ok(Err(ErrorKind::FooError)?)
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! Ok(Err("bogus!")?)
+//! }
+//! ```
+//!
+//! ## The `bail!` macro
+//!
+//! The above method of introducing new errors works but is a little
+//! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
+//! with conversions done automatically.
+//!
+//! With [`bail!`] the previous examples look like:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! if true {
+//! bail!(ErrorKind::FooError);
+//! } else {
+//! Ok(())
+//! }
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! if true {
+//! bail!("bogus!");
+//! } else {
+//! Ok(())
+//! }
+//! }
+//! ```
+//!
+//! ## Chaining errors
+//! error-chain supports extending an error chain by appending new errors.
+//! This can be done on a Result or on an existing Error.
+//!
+//! To extend the error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! [`chain_err`] can be called on any [`Result`] type where the contained
+//! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
+//! the [`Result`] type's corresponding [`ResultExt`] trait is in scope. If
+//! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
+//! which returns *some type that can be converted to [`ErrorKind`]*,
+//! boxes the original error to store as the cause, then returns a new
+//! error containing the original error.
+//!
+//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
+//! the same signature and produces the same outcome as being called on a
+//! [`Result`] matching the properties described above. This is most useful when
+//! partially handling errors using the [`map_err`] function.
+//!
+//! To chain an error directly, use [`with_chain`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> =
+//! do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ## Linking errors
+//!
+//! To convert an error from another error chain to this error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # mod other { error_chain! {} }
+//! error_chain! {
+//! links {
+//! OtherError(other::Error, other::ErrorKind);
+//! }
+//! }
+//!
+//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
+//!
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
+//! types of all linked error chains. Linked errors do not introduce a new
+//! cause to the error chain.
+//!
+//! ## Matching errors
+//!
+//! error-chain error variants are matched with simple patterns.
+//! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
+//! making dispatching on error kinds relatively compact:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! match Error::from("error!") {
+//! Error(ErrorKind::InvalidToolchainName(_), _) => { }
+//! Error(ErrorKind::Msg(_), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! Chained errors are also matched with (relatively) compact syntax
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod utils {
+//! error_chain! {
+//! errors {
+//! BadStuff {
+//! description("bad stuff")
+//! }
+//! }
+//! }
+//! }
+//!
+//! mod app {
+//! error_chain! {
+//! links {
+//! Utils(::utils::Error, ::utils::ErrorKind);
+//! }
+//! }
+//! }
+//!
+//!
+//! # fn main() {
+//! match app::Error::from("error!") {
+//! app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! ## Inspecting errors
+//!
+//! An error-chain error contains information about the error itself, a backtrace, and the chain
+//! of causing errors. For reporting purposes, this information can be accessed as follows.
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! use error_chain::ChainedError; // for e.display_chain()
+//!
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! # fn main() {
+//! // Generate an example error to inspect:
+//! let e = "xyzzy".parse::<i32>()
+//! .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
+//! .unwrap_err();
+//!
+//! // Get the brief description of the error:
+//! assert_eq!(e.description(), "invalid toolchain name");
+//!
+//! // Get the display version of the error:
+//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
+//!
+//! // Get the full cause and backtrace:
+//! println!("{}", e.display_chain().to_string());
+//! // Error: invalid toolchain name: 'xyzzy'
+//! // Caused by: invalid digit found in string
+//! // stack backtrace:
+//! // 0: 0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
+//! // at src/backtrace/libunwind.rs:53
+//! // - backtrace::backtrace::trace<closure>
+//! // at src/backtrace/mod.rs:42
+//! // 1: 0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
+//! // at out/capture.rs:79
+//! // [..]
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
+//!
+//! ## Foreign links
+//!
+//! Errors that do not conform to the same conventions as this library
+//! can still be included in the error chain. They are considered "foreign
+//! errors", and are declared using the `foreign_links` block of the
+//! [`error_chain!`] macro. [`Error`]s are automatically created from
+//! foreign errors by the `?` operator.
+//!
+//! Foreign links and regular links have one crucial difference:
+//! [`From`] conversions for regular links *do not introduce a new error
+//! into the error chain*, while conversions for foreign links *always
+//! introduce a new error into the error chain*. So for the example
+//! above all errors deriving from the [`std::fmt::Error`] type will be
+//! presented to the user as a new [`ErrorKind`] variant, and the
+//! cause will be the original [`std::fmt::Error`] error. In contrast, when
+//! `other_error::Error` is converted to `Error` the two `ErrorKind`s
+//! are converted between each other to create a new `Error` but the
+//! old error is discarded; there is no "cause" created from the
+//! original error.
+//!
+//! ## Backtraces
+//!
+//! If the `RUST_BACKTRACE` environment variable is set to anything
+//! but ``0``, the earliest non-foreign error to be generated creates
+//! a single backtrace, which is passed through all [`From`] conversions
+//! and [`chain_err`] invocations of compatible types. To read the
+//! backtrace just call the [`backtrace`] method.
+//!
+//! Backtrace generation can be disabled by turning off the `backtrace` feature.
+//!
+//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
+//! on directly. For example, to only see the files and line numbers of code
+//! within your own project.
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate error_chain;
+//! # mod errors {
+//! # error_chain! {
+//! # foreign_links {
+//! # Io(::std::io::Error);
+//! # }
+//! # }
+//! # }
+//! # use errors::*;
+//! # #[cfg(feature="backtrace")]
+//! # fn main() {
+//! if let Err(ref e) = open_file() {
+//! if let Some(backtrace) = e.backtrace() {
+//! let frames = backtrace.frames();
+//! for frame in frames.iter() {
+//! for symbol in frame.symbols().iter() {
+//! if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
+//! if file.display().to_string()[0..3] == "src".to_string(){
+//! println!("{}:{}", file.display().to_string(), lineno);
+//! }
+//! }
+//! }
+//! }
+//! }
+//! };
+//! # }
+//! # #[cfg(not(feature="backtrace"))]
+//! # fn main() { }
+//!
+//! fn open_file() -> Result<()> {
+//! std::fs::File::open("does_not_exist")?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## Iteration
+//!
+//! The [`iter`] method returns an iterator over the chain of error boxes.
+//!
+//! [error-type]: https://github.com/DanielKeep/rust-error-type
+//! [quick-error]: https://github.com/tailhook/quick-error
+
+//! [`display_chain`]: trait.ChainedError.html#method.display_chain
+//! [`error_chain!`]: macro.error_chain.html
+//! [`bail!`]: macro.bail.html
+//! [`Backtrace`]: struct.Backtrace.html
+
+//! [`Error`]: example_generated/struct.Error.html
+//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
+//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
+//! [`cause`]: example_generated/struct.Error.html#method.cause
+//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
+//! [`iter`]: example_generated/struct.Error.html#method.iter
+//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
+//! [`description`]: example_generated/enum.ErrorKind.html#method.description
+//! [`Result`]: example_generated/type.Result.html
+//! [`ResultExt`]: example_generated/trait.ResultExt.html
+//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
+
+//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
+//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
+//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
+//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
+//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
+//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
+//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
+//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
+//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
+
+use std::error;
+use std::fmt;
+use std::iter::Iterator;
+
+#[macro_use]
+mod impl_error_chain_kind;
+#[macro_use]
+mod error_chain;
+#[macro_use]
+mod quick_main;
+pub use quick_main::ExitCode;
+mod backtrace;
+#[cfg(feature = "example_generated")]
+pub mod example_generated;
+pub use backtrace::Backtrace;
+#[doc(hidden)]
+pub use backtrace::InternalBacktrace;
+
+#[derive(Debug)]
+#[allow(unknown_lints, bare_trait_objects)]
+/// Iterator over the error chain using the `Error::cause()` method.
+pub struct Iter<'a>(Option<&'a error::Error>);
+
+impl<'a> Iter<'a> {
+ /// Returns a new iterator over the error chain using `Error::cause()`.
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
+ Iter(err)
+ }
+}
+
+#[allow(unknown_lints, bare_trait_objects)]
+impl<'a> Iterator for Iter<'a> {
+ type Item = &'a error::Error;
+
+ fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
+ match self.0.take() {
+ Some(e) => {
+ self.0 = match () {
+ #[cfg(not(has_error_source))]
+ () => e.cause(),
+ #[cfg(has_error_source)]
+ () => e.source(),
+ };
+ Some(e)
+ }
+ None => None,
+ }
+ }
+}
+
+/// This trait is implemented on all the errors generated by the `error_chain`
+/// macro.
+pub trait ChainedError: error::Error + Send + 'static {
+ /// Associated kind type.
+ type ErrorKind;
+
+ /// Constructs an error from a kind, and generates a backtrace.
+ fn from_kind(kind: Self::ErrorKind) -> Self
+ where
+ Self: Sized;
+
+ /// Constructs a chained error from another error and a kind, and generates a backtrace.
+ fn with_chain<E, K>(error: E, kind: K) -> Self
+ where
+ Self: Sized,
+ E: ::std::error::Error + Send + 'static,
+ K: Into<Self::ErrorKind>;
+
+ /// Returns the kind of the error.
+ fn kind(&self) -> &Self::ErrorKind;
+
+ /// Iterates over the error chain.
+ fn iter(&self) -> Iter;
+
+ /// Returns the backtrace associated with this error.
+ fn backtrace(&self) -> Option<&Backtrace>;
+
+ /// Returns an object which implements `Display` for printing the full
+ /// context of this error.
+ ///
+ /// The full cause chain and backtrace, if present, will be printed.
+ fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
+ DisplayChain(self)
+ }
+
+ /// Extends the error chain with a new entry.
+ fn chain_err<F, EK>(self, error: F) -> Self
+ where
+ F: FnOnce() -> EK,
+ EK: Into<Self::ErrorKind>;
+
+ /// Creates an error from its parts.
+ #[doc(hidden)]
+ fn new(kind: Self::ErrorKind, state: State) -> Self
+ where
+ Self: Sized;
+
+ /// Returns the first known backtrace, either from its State or from one
+ /// of the errors from `foreign_links`.
+ #[doc(hidden)]
+ #[allow(unknown_lints, bare_trait_objects)]
+ fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
+ where
+ Self: Sized;
+}
+
+/// A struct which formats an error for output.
+#[derive(Debug)]
+pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
+
+impl<'a, T> fmt::Display for DisplayChain<'a, T>
+where
+ T: ChainedError,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ writeln!(fmt, "Error: {}", self.0)?;
+
+ for e in self.0.iter().skip(1) {
+ writeln!(fmt, "Caused by: {}", e)?;
+ }
+
+ if let Some(backtrace) = ChainedError::backtrace(self.0) {
+ writeln!(fmt, "{:?}", backtrace)?;
+ }
+
+ Ok(())
+ }
+}
+
+/// Common state between errors.
+#[derive(Debug)]
+#[doc(hidden)]
+#[allow(unknown_lints, bare_trait_objects)]
+pub struct State {
+ /// Next error in the error chain.
+ pub next_error: Option<Box<error::Error + Send>>,
+ /// Backtrace for the current error.
+ pub backtrace: InternalBacktrace,
+}
+
+impl Default for State {
+ fn default() -> State {
+ State {
+ next_error: None,
+ backtrace: InternalBacktrace::new(),
+ }
+ }
+}
+
+impl State {
+ /// Creates a new State type
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
+ let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
+ State {
+ next_error: Some(e),
+ backtrace: backtrace,
+ }
+ }
+
+ /// Returns the inner backtrace if present.
+ pub fn backtrace(&self) -> Option<&Backtrace> {
+ self.backtrace.as_backtrace()
+ }
+}
+
+/// Exits a function early with an error
+///
+/// The `bail!` macro provides an easy way to exit a function.
+/// `bail!(expr)` is equivalent to writing.
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let expr = "";
+/// return Err(expr.into());
+/// # }
+/// ```
+///
+/// And as shorthand it takes a formatting string a la `println!`:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let n = 0;
+/// bail!("bad number: {}", n);
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// Bailing on a custom error:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! {
+/// errors { FooError }
+/// }
+///
+/// fn foo() -> Result<()> {
+/// if bad_condition() {
+/// bail!(ErrorKind::FooError);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> bool { true }
+/// ```
+///
+/// Bailing on a formatted string:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! { }
+///
+/// fn foo() -> Result<()> {
+/// if let Some(bad_num) = bad_condition() {
+/// bail!("so bad: {}", bad_num);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> Option<i8> { None }
+/// ```
+#[macro_export]
+macro_rules! bail {
+ ($e:expr) => {
+ return Err($e.into());
+ };
+ ($fmt:expr, $($arg:tt)+) => {
+ return Err(format!($fmt, $($arg)+).into());
+ };
+}
+
+/// Exits a function early with an error if the condition is not satisfied
+///
+/// The `ensure!` macro is a convenience helper that provides a way to exit
+/// a function with an error if the given condition fails.
+///
+/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let errcode = 0u8;
+/// # let condition = true;
+/// if !condition {
+/// bail!("error code: {}", errcode);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// See documentation for `bail!` macro for further details.
+#[macro_export(local_inner_macros)]
+macro_rules! ensure {
+ ($cond:expr, $e:expr) => {
+ if !($cond) {
+ bail!($e);
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)+) => {
+ if !($cond) {
+ bail!($fmt, $($arg)+);
+ }
+ };
+}
+
+#[doc(hidden)]
+pub mod mock {
+ error_chain! {}
+}
diff --git a/third_party/rust/error-chain/src/quick_main.rs b/third_party/rust/error-chain/src/quick_main.rs
new file mode 100644
index 0000000000..a6f093d2b3
--- /dev/null
+++ b/third_party/rust/error-chain/src/quick_main.rs
@@ -0,0 +1,81 @@
+/// Convenient wrapper to be able to use `?` and such in the main. You can
+/// use it with a separated function:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<()> {
+/// Err("error".into())
+/// }
+/// ```
+///
+/// or with a closure:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(|| -> Result<()> {
+/// Err("error".into())
+/// });
+/// # }
+/// ```
+///
+/// You can also set the exit value of the process by returning a type that implements [`ExitCode`](trait.ExitCode.html):
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<i32> {
+/// Err("error".into())
+/// }
+/// ```
+#[macro_export]
+macro_rules! quick_main {
+ ($main:expr) => {
+ fn main() {
+ use std::io::Write;
+
+ ::std::process::exit(match $main() {
+ Ok(ret) => $crate::ExitCode::code(ret),
+ Err(ref e) => {
+ write!(
+ &mut ::std::io::stderr(),
+ "{}",
+ $crate::ChainedError::display_chain(e)
+ )
+ .expect("Error writing to stderr");
+
+ 1
+ }
+ });
+ }
+ };
+}
+
+/// Represents a value that can be used as the exit status of the process.
+/// See [`quick_main!`](macro.quick_main.html).
+pub trait ExitCode {
+ /// Returns the value to use as the exit status.
+ fn code(self) -> i32;
+}
+
+impl ExitCode for i32 {
+ fn code(self) -> i32 {
+ self
+ }
+}
+
+impl ExitCode for () {
+ fn code(self) -> i32 {
+ 0
+ }
+}