summaryrefslogtreecommitdiffstats
path: root/third_party/rust/failure/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/failure/src')
-rw-r--r--third_party/rust/failure/src/as_fail.rs37
-rw-r--r--third_party/rust/failure/src/backtrace/internal.rs132
-rw-r--r--third_party/rust/failure/src/backtrace/mod.rs159
-rw-r--r--third_party/rust/failure/src/box_std.rs19
-rw-r--r--third_party/rust/failure/src/compat.rs53
-rw-r--r--third_party/rust/failure/src/context.rs180
-rw-r--r--third_party/rust/failure/src/error/error_impl.rs50
-rw-r--r--third_party/rust/failure/src/error/error_impl_small.rs132
-rw-r--r--third_party/rust/failure/src/error/mod.rs248
-rw-r--r--third_party/rust/failure/src/error_message.rs32
-rw-r--r--third_party/rust/failure/src/lib.rs307
-rw-r--r--third_party/rust/failure/src/macros.rs64
-rw-r--r--third_party/rust/failure/src/result_ext.rs203
-rw-r--r--third_party/rust/failure/src/small_error.rs264
-rw-r--r--third_party/rust/failure/src/sync_failure.rs97
15 files changed, 1977 insertions, 0 deletions
diff --git a/third_party/rust/failure/src/as_fail.rs b/third_party/rust/failure/src/as_fail.rs
new file mode 100644
index 0000000000..6e4172bd8c
--- /dev/null
+++ b/third_party/rust/failure/src/as_fail.rs
@@ -0,0 +1,37 @@
+use Fail;
+
+/// The `AsFail` trait
+///
+/// This trait is similar to `AsRef<Fail>`, but it is specialized to handle
+/// the dynamic object of `Fail`. Implementors of `Fail` have a blanket
+/// implementation. It is used in `failure_derive` in order to generate a
+/// custom cause.
+pub trait AsFail {
+ /// Converts a reference to `Self` into a dynamic trait object of `Fail`.
+ fn as_fail(&self) -> &dyn Fail;
+}
+
+impl<T> AsFail for T
+where
+ T: Fail,
+{
+ fn as_fail(&self) -> &dyn Fail {
+ self
+ }
+}
+
+impl AsFail for dyn Fail {
+ fn as_fail(&self) -> &dyn Fail {
+ self
+ }
+}
+
+with_std! {
+ use error::Error;
+
+ impl AsFail for Error {
+ fn as_fail(&self) -> &dyn Fail {
+ self.as_fail()
+ }
+ }
+}
diff --git a/third_party/rust/failure/src/backtrace/internal.rs b/third_party/rust/failure/src/backtrace/internal.rs
new file mode 100644
index 0000000000..5e421201fa
--- /dev/null
+++ b/third_party/rust/failure/src/backtrace/internal.rs
@@ -0,0 +1,132 @@
+use std::cell::UnsafeCell;
+use std::env;
+use std::ffi::OsString;
+use std::fmt;
+#[allow(deprecated)] // to allow for older Rust versions (<1.24)
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+use std::sync::Mutex;
+
+pub use super::backtrace::Backtrace;
+
+const GENERAL_BACKTRACE: &str = "RUST_BACKTRACE";
+const FAILURE_BACKTRACE: &str = "RUST_FAILURE_BACKTRACE";
+
+pub(super) struct InternalBacktrace {
+ backtrace: Option<MaybeResolved>,
+}
+
+struct MaybeResolved {
+ resolved: Mutex<bool>,
+ backtrace: UnsafeCell<Backtrace>,
+}
+
+unsafe impl Send for MaybeResolved {}
+unsafe impl Sync for MaybeResolved {}
+
+impl InternalBacktrace {
+ pub(super) fn new() -> InternalBacktrace {
+ #[allow(deprecated)] // to allow for older Rust versions (<1.24)
+ static ENABLED: AtomicUsize = ATOMIC_USIZE_INIT;
+
+ match ENABLED.load(Ordering::SeqCst) {
+ 0 => {
+ let enabled = is_backtrace_enabled(|var| env::var_os(var));
+ ENABLED.store(enabled as usize + 1, Ordering::SeqCst);
+ if !enabled {
+ return InternalBacktrace { backtrace: None }
+ }
+ }
+ 1 => return InternalBacktrace { backtrace: None },
+ _ => {}
+ }
+
+ InternalBacktrace {
+ backtrace: Some(MaybeResolved {
+ resolved: Mutex::new(false),
+ backtrace: UnsafeCell::new(Backtrace::new_unresolved()),
+ }),
+ }
+ }
+
+ pub(super) fn none() -> InternalBacktrace {
+ InternalBacktrace { backtrace: None }
+ }
+
+ pub(super) 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())
+ }
+ }
+
+ pub(super) fn is_none(&self) -> bool {
+ self.backtrace.is_none()
+ }
+}
+
+impl fmt::Debug for InternalBacktrace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("InternalBacktrace")
+ .field("backtrace", &self.as_backtrace())
+ .finish()
+ }
+}
+
+fn is_backtrace_enabled<F: Fn(&str) -> Option<OsString>>(get_var: F) -> bool {
+ match get_var(FAILURE_BACKTRACE) {
+ Some(ref val) if val != "0" => true,
+ Some(ref val) if val == "0" => false,
+ _ => match get_var(GENERAL_BACKTRACE) {
+ Some(ref val) if val != "0" => true,
+ _ => false,
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ const YEA: Option<&str> = Some("1");
+ const NAY: Option<&str> = Some("0");
+ const NOT_SET: Option<&str> = None;
+
+ macro_rules! test_enabled {
+ (failure: $failure:ident, general: $general:ident => $result:expr) => {{
+ assert_eq!(is_backtrace_enabled(|var| match var {
+ FAILURE_BACKTRACE => $failure.map(OsString::from),
+ GENERAL_BACKTRACE => $general.map(OsString::from),
+ _ => panic!()
+ }), $result);
+ }}
+ }
+
+ #[test]
+ fn always_enabled_if_failure_is_set_to_yes() {
+ test_enabled!(failure: YEA, general: YEA => true);
+ test_enabled!(failure: YEA, general: NOT_SET => true);
+ test_enabled!(failure: YEA, general: NAY => true);
+ }
+
+ #[test]
+ fn never_enabled_if_failure_is_set_to_no() {
+ test_enabled!(failure: NAY, general: YEA => false);
+ test_enabled!(failure: NAY, general: NOT_SET => false);
+ test_enabled!(failure: NAY, general: NAY => false);
+ }
+
+ #[test]
+ fn follows_general_if_failure_is_not_set() {
+ test_enabled!(failure: NOT_SET, general: YEA => true);
+ test_enabled!(failure: NOT_SET, general: NOT_SET => false);
+ test_enabled!(failure: NOT_SET, general: NAY => false);
+ }
+}
diff --git a/third_party/rust/failure/src/backtrace/mod.rs b/third_party/rust/failure/src/backtrace/mod.rs
new file mode 100644
index 0000000000..9eba16d9cb
--- /dev/null
+++ b/third_party/rust/failure/src/backtrace/mod.rs
@@ -0,0 +1,159 @@
+use core::fmt::{self, Debug, Display};
+
+macro_rules! with_backtrace { ($($i:item)*) => ($(#[cfg(all(feature = "backtrace", feature = "std"))]$i)*) }
+macro_rules! without_backtrace { ($($i:item)*) => ($(#[cfg(not(all(feature = "backtrace", feature = "std")))]$i)*) }
+
+without_backtrace! {
+ /// A `Backtrace`.
+ ///
+ /// This is an opaque wrapper around the backtrace provided by
+ /// libbacktrace. A variety of optimizations have been performed to avoid
+ /// unnecessary or ill-advised work:
+ ///
+ /// - If this crate is compiled in `no_std` compatible mode, `Backtrace`
+ /// is an empty struct, and will be completely compiled away.
+ /// - If this crate is run without the `RUST_BACKTRACE` environmental
+ /// variable enabled, the backtrace will not be generated at runtime.
+ /// - Even if a backtrace is generated, the most expensive part of
+ /// generating a backtrace is symbol resolution. This backtrace does not
+ /// perform symbol resolution until it is actually read (e.g. by
+ /// printing it). If the Backtrace is never used for anything, symbols
+ /// never get resolved.
+ ///
+ /// Even with these optimizations, including a backtrace in your failure
+ /// may not be appropriate to your use case. You are not required to put a
+ /// backtrace in a custom `Fail` type.
+ ///
+ /// > (We have detected that this crate was documented with no_std
+ /// > compatibility turned on. The version of this crate that has been
+ /// > documented here will never generate a backtrace.)
+ pub struct Backtrace {
+ _secret: (),
+ }
+
+ impl Backtrace {
+ /// Constructs a new backtrace. This will only create a real backtrace
+ /// if the crate is compiled in std mode and the `RUST_BACKTRACE`
+ /// environmental variable is activated.
+ ///
+ /// > (We have detected that this crate was documented with no_std
+ /// > compatibility turned on. The version of this crate that has been
+ /// > documented here will never generate a backtrace.)
+ pub fn new() -> Backtrace {
+ Backtrace { _secret: () }
+ }
+
+ #[cfg(feature = "std")]
+ pub(crate) fn none() -> Backtrace {
+ Backtrace { _secret: () }
+ }
+
+ #[cfg(feature = "std")]
+ pub(crate) fn is_none(&self) -> bool {
+ true
+ }
+
+ /// Returns true if displaying this backtrace would be an empty string.
+ ///
+ /// > (We have detected that this crate was documented with no_std
+ /// > compatibility turned on. The version of this crate that has been
+ /// > documented here will never generate a backtrace and this method
+ /// > will always return true.)
+ pub fn is_empty(&self) -> bool {
+ true
+ }
+ }
+
+ impl Default for Backtrace {
+ fn default() -> Backtrace {
+ Backtrace::new()
+ }
+ }
+
+ impl Debug for Backtrace {
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ Ok(())
+ }
+ }
+
+ impl Display for Backtrace {
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ Ok(())
+ }
+ }
+}
+
+with_backtrace! {
+ extern crate backtrace;
+
+ mod internal;
+
+ use self::internal::InternalBacktrace;
+
+ /// A `Backtrace`.
+ ///
+ /// This is an opaque wrapper around the backtrace provided by
+ /// libbacktrace. A variety of optimizations have been performed to avoid
+ /// unnecessary or ill-advised work:
+ ///
+ /// - If this crate is compiled in `no_std` compatible mode, `Backtrace`
+ /// is an empty struct, and will be completely compiled away.
+ /// - If this crate is run without the `RUST_BACKTRACE` environmental
+ /// variable enabled, the backtrace will not be generated at runtime.
+ /// - Even if a backtrace is generated, the most expensive part of
+ /// generating a backtrace is symbol resolution. This backtrace does not
+ /// perform symbol resolution until it is actually read (e.g. by
+ /// printing it). If the Backtrace is never used for anything, symbols
+ /// never get resolved.
+ ///
+ /// Even with these optimizations, including a backtrace in your failure
+ /// may not be appropriate to your use case. You are not required to put a
+ /// backtrace in a custom `Fail` type.
+ pub struct Backtrace {
+ internal: InternalBacktrace
+ }
+
+ impl Backtrace {
+ /// Constructs a new backtrace. This will only create a real backtrace
+ /// if the crate is compiled in std mode and the `RUST_BACKTRACE`
+ /// environmental variable is activated.
+ pub fn new() -> Backtrace {
+ Backtrace { internal: InternalBacktrace::new() }
+ }
+
+ pub(crate) fn none() -> Backtrace {
+ Backtrace { internal: InternalBacktrace::none() }
+ }
+
+ pub(crate) fn is_none(&self) -> bool {
+ self.internal.is_none()
+ }
+
+ /// Returns true if displaying this backtrace would be an empty string.
+ pub fn is_empty(&self) -> bool {
+ self.internal.is_none()
+ }
+ }
+
+ impl Default for Backtrace {
+ fn default() -> Backtrace {
+ Backtrace::new()
+ }
+ }
+
+ impl Debug for Backtrace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if let Some(bt) = self.internal.as_backtrace() {
+ Debug::fmt(bt, f)
+ } else { Ok(()) }
+ }
+ }
+
+ impl Display for Backtrace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if let Some(bt) = self.internal.as_backtrace() {
+ Debug::fmt(bt, f)
+ } else { Ok(()) }
+ }
+ }
+}
diff --git a/third_party/rust/failure/src/box_std.rs b/third_party/rust/failure/src/box_std.rs
new file mode 100644
index 0000000000..05891db13c
--- /dev/null
+++ b/third_party/rust/failure/src/box_std.rs
@@ -0,0 +1,19 @@
+use std::error::Error;
+use std::fmt;
+use Fail;
+
+pub struct BoxStd(pub Box<dyn Error + Send + Sync + 'static>);
+
+impl fmt::Display for BoxStd {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.0, f)
+ }
+}
+
+impl fmt::Debug for BoxStd {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Debug::fmt(&self.0, f)
+ }
+}
+
+impl Fail for BoxStd {}
diff --git a/third_party/rust/failure/src/compat.rs b/third_party/rust/failure/src/compat.rs
new file mode 100644
index 0000000000..dec5383828
--- /dev/null
+++ b/third_party/rust/failure/src/compat.rs
@@ -0,0 +1,53 @@
+use core::fmt::{self, Display};
+
+/// A compatibility wrapper around an error type from this crate.
+///
+/// `Compat` implements `std::error::Error`, allowing the types from this
+/// crate to be passed to interfaces that expect a type of that trait.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]
+pub struct Compat<E> {
+ pub(crate) error: E,
+}
+
+impl<E: Display> Display for Compat<E> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.error, f)
+ }
+}
+
+impl<E> Compat<E> {
+ /// Unwraps this into the inner error.
+ pub fn into_inner(self) -> E {
+ self.error
+ }
+
+ /// Gets a reference to the inner error.
+ pub fn get_ref(&self) -> &E {
+ &self.error
+ }
+}
+
+with_std! {
+ use std::fmt::Debug;
+ use std::error::Error as StdError;
+
+ use Error;
+
+ impl<E: Display + Debug> StdError for Compat<E> {
+ fn description(&self) -> &'static str {
+ "An error has occurred."
+ }
+ }
+
+ impl From<Error> for Box<dyn StdError> {
+ fn from(error: Error) -> Box<dyn StdError> {
+ Box::new(Compat { error })
+ }
+ }
+
+ impl From<Error> for Box<dyn StdError + Send + Sync> {
+ fn from(error: Error) -> Box<dyn StdError + Send + Sync> {
+ Box::new(Compat { error })
+ }
+ }
+}
diff --git a/third_party/rust/failure/src/context.rs b/third_party/rust/failure/src/context.rs
new file mode 100644
index 0000000000..b5977e9a28
--- /dev/null
+++ b/third_party/rust/failure/src/context.rs
@@ -0,0 +1,180 @@
+use core::fmt::{self, Debug, Display};
+
+use Fail;
+
+without_std! {
+ /// An error with context around it.
+ ///
+ /// The context is intended to be a human-readable, user-facing explanation for the
+ /// error that has occurred. The underlying error is not assumed to be end-user-relevant
+ /// information.
+ ///
+ /// The `Display` impl for `Context` only prints the human-readable context, while the
+ /// `Debug` impl also prints the underlying error.
+ pub struct Context<D: Display + Send + Sync + 'static> {
+ context: D,
+ }
+
+ impl<D: Display + Send + Sync + 'static> Context<D> {
+ /// Creates a new context without an underlying error message.
+ pub fn new(context: D) -> Context<D> {
+ Context { context }
+ }
+
+ /// Returns a reference to the context provided with this error.
+ pub fn get_context(&self) -> &D {
+ &self.context
+ }
+
+ /// Maps `Context<D>` to `Context<T>` by applying a function to the contained context.
+ pub fn map<F, T>(self, op: F) -> Context<T>
+ where F: FnOnce(D) -> T,
+ T: Display + Send + Sync + 'static
+ {
+ Context {
+ context: op(self.context),
+ }
+ }
+
+ pub(crate) fn with_err<E: Fail>(context: D, _: E) -> Context<D> {
+ Context { context }
+ }
+ }
+
+ impl<D: Display + Send + Sync + 'static> Fail for Context<D> { }
+
+ impl<D: Display + Send + Sync + 'static> Debug for Context<D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.context)
+ }
+ }
+
+ impl<D: Display + Send + Sync + 'static> Display for Context<D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.context)
+ }
+ }
+
+ #[test]
+ fn test_map() {
+ let ctx = Context::new("a string").map(|s| format!("{} with some more stuff", s));
+ assert_eq!(ctx.context, String::from("a string with some more stuff"));
+ }
+}
+
+with_std! {
+ use {Error, Backtrace};
+
+ /// An error with context around it.
+ ///
+ /// The context is intended to be a human-readable, user-facing explanation for the
+ /// error that has occurred. The underlying error is not assumed to be end-user-relevant
+ /// information.
+ ///
+ /// The `Display` impl for `Context` only prints the human-readable context, while the
+ /// `Debug` impl also prints the underlying error.
+ pub struct Context<D: Display + Send + Sync + 'static> {
+ context: D,
+ failure: Either<Backtrace, Error>,
+ }
+
+ impl<D: Display + Send + Sync + 'static> Context<D> {
+ /// Creates a new context without an underlying error message.
+ pub fn new(context: D) -> Context<D> {
+ let failure = Either::This(Backtrace::new());
+ Context { context, failure }
+ }
+
+ /// Returns a reference to the context provided with this error.
+ pub fn get_context(&self) -> &D {
+ &self.context
+ }
+
+ /// Maps `Context<D>` to `Context<T>` by applying a function to the contained context.
+ pub fn map<F, T>(self, op: F) -> Context<T>
+ where F: FnOnce(D) -> T,
+ T: Display + Send + Sync + 'static
+ {
+ Context {
+ context: op(self.context),
+ failure: self.failure,
+ }
+ }
+
+ pub(crate) fn with_err<E: Into<Error>>(context: D, error: E) -> Context<D> {
+ let failure = Either::That(error.into());
+ Context { context, failure }
+ }
+ }
+
+ impl<D: Display + Send + Sync + 'static> Fail for Context<D> {
+ fn name(&self) -> Option<&str> {
+ self.failure.as_cause().and_then(|x| x.name())
+ }
+
+ fn cause(&self) -> Option<&dyn Fail> {
+ self.failure.as_cause()
+ }
+
+ fn backtrace(&self) -> Option<&Backtrace> {
+ Some(self.failure.backtrace())
+ }
+ }
+
+ impl<D: Display + Send + Sync + 'static> Debug for Context<D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}\n\n{}", self.failure, self.context)
+ }
+ }
+
+ impl<D: Display + Send + Sync + 'static> Display for Context<D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.context)
+ }
+ }
+
+ enum Either<A, B> {
+ This(A),
+ That(B),
+ }
+
+ impl Either<Backtrace, Error> {
+ fn backtrace(&self) -> &Backtrace {
+ match *self {
+ Either::This(ref backtrace) => backtrace,
+ Either::That(ref error) => error.backtrace(),
+ }
+ }
+
+ fn as_cause(&self) -> Option<&dyn Fail> {
+ match *self {
+ Either::This(_) => None,
+ Either::That(ref error) => Some(error.as_fail())
+ }
+ }
+ }
+
+ impl Debug for Either<Backtrace, Error> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Either::This(ref backtrace) => write!(f, "{:?}", backtrace),
+ Either::That(ref error) => write!(f, "{:?}", error),
+ }
+ }
+ }
+
+ #[test]
+ fn test_map() {
+ let ctx = Context::new("a string").map(|s| format!("{} with some more stuff", s));
+ assert_eq!(ctx.context, String::from("a string with some more stuff"));
+ }
+}
+
+impl<D> From<D> for Context<D>
+where
+ D: Display + Send + Sync + 'static,
+{
+ fn from(display: D) -> Context<D> {
+ Context::new(display)
+ }
+}
diff --git a/third_party/rust/failure/src/error/error_impl.rs b/third_party/rust/failure/src/error/error_impl.rs
new file mode 100644
index 0000000000..6a95d92d18
--- /dev/null
+++ b/third_party/rust/failure/src/error/error_impl.rs
@@ -0,0 +1,50 @@
+use core::any::TypeId;
+
+use Fail;
+use backtrace::Backtrace;
+
+pub(crate) struct ErrorImpl {
+ inner: Box<Inner<dyn Fail>>,
+}
+
+struct Inner<F: ?Sized + Fail> {
+ backtrace: Backtrace,
+ pub(crate) failure: F,
+}
+
+impl<F: Fail> From<F> for ErrorImpl {
+ fn from(failure: F) -> ErrorImpl {
+ let inner: Inner<F> = {
+ let backtrace = if failure.backtrace().is_none() {
+ Backtrace::new()
+ } else { Backtrace::none() };
+ Inner { failure, backtrace }
+ };
+ ErrorImpl { inner: Box::new(inner) }
+ }
+}
+
+impl ErrorImpl {
+ pub(crate) fn failure(&self) -> &dyn Fail {
+ &self.inner.failure
+ }
+
+ pub(crate) fn failure_mut(&mut self) -> &mut dyn Fail {
+ &mut self.inner.failure
+ }
+
+ pub(crate) fn backtrace(&self) -> &Backtrace {
+ &self.inner.backtrace
+ }
+
+ pub(crate) fn downcast<T: Fail>(self) -> Result<T, ErrorImpl> {
+ if self.failure().__private_get_type_id__() == TypeId::of::<T>() {
+ let ErrorImpl { inner } = self;
+ let casted = unsafe { Box::from_raw(Box::into_raw(inner) as *mut Inner<T>) };
+ let Inner { backtrace:_, failure } = *casted;
+ Ok(failure)
+ } else {
+ Err(self)
+ }
+ }
+}
diff --git a/third_party/rust/failure/src/error/error_impl_small.rs b/third_party/rust/failure/src/error/error_impl_small.rs
new file mode 100644
index 0000000000..6ff7c78ec7
--- /dev/null
+++ b/third_party/rust/failure/src/error/error_impl_small.rs
@@ -0,0 +1,132 @@
+use std::heap::{Heap, Alloc, Layout};
+
+use core::mem;
+use core::ptr;
+
+use Fail;
+use backtrace::Backtrace;
+
+pub(crate) struct ErrorImpl {
+ inner: &'static mut Inner,
+}
+
+// Dynamically sized inner value
+struct Inner {
+ backtrace: Backtrace,
+ vtable: *const VTable,
+ failure: FailData,
+}
+
+unsafe impl Send for Inner { }
+unsafe impl Sync for Inner { }
+
+extern {
+ type VTable;
+ type FailData;
+}
+
+#[allow(dead_code)]
+struct InnerRaw<F> {
+ header: InnerHeader,
+ failure: F,
+}
+
+#[allow(dead_code)]
+struct InnerHeader {
+ backtrace: Backtrace,
+ vtable: *const VTable,
+}
+
+struct TraitObject {
+ #[allow(dead_code)]
+ data: *const FailData,
+ vtable: *const VTable,
+}
+
+impl<F: Fail> From<F> for ErrorImpl {
+ fn from(failure: F) -> ErrorImpl {
+ let backtrace = if failure.backtrace().is_none() {
+ Backtrace::new()
+ } else {
+ Backtrace::none()
+ };
+
+ unsafe {
+ let vtable = mem::transmute::<_, TraitObject>(&failure as &Fail).vtable;
+
+ let ptr: *mut InnerRaw<F> = match Heap.alloc(Layout::new::<InnerRaw<F>>()) {
+ Ok(p) => p as *mut InnerRaw<F>,
+ Err(e) => Heap.oom(e),
+ };
+
+ // N.B. must use `ptr::write`, not `=`, to avoid dropping the contents of `*ptr`
+ ptr::write(ptr, InnerRaw {
+ header: InnerHeader {
+ backtrace,
+ vtable,
+ },
+ failure,
+ });
+
+ let inner: &'static mut Inner = mem::transmute(ptr);
+
+ ErrorImpl { inner }
+ }
+ }
+}
+
+impl ErrorImpl {
+ pub(crate) fn failure(&self) -> &Fail {
+ unsafe {
+ mem::transmute::<TraitObject, &Fail>(TraitObject {
+ data: &self.inner.failure as *const FailData,
+ vtable: self.inner.vtable,
+ })
+ }
+ }
+
+ pub(crate) fn failure_mut(&mut self) -> &mut Fail {
+ unsafe {
+ mem::transmute::<TraitObject, &mut Fail>(TraitObject {
+ data: &mut self.inner.failure as *const FailData,
+ vtable: self.inner.vtable,
+ })
+ }
+ }
+
+ pub(crate) fn backtrace(&self) -> &Backtrace {
+ &self.inner.backtrace
+ }
+
+ pub(crate) fn downcast<T: Fail>(self) -> Result<T, ErrorImpl> {
+ let ret: Option<T> = self.failure().downcast_ref().map(|fail| {
+ unsafe {
+ // drop the backtrace
+ let _ = ptr::read(&self.inner.backtrace as *const Backtrace);
+ // read out the fail type
+ ptr::read(fail as *const T)
+ }
+ });
+ match ret {
+ Some(ret) => {
+ // forget self (backtrace is dropped, failure is moved
+ mem::forget(self);
+ Ok(ret)
+ }
+ _ => Err(self)
+ }
+ }
+}
+
+
+#[cfg(test)]
+mod test {
+ use std::mem::size_of;
+
+ use super::ErrorImpl;
+
+ #[test]
+ fn assert_is_one_word() {
+ assert_eq!(size_of::<ErrorImpl>(), size_of::<usize>());
+ }
+}
diff --git a/third_party/rust/failure/src/error/mod.rs b/third_party/rust/failure/src/error/mod.rs
new file mode 100644
index 0000000000..842dbbae0c
--- /dev/null
+++ b/third_party/rust/failure/src/error/mod.rs
@@ -0,0 +1,248 @@
+use core::fmt::{self, Display, Debug};
+
+use {Causes, Fail};
+use backtrace::Backtrace;
+use context::Context;
+use compat::Compat;
+
+#[cfg(feature = "std")]
+use box_std::BoxStd;
+
+#[cfg_attr(feature = "small-error", path = "./error_impl_small.rs")]
+mod error_impl;
+use self::error_impl::ErrorImpl;
+
+#[cfg(feature = "std")]
+use std::error::Error as StdError;
+
+
+/// The `Error` type, which can contain any failure.
+///
+/// Functions which accumulate many kinds of errors should return this type.
+/// All failures can be converted into it, so functions which catch those
+/// errors can be tried with `?` inside of a function that returns this kind
+/// of error.
+///
+/// In addition to implementing `Debug` and `Display`, this type carries `Backtrace`
+/// information, and can be downcast into the failure that underlies it for
+/// more detailed inspection.
+pub struct Error {
+ imp: ErrorImpl,
+}
+
+impl<F: Fail> From<F> for Error {
+ fn from(failure: F) -> Error {
+ Error {
+ imp: ErrorImpl::from(failure)
+ }
+ }
+}
+
+impl Error {
+ /// Creates an `Error` from `Box<std::error::Error>`.
+ ///
+ /// This method is useful for comparability with code,
+ /// which does not use the `Fail` trait.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::error::Error as StdError;
+ /// use failure::Error;
+ ///
+ /// fn app_fn() -> Result<i32, Error> {
+ /// let x = library_fn().map_err(Error::from_boxed_compat)?;
+ /// Ok(x * 2)
+ /// }
+ ///
+ /// fn library_fn() -> Result<i32, Box<StdError + Sync + Send + 'static>> {
+ /// Ok(92)
+ /// }
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn from_boxed_compat(err: Box<dyn StdError + Sync + Send + 'static>) -> Error {
+ Error::from(BoxStd(err))
+ }
+
+ /// Return a reference to the underlying failure that this `Error`
+ /// contains.
+ pub fn as_fail(&self) -> &dyn Fail {
+ self.imp.failure()
+ }
+
+ /// Returns the name of the underlying fail.
+ pub fn name(&self) -> Option<&str> {
+ self.as_fail().name()
+ }
+
+ /// Returns a reference to the underlying cause of this `Error`. Unlike the
+ /// method on `Fail`, this does not return an `Option`. The `Error` type
+ /// always has an underlying failure.
+ ///
+ /// This method has been deprecated in favor of the [Error::as_fail] method,
+ /// which does the same thing.
+ #[deprecated(since = "0.1.2", note = "please use 'as_fail()' method instead")]
+ pub fn cause(&self) -> &dyn Fail {
+ self.as_fail()
+ }
+
+ /// Gets a reference to the `Backtrace` for this `Error`.
+ ///
+ /// If the failure this wrapped carried a backtrace, that backtrace will
+ /// be returned. Otherwise, the backtrace will have been constructed at
+ /// the point that failure was cast into the `Error` type.
+ pub fn backtrace(&self) -> &Backtrace {
+ self.imp.failure().backtrace().unwrap_or(&self.imp.backtrace())
+ }
+
+ /// Provides context for this `Error`.
+ ///
+ /// This can provide additional information about this error, appropriate
+ /// to the semantics of the current layer. That is, if you have a
+ /// lower-level error, such as an IO error, you can provide additional context
+ /// about what that error means in the context of your function. This
+ /// gives users of this function more information about what has gone
+ /// wrong.
+ ///
+ /// This takes any type that implements `Display`, as well as
+ /// `Send`/`Sync`/`'static`. In practice, this means it can take a `String`
+ /// or a string literal, or a failure, or some other custom context-carrying
+ /// type.
+ pub fn context<D: Display + Send + Sync + 'static>(self, context: D) -> Context<D> {
+ Context::with_err(context, self)
+ }
+
+ /// Wraps `Error` in a compatibility type.
+ ///
+ /// This type implements the `Error` trait from `std::error`. If you need
+ /// to pass failure's `Error` to an interface that takes any `Error`, you
+ /// can use this method to get a compatible type.
+ pub fn compat(self) -> Compat<Error> {
+ Compat { error: self }
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type.
+ ///
+ /// This downcasts by value, returning an owned `T` if the underlying
+ /// failure is of the type `T`. For this reason it returns a `Result` - in
+ /// the case that the underlying error is of a different type, the
+ /// original `Error` is returned.
+ pub fn downcast<T: Fail>(self) -> Result<T, Error> {
+ self.imp.downcast().map_err(|imp| Error { imp })
+ }
+
+ /// Returns the "root cause" of this error - the last value in the
+ /// cause chain which does not return an underlying `cause`.
+ pub fn find_root_cause(&self) -> &dyn Fail {
+ self.as_fail().find_root_cause()
+ }
+
+ /// Returns a iterator over the causes of this error with the cause
+ /// of the fail as the first item and the `root_cause` as the final item.
+ ///
+ /// Use `iter_chain` to also include the fail of this error itself.
+ pub fn iter_causes(&self) -> Causes {
+ self.as_fail().iter_causes()
+ }
+
+ /// Returns a iterator over all fails up the chain from the current
+ /// as the first item up to the `root_cause` as the final item.
+ ///
+ /// This means that the chain also includes the fail itself which
+ /// means that it does *not* start with `cause`. To skip the outermost
+ /// fail use `iter_causes` instead.
+ pub fn iter_chain(&self) -> Causes {
+ self.as_fail().iter_chain()
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type by
+ /// reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
+ self.imp.failure().downcast_ref()
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type by
+ /// mutable reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_mut<T: Fail>(&mut self) -> Option<&mut T> {
+ self.imp.failure_mut().downcast_mut()
+ }
+
+ /// Deprecated alias to `find_root_cause`.
+ #[deprecated(since = "0.1.2", note = "please use the 'find_root_cause()' method instead")]
+ pub fn root_cause(&self) -> &dyn Fail {
+ ::find_root_cause(self.as_fail())
+ }
+
+ /// Deprecated alias to `iter_causes`.
+ #[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
+ pub fn causes(&self) -> Causes {
+ Causes { fail: Some(self.as_fail()) }
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.imp.failure(), f)
+ }
+}
+
+impl Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let backtrace = self.imp.backtrace();
+ if backtrace.is_none() {
+ Debug::fmt(&self.imp.failure(), f)
+ } else {
+ write!(f, "{:?}\n\n{:?}", &self.imp.failure(), backtrace)
+ }
+ }
+}
+
+impl AsRef<dyn Fail> for Error {
+ fn as_ref(&self) -> &dyn Fail {
+ self.as_fail()
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use std::io;
+ use super::Error;
+
+ fn assert_just_data<T: Send + Sync + 'static>() { }
+
+ #[test]
+ fn assert_error_is_just_data() {
+ assert_just_data::<Error>();
+ }
+
+ #[test]
+ fn methods_seem_to_work() {
+ let io_error: io::Error = io::Error::new(io::ErrorKind::NotFound, "test");
+ let error: Error = io::Error::new(io::ErrorKind::NotFound, "test").into();
+ assert!(error.downcast_ref::<io::Error>().is_some());
+ let _: ::Backtrace = *error.backtrace();
+ assert_eq!(format!("{:?}", io_error), format!("{:?}", error));
+ assert_eq!(format!("{}", io_error), format!("{}", error));
+ drop(error);
+ assert!(true);
+ }
+
+ #[test]
+ fn downcast_can_be_used() {
+ let mut error: Error = io::Error::new(io::ErrorKind::NotFound, "test").into();
+ {
+ let real_io_error_ref = error.downcast_ref::<io::Error>().unwrap();
+ assert_eq!(real_io_error_ref.to_string(), "test");
+ }
+ {
+ let real_io_error_mut = error.downcast_mut::<io::Error>().unwrap();
+ assert_eq!(real_io_error_mut.to_string(), "test");
+ }
+ let real_io_error = error.downcast::<io::Error>().unwrap();
+ assert_eq!(real_io_error.to_string(), "test");
+ }
+}
diff --git a/third_party/rust/failure/src/error_message.rs b/third_party/rust/failure/src/error_message.rs
new file mode 100644
index 0000000000..560d317b4d
--- /dev/null
+++ b/third_party/rust/failure/src/error_message.rs
@@ -0,0 +1,32 @@
+use core::fmt::{self, Display, Debug};
+
+use Fail;
+use Error;
+
+/// Constructs a `Fail` type from a string.
+///
+/// This is a convenient way to turn a string into an error value that
+/// can be passed around, if you do not want to create a new `Fail` type for
+/// this use case.
+pub fn err_msg<D: Display + Debug + Sync + Send + 'static>(msg: D) -> Error {
+ Error::from(ErrorMessage { msg })
+}
+
+/// A `Fail` type that just contains an error message. You can construct
+/// this from the `err_msg` function.
+#[derive(Debug)]
+struct ErrorMessage<D: Display + Debug + Sync + Send + 'static> {
+ msg: D,
+}
+
+impl<D: Display + Debug + Sync + Send + 'static> Fail for ErrorMessage<D> {
+ fn name(&self) -> Option<&str> {
+ Some("failure::ErrorMessage")
+ }
+}
+
+impl<D: Display + Debug + Sync + Send + 'static> Display for ErrorMessage<D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.msg, f)
+ }
+}
diff --git a/third_party/rust/failure/src/lib.rs b/third_party/rust/failure/src/lib.rs
new file mode 100644
index 0000000000..41a45ba474
--- /dev/null
+++ b/third_party/rust/failure/src/lib.rs
@@ -0,0 +1,307 @@
+//! An experimental new error-handling library. Guide-style introduction
+//! is available [here](https://boats.gitlab.io/failure/).
+//!
+//! The primary items exported by this library are:
+//!
+//! - `Fail`: a new trait for custom error types in Rust.
+//! - `Error`: a wrapper around `Fail` types to make it easy to coalesce them
+//! at higher levels.
+//!
+//! As a general rule, library authors should create their own error types and
+//! implement `Fail` for them, whereas application authors should primarily
+//! deal with the `Error` type. There are exceptions to this rule, though, in
+//! both directions, and users should do whatever seems most appropriate to
+//! their situation.
+//!
+//! ## Backtraces
+//!
+//! Backtraces are disabled by default. To turn backtraces on, enable
+//! the `backtrace` Cargo feature and set the `RUST_BACKTRACE` environment
+//! variable to a non-zero value (this also enables backtraces for panics).
+//! Use the `RUST_FAILURE_BACKTRACE` variable to enable or disable backtraces
+//! for `failure` specifically.
+#![cfg_attr(not(feature = "std"), no_std)]
+#![deny(missing_docs)]
+#![deny(warnings)]
+#![cfg_attr(feature = "small-error", feature(extern_types, allocator_api))]
+
+macro_rules! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) }
+macro_rules! without_std { ($($i:item)*) => ($(#[cfg(not(feature = "std"))]$i)*) }
+
+// Re-export libcore using an alias so that the macros can work without
+// requiring `extern crate core` downstream.
+#[doc(hidden)]
+pub extern crate core as _core;
+
+mod as_fail;
+mod backtrace;
+#[cfg(feature = "std")]
+mod box_std;
+mod compat;
+mod context;
+mod result_ext;
+
+use core::any::TypeId;
+use core::fmt::{Debug, Display};
+
+pub use as_fail::AsFail;
+pub use backtrace::Backtrace;
+pub use compat::Compat;
+pub use context::Context;
+pub use result_ext::ResultExt;
+
+#[cfg(feature = "failure_derive")]
+#[allow(unused_imports)]
+#[macro_use]
+extern crate failure_derive;
+
+#[cfg(feature = "failure_derive")]
+#[doc(hidden)]
+pub use failure_derive::*;
+
+with_std! {
+ extern crate core;
+
+ mod sync_failure;
+ pub use sync_failure::SyncFailure;
+
+ mod error;
+
+ use std::error::Error as StdError;
+
+ pub use error::Error;
+
+ /// A common result with an `Error`.
+ pub type Fallible<T> = Result<T, Error>;
+
+ mod macros;
+ mod error_message;
+ pub use error_message::err_msg;
+}
+
+/// The `Fail` trait.
+///
+/// Implementors of this trait are called 'failures'.
+///
+/// All error types should implement `Fail`, which provides a baseline of
+/// functionality that they all share.
+///
+/// `Fail` has no required methods, but it does require that your type
+/// implement several other traits:
+///
+/// - `Display`: to print a user-friendly representation of the error.
+/// - `Debug`: to print a verbose, developer-focused representation of the
+/// error.
+/// - `Send + Sync`: Your error type is required to be safe to transfer to and
+/// reference from another thread
+///
+/// Additionally, all failures must be `'static`. This enables downcasting.
+///
+/// `Fail` provides several methods with default implementations. Two of these
+/// may be appropriate to override depending on the definition of your
+/// particular failure: the `cause` and `backtrace` methods.
+///
+/// The `failure_derive` crate provides a way to derive the `Fail` trait for
+/// your type. Additionally, all types that already implement
+/// `std::error::Error`, and are also `Send`, `Sync`, and `'static`, implement
+/// `Fail` by a blanket impl.
+pub trait Fail: Display + Debug + Send + Sync + 'static {
+ /// Returns the "name" of the error.
+ ///
+ /// This is typically the type name. Not all errors will implement
+ /// this. This method is expected to be most useful in situations
+ /// where errors need to be reported to external instrumentation systems
+ /// such as crash reporters.
+ fn name(&self) -> Option<&str> {
+ None
+ }
+
+ /// Returns a reference to the underlying cause of this failure, if it
+ /// is an error that wraps other errors.
+ ///
+ /// Returns `None` if this failure does not have another error as its
+ /// underlying cause. By default, this returns `None`.
+ ///
+ /// This should **never** return a reference to `self`, but only return
+ /// `Some` when it can return a **different** failure. Users may loop
+ /// over the cause chain, and returning `self` would result in an infinite
+ /// loop.
+ fn cause(&self) -> Option<&dyn Fail> {
+ None
+ }
+
+ /// Returns a reference to the `Backtrace` carried by this failure, if it
+ /// carries one.
+ ///
+ /// Returns `None` if this failure does not carry a backtrace. By
+ /// default, this returns `None`.
+ fn backtrace(&self) -> Option<&Backtrace> {
+ None
+ }
+
+ /// Provides context for this failure.
+ ///
+ /// This can provide additional information about this error, appropriate
+ /// to the semantics of the current layer. That is, if you have a
+ /// lower-level error, such as an IO error, you can provide additional context
+ /// about what that error means in the context of your function. This
+ /// gives users of this function more information about what has gone
+ /// wrong.
+ ///
+ /// This takes any type that implements `Display`, as well as
+ /// `Send`/`Sync`/`'static`. In practice, this means it can take a `String`
+ /// or a string literal, or another failure, or some other custom context-carrying
+ /// type.
+ fn context<D>(self, context: D) -> Context<D>
+ where
+ D: Display + Send + Sync + 'static,
+ Self: Sized,
+ {
+ Context::with_err(context, self)
+ }
+
+ /// Wraps this failure in a compatibility wrapper that implements
+ /// `std::error::Error`.
+ ///
+ /// This allows failures to be compatible with older crates that
+ /// expect types that implement the `Error` trait from `std::error`.
+ fn compat(self) -> Compat<Self>
+ where
+ Self: Sized,
+ {
+ Compat { error: self }
+ }
+
+ #[doc(hidden)]
+ #[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
+ fn causes(&self) -> Causes
+ where
+ Self: Sized,
+ {
+ Causes { fail: Some(self) }
+ }
+
+ #[doc(hidden)]
+ #[deprecated(
+ since = "0.1.2",
+ note = "please use the 'find_root_cause()' method instead"
+ )]
+ fn root_cause(&self) -> &dyn Fail
+ where
+ Self: Sized,
+ {
+ find_root_cause(self)
+ }
+
+ #[doc(hidden)]
+ fn __private_get_type_id__(&self) -> TypeId {
+ TypeId::of::<Self>()
+ }
+}
+
+impl dyn Fail {
+ /// Attempts to downcast this failure to a concrete type by reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
+ if self.__private_get_type_id__() == TypeId::of::<T>() {
+ unsafe { Some(&*(self as *const dyn Fail as *const T)) }
+ } else {
+ None
+ }
+ }
+
+ /// Attempts to downcast this failure to a concrete type by mutable
+ /// reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_mut<T: Fail>(&mut self) -> Option<&mut T> {
+ if self.__private_get_type_id__() == TypeId::of::<T>() {
+ unsafe { Some(&mut *(self as *mut dyn Fail as *mut T)) }
+ } else {
+ None
+ }
+ }
+
+ /// Returns the "root cause" of this `Fail` - the last value in the
+ /// cause chain which does not return an underlying `cause`.
+ ///
+ /// If this type does not have a cause, `self` is returned, because
+ /// it is its own root cause.
+ ///
+ /// This is equivalent to iterating over `iter_causes()` and taking
+ /// the last item.
+ pub fn find_root_cause(&self) -> &dyn Fail {
+ find_root_cause(self)
+ }
+
+ /// Returns a iterator over the causes of this `Fail` with the cause
+ /// of this fail as the first item and the `root_cause` as the final item.
+ ///
+ /// Use `iter_chain` to also include the fail itself.
+ pub fn iter_causes(&self) -> Causes {
+ Causes { fail: self.cause() }
+ }
+
+ /// Returns a iterator over all fails up the chain from the current
+ /// as the first item up to the `root_cause` as the final item.
+ ///
+ /// This means that the chain also includes the fail itself which
+ /// means that it does *not* start with `cause`. To skip the outermost
+ /// fail use `iter_causes` instead.
+ pub fn iter_chain(&self) -> Causes {
+ Causes { fail: Some(self) }
+ }
+
+ /// Deprecated alias to `find_root_cause`.
+ #[deprecated(
+ since = "0.1.2",
+ note = "please use the 'find_root_cause()' method instead"
+ )]
+ pub fn root_cause(&self) -> &dyn Fail {
+ find_root_cause(self)
+ }
+
+ /// Deprecated alias to `iter_chain`.
+ #[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
+ pub fn causes(&self) -> Causes {
+ Causes { fail: Some(self) }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<E: StdError + Send + Sync + 'static> Fail for E {}
+
+#[cfg(feature = "std")]
+impl Fail for Box<dyn Fail> {
+ fn cause(&self) -> Option<&dyn Fail> {
+ (**self).cause()
+ }
+
+ fn backtrace(&self) -> Option<&Backtrace> {
+ (**self).backtrace()
+ }
+}
+
+/// A iterator over the causes of a `Fail`
+pub struct Causes<'f> {
+ fail: Option<&'f dyn Fail>,
+}
+
+impl<'f> Iterator for Causes<'f> {
+ type Item = &'f dyn Fail;
+ fn next(&mut self) -> Option<&'f dyn Fail> {
+ self.fail.map(|fail| {
+ self.fail = fail.cause();
+ fail
+ })
+ }
+}
+
+fn find_root_cause(mut fail: &dyn Fail) -> &dyn Fail {
+ while let Some(cause) = fail.cause() {
+ fail = cause;
+ }
+
+ fail
+}
diff --git a/third_party/rust/failure/src/macros.rs b/third_party/rust/failure/src/macros.rs
new file mode 100644
index 0000000000..c0a9dad294
--- /dev/null
+++ b/third_party/rust/failure/src/macros.rs
@@ -0,0 +1,64 @@
+/// Exits a function early with an `Error`.
+///
+/// The `bail!` macro provides an easy way to exit a function. `bail!(X)` is
+/// equivalent to writing:
+///
+/// ```rust,ignore
+/// return Err(format_err!(X))
+/// ```
+#[macro_export]
+macro_rules! bail {
+ ($e:expr) => {
+ return Err($crate::err_msg($e));
+ };
+ ($fmt:expr, $($arg:tt)*) => {
+ return Err($crate::err_msg(format!($fmt, $($arg)*)));
+ };
+}
+
+/// Exits a function early with an `Error` if the condition is not satisfied.
+///
+/// Similar to `assert!`, `ensure!` takes a condition and exits the function
+/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`,
+/// it does not panic.
+#[macro_export(local_inner_macros)]
+macro_rules! ensure {
+ ($cond:expr) => {
+ if !($cond) {
+ bail!("{}", _failure__stringify!($cond));
+ }
+ };
+ ($cond:expr, $e:expr) => {
+ if !($cond) {
+ bail!($e);
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)*) => {
+ if !($cond) {
+ bail!($fmt, $($arg)*);
+ }
+ };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! _failure__stringify {
+ ($($inner:tt)*) => {
+ stringify! { $($inner)* }
+ }
+}
+
+/// Constructs an `Error` using the standard string interpolation syntax.
+///
+/// ```rust
+/// #[macro_use] extern crate failure;
+///
+/// fn main() {
+/// let code = 101;
+/// let err = format_err!("Error code: {}", code);
+/// }
+/// ```
+#[macro_export]
+macro_rules! format_err {
+ ($($arg:tt)*) => { $crate::err_msg(format!($($arg)*)) }
+}
diff --git a/third_party/rust/failure/src/result_ext.rs b/third_party/rust/failure/src/result_ext.rs
new file mode 100644
index 0000000000..f4125cdd68
--- /dev/null
+++ b/third_party/rust/failure/src/result_ext.rs
@@ -0,0 +1,203 @@
+use core::fmt::Display;
+
+use {Compat, Context, Fail};
+
+/// Extension methods for `Result`.
+pub trait ResultExt<T, E> {
+ /// Wraps the error in `Compat` to make it compatible with older error
+ /// handling APIs that expect `std::error::Error`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn main() {
+ /// # tests::run_test();
+ /// # }
+ /// #
+ /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
+ /// #
+ /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
+ /// use std::error::Error;
+ /// # use std::fmt;
+ /// #
+ /// # extern crate failure;
+ /// #
+ /// # use tests::failure::ResultExt;
+ /// #
+ /// # #[derive(Debug)]
+ /// struct CustomError;
+ ///
+ /// impl Error for CustomError {
+ /// fn description(&self) -> &str {
+ /// "My custom error message"
+ /// }
+ ///
+ /// fn cause(&self) -> Option<&Error> {
+ /// None
+ /// }
+ /// }
+ /// #
+ /// # impl fmt::Display for CustomError {
+ /// # fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ /// # write!(f, "{}", self.description())
+ /// # }
+ /// # }
+ /// #
+ /// # pub fn run_test() {
+ ///
+ /// let x = (|| -> Result<(), failure::Error> {
+ /// Err(CustomError).compat()?
+ /// })().with_context(|e| {
+ /// format!("An error occured: {}", e)
+ /// }).unwrap_err();
+ ///
+ /// let x = format!("{}", x);
+ ///
+ /// assert_eq!(x, "An error occured: My custom error message");
+ /// # }
+ ///
+ /// # }
+ /// ```
+ fn compat(self) -> Result<T, Compat<E>>;
+
+ /// Wraps the error type in a context type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[cfg(all(feature = "std", feature = "derive"))]
+ /// # #[macro_use] extern crate failure;
+ /// #
+ /// # #[cfg(all(feature = "std", feature = "derive"))]
+ /// # #[macro_use] extern crate failure_derive;
+ /// #
+ /// # fn main() {
+ /// # tests::run_test();
+ /// # }
+ /// #
+ /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
+ /// #
+ /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
+ /// #
+ /// # use failure::{self, ResultExt};
+ /// #
+ /// #[derive(Fail, Debug)]
+ /// #[fail(display = "")]
+ /// struct CustomError;
+ /// #
+ /// # pub fn run_test() {
+ ///
+ /// let x = (|| -> Result<(), failure::Error> {
+ /// Err(CustomError)?
+ /// })().context(format!("An error occured")).unwrap_err();
+ ///
+ /// let x = format!("{}", x);
+ ///
+ /// assert_eq!(x, "An error occured");
+ /// # }
+ ///
+ /// # }
+ /// ```
+ fn context<D>(self, context: D) -> Result<T, Context<D>>
+ where
+ D: Display + Send + Sync + 'static;
+
+ /// Wraps the error type in a context type generated by looking at the
+ /// error value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[cfg(all(feature = "std", feature = "derive"))]
+ /// # #[macro_use] extern crate failure;
+ /// #
+ /// # #[cfg(all(feature = "std", feature = "derive"))]
+ /// # #[macro_use] extern crate failure_derive;
+ /// #
+ /// # fn main() {
+ /// # tests::run_test();
+ /// # }
+ /// #
+ /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
+ /// #
+ /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
+ /// #
+ /// # use failure::{self, ResultExt};
+ /// #
+ /// #[derive(Fail, Debug)]
+ /// #[fail(display = "My custom error message")]
+ /// struct CustomError;
+ /// #
+ /// # pub fn run_test() {
+ ///
+ /// let x = (|| -> Result<(), failure::Error> {
+ /// Err(CustomError)?
+ /// })().with_context(|e| {
+ /// format!("An error occured: {}", e)
+ /// }).unwrap_err();
+ ///
+ /// let x = format!("{}", x);
+ ///
+ /// assert_eq!(x, "An error occured: My custom error message");
+ /// # }
+ ///
+ /// # }
+ /// ```
+ fn with_context<F, D>(self, f: F) -> Result<T, Context<D>>
+ where
+ F: FnOnce(&E) -> D,
+ D: Display + Send + Sync + 'static;
+}
+
+impl<T, E> ResultExt<T, E> for Result<T, E>
+where
+ E: Fail,
+{
+ fn compat(self) -> Result<T, Compat<E>> {
+ self.map_err(|err| err.compat())
+ }
+
+ fn context<D>(self, context: D) -> Result<T, Context<D>>
+ where
+ D: Display + Send + Sync + 'static,
+ {
+ self.map_err(|failure| failure.context(context))
+ }
+
+ fn with_context<F, D>(self, f: F) -> Result<T, Context<D>>
+ where
+ F: FnOnce(&E) -> D,
+ D: Display + Send + Sync + 'static,
+ {
+ self.map_err(|failure| {
+ let context = f(&failure);
+ failure.context(context)
+ })
+ }
+}
+
+with_std! {
+ use Error;
+
+ impl<T> ResultExt<T, Error> for Result<T, Error> {
+ fn compat(self) -> Result<T, Compat<Error>> {
+ self.map_err(|err| err.compat())
+ }
+
+ fn context<D>(self, context: D) -> Result<T, Context<D>> where
+ D: Display + Send + Sync + 'static
+ {
+ self.map_err(|failure| failure.context(context))
+ }
+
+ fn with_context<F, D>(self, f: F) -> Result<T, Context<D>> where
+ F: FnOnce(&Error) -> D,
+ D: Display + Send + Sync + 'static
+ {
+ self.map_err(|failure| {
+ let context = f(&failure);
+ failure.context(context)
+ })
+ }
+ }
+}
diff --git a/third_party/rust/failure/src/small_error.rs b/third_party/rust/failure/src/small_error.rs
new file mode 100644
index 0000000000..09646e3915
--- /dev/null
+++ b/third_party/rust/failure/src/small_error.rs
@@ -0,0 +1,264 @@
+use core::fmt::{self, Display, Debug};
+use std::heap::{Heap, Alloc, Layout};
+
+use core::mem;
+use core::ptr;
+
+use {Causes, Fail};
+use backtrace::Backtrace;
+use context::Context;
+use compat::Compat;
+
+/// The `Error` type, which can contain any failure.
+///
+/// Functions which accumulate many kinds of errors should return this type.
+/// All failures can be converted into it, so functions which catch those
+/// errors can be tried with `?` inside of a function that returns this kind
+/// of error.
+///
+/// In addition to implementing `Debug` and `Display`, this type carries `Backtrace`
+/// information, and can be downcast into the failure that underlies it for
+/// more detailed inspection.
+pub struct Error {
+ inner: &'static mut Inner,
+}
+
+// Dynamically sized inner value
+struct Inner {
+ backtrace: Backtrace,
+ vtable: *const VTable,
+ failure: FailData,
+}
+
+unsafe impl Send for Inner { }
+unsafe impl Sync for Inner { }
+
+extern {
+ type VTable;
+ type FailData;
+}
+
+struct InnerRaw<F> {
+ header: InnerHeader,
+ failure: F,
+}
+
+struct InnerHeader {
+ backtrace: Backtrace,
+ vtable: *const VTable,
+}
+
+struct TraitObject {
+ #[allow(dead_code)]
+ data: *const FailData,
+ vtable: *const VTable,
+}
+
+impl<F: Fail> From<F> for Error {
+ fn from(failure: F) -> Error {
+ let backtrace = if failure.backtrace().is_none() {
+ Backtrace::new()
+ } else {
+ Backtrace::none()
+ };
+
+ unsafe {
+ let vtable = mem::transmute::<_, TraitObject>(&failure as &Fail).vtable;
+
+ let ptr: *mut InnerRaw<F> = match Heap.alloc(Layout::new::<InnerRaw<F>>()) {
+ Ok(p) => p as *mut InnerRaw<F>,
+ Err(e) => Heap.oom(e),
+ };
+
+ // N.B. must use `ptr::write`, not `=`, to avoid dropping the contents of `*ptr`
+ ptr::write(ptr, InnerRaw {
+ header: InnerHeader {
+ backtrace,
+ vtable,
+ },
+ failure,
+ });
+
+ let inner: &'static mut Inner = mem::transmute(ptr);
+
+ Error { inner }
+ }
+ }
+}
+
+impl Inner {
+ fn failure(&self) -> &Fail {
+ unsafe {
+ mem::transmute::<TraitObject, &Fail>(TraitObject {
+ data: &self.failure as *const FailData,
+ vtable: self.vtable,
+ })
+ }
+ }
+
+ fn failure_mut(&mut self) -> &mut Fail {
+ unsafe {
+ mem::transmute::<TraitObject, &mut Fail>(TraitObject {
+ data: &mut self.failure as *const FailData,
+ vtable: self.vtable,
+ })
+ }
+ }
+}
+
+impl Error {
+ /// Returns a reference to the underlying cause of this `Error`. Unlike the
+ /// method on `Fail`, this does not return an `Option`. The `Error` type
+ /// always has an underlying failure.
+ pub fn cause(&self) -> &Fail {
+ self.inner.failure()
+ }
+
+ /// Gets a reference to the `Backtrace` for this `Error`.
+ ///
+ /// If the failure this wrapped carried a backtrace, that backtrace will
+ /// be returned. Otherwise, the backtrace will have been constructed at
+ /// the point that failure was cast into the `Error` type.
+ pub fn backtrace(&self) -> &Backtrace {
+ self.inner.failure().backtrace().unwrap_or(&self.inner.backtrace)
+ }
+
+ /// Provides context for this `Error`.
+ ///
+ /// This can provide additional information about this error, appropriate
+ /// to the semantics of the current layer. That is, if you have a
+ /// lower-level error, such as an IO error, you can provide additional context
+ /// about what that error means in the context of your function. This
+ /// gives users of this function more information about what has gone
+ /// wrong.
+ ///
+ /// This takes any type that implements `Display`, as well as
+ /// `Send`/`Sync`/`'static`. In practice, this means it can take a `String`
+ /// or a string literal, or a failure, or some other custom context-carrying
+ /// type.
+ pub fn context<D: Display + Send + Sync + 'static>(self, context: D) -> Context<D> {
+ Context::with_err(context, self)
+ }
+
+ /// Wraps `Error` in a compatibility type.
+ ///
+ /// This type implements the `Error` trait from `std::error`. If you need
+ /// to pass failure's `Error` to an interface that takes any `Error`, you
+ /// can use this method to get a compatible type.
+ pub fn compat(self) -> Compat<Error> {
+ Compat { error: self }
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type.
+ ///
+ /// This downcasts by value, returning an owned `T` if the underlying
+ /// failure is of the type `T`. For this reason it returns a `Result` - in
+ /// the case that the underlying error is of a different type, the
+ /// original `Error` is returned.
+ pub fn downcast<T: Fail>(self) -> Result<T, Error> {
+ let ret: Option<T> = self.downcast_ref().map(|fail| {
+ unsafe {
+ // drop the backtrace
+ let _ = ptr::read(&self.inner.backtrace as *const Backtrace);
+ // read out the fail type
+ ptr::read(fail as *const T)
+ }
+ });
+ match ret {
+ Some(ret) => {
+ // forget self (backtrace is dropped, failure is moved
+ mem::forget(self);
+ Ok(ret)
+ }
+ _ => Err(self)
+ }
+ }
+
+ /// Returns the "root cause" of this error - the last value in the
+ /// cause chain which does not return an underlying `cause`.
+ pub fn root_cause(&self) -> &Fail {
+ ::find_root_cause(self.cause())
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type by
+ /// reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
+ self.inner.failure().downcast_ref()
+ }
+
+ /// Attempts to downcast this `Error` to a particular `Fail` type by
+ /// mutable reference.
+ ///
+ /// If the underlying error is not of type `T`, this will return `None`.
+ pub fn downcast_mut<T: Fail>(&mut self) -> Option<&mut T> {
+ self.inner.failure_mut().downcast_mut()
+ }
+
+ /// Returns a iterator over the causes of the `Error`, beginning with
+ /// the failure returned by the `cause` method and ending with the failure
+ /// returned by `root_cause`.
+ pub fn causes(&self) -> Causes {
+ Causes { fail: Some(self.cause()) }
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(self.inner.failure(), f)
+ }
+}
+
+impl Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.inner.backtrace.is_none() {
+ Debug::fmt(self.inner.failure(), f)
+ } else {
+ write!(f, "{:?}\n\n{:?}", self.inner.failure(), self.inner.backtrace)
+ }
+ }
+}
+
+impl Drop for Error {
+ fn drop(&mut self) {
+ unsafe {
+ let layout = {
+ let header = Layout::new::<InnerHeader>();
+ header.extend(Layout::for_value(self.inner.failure())).unwrap().0
+ };
+ Heap.dealloc(self.inner as *const _ as *const u8 as *mut u8, layout);
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use std::mem::size_of;
+ use std::io;
+
+ use super::Error;
+
+ #[test]
+ fn assert_error_is_just_data() {
+ fn assert_just_data<T: Send + Sync + 'static>() { }
+ assert_just_data::<Error>();
+ }
+
+ #[test]
+ fn assert_is_one_word() {
+ assert_eq!(size_of::<Error>(), size_of::<usize>());
+ }
+
+ #[test]
+ fn methods_seem_to_work() {
+ let io_error: io::Error = io::Error::new(io::ErrorKind::NotFound, "test");
+ let error: Error = io::Error::new(io::ErrorKind::NotFound, "test").into();
+ assert!(error.downcast_ref::<io::Error>().is_some());
+ let _: ::Backtrace = *error.backtrace();
+ assert_eq!(format!("{:?}", io_error), format!("{:?}", error));
+ assert_eq!(format!("{}", io_error), format!("{}", error));
+ drop(error);
+ assert!(true);
+ }
+}
diff --git a/third_party/rust/failure/src/sync_failure.rs b/third_party/rust/failure/src/sync_failure.rs
new file mode 100644
index 0000000000..63e966cdd5
--- /dev/null
+++ b/third_party/rust/failure/src/sync_failure.rs
@@ -0,0 +1,97 @@
+use Fail;
+use std::error::Error;
+use std::fmt::{self, Debug, Display};
+use std::sync::Mutex;
+
+/// Wrapper for `std` errors to make them `Sync`.
+///
+/// This exists to coerce existing types that are only `Error + Send +
+/// 'static` into a `Fail`-compatible representation, most notably for
+/// types generated by `error-chain`.
+///
+/// Unfortunately, this requires wrapping the error in a `Mutex`, which must
+/// be locked for every `Debug`/`Display`. Therefore, this should be
+/// something of a last resort in making the error work with `failure`.
+///
+pub struct SyncFailure<T> {
+ inner: Mutex<T>,
+}
+
+impl<E: Error + Send + 'static> SyncFailure<E> {
+ /// Wraps a non-`Sync` `Error` in order to make it implement `Fail`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// extern crate failure;
+ ///
+ /// # use std::error::Error as StdError;
+ /// # use std::fmt::{self, Display};
+ /// use failure::{Error, SyncFailure};
+ /// use std::cell::RefCell;
+ ///
+ /// #[derive(Debug)]
+ /// struct NonSyncError {
+ /// // RefCells are non-Sync, so structs containing them will be
+ /// // non-Sync as well.
+ /// count: RefCell<usize>,
+ /// }
+ ///
+ /// // implement Display/Error for NonSyncError...
+ /// #
+ /// # impl StdError for NonSyncError {
+ /// # fn description(&self) -> &str {
+ /// # "oops!"
+ /// # }
+ /// # }
+ /// #
+ /// # impl Display for NonSyncError {
+ /// # fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ /// # write!(f, "oops!")
+ /// # }
+ /// # }
+ ///
+ /// fn returns_error() -> Result<(), NonSyncError> {
+ /// // Do stuff
+ /// # Ok(())
+ /// }
+ ///
+ /// fn my_function() -> Result<(), Error> {
+ /// // without the map_err here, we end up with a compile error
+ /// // complaining that NonSyncError doesn't implement Sync.
+ /// returns_error().map_err(SyncFailure::new)?;
+ /// // Do more stuff
+ /// # Ok(())
+ /// }
+ /// #
+ /// # fn main() {
+ /// # my_function().unwrap();
+ /// # }
+ /// ```
+ ///
+ pub fn new(err: E) -> Self {
+ SyncFailure {
+ inner: Mutex::new(err),
+ }
+ }
+}
+
+impl<T> Display for SyncFailure<T>
+where
+ T: Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.inner.lock().unwrap().fmt(f)
+ }
+}
+
+impl<T> Debug for SyncFailure<T>
+where
+ T: Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ (*self.inner.lock().unwrap()).fmt(f)
+ }
+}
+
+impl<E: Error + Send + 'static> Fail for SyncFailure<E> {}