summaryrefslogtreecommitdiffstats
path: root/third_party/rust/anyhow/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
commit9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/rust/anyhow/src
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/anyhow/src')
-rw-r--r--third_party/rust/anyhow/src/backtrace.rs401
-rw-r--r--third_party/rust/anyhow/src/chain.rs102
-rw-r--r--third_party/rust/anyhow/src/context.rs193
-rw-r--r--third_party/rust/anyhow/src/ensure.rs834
-rw-r--r--third_party/rust/anyhow/src/error.rs992
-rw-r--r--third_party/rust/anyhow/src/fmt.rs155
-rw-r--r--third_party/rust/anyhow/src/kind.rs116
-rw-r--r--third_party/rust/anyhow/src/lib.rs680
-rw-r--r--third_party/rust/anyhow/src/macros.rs231
-rw-r--r--third_party/rust/anyhow/src/ptr.rs199
-rw-r--r--third_party/rust/anyhow/src/wrapper.rs81
11 files changed, 3984 insertions, 0 deletions
diff --git a/third_party/rust/anyhow/src/backtrace.rs b/third_party/rust/anyhow/src/backtrace.rs
new file mode 100644
index 0000000000..23c0c85ce2
--- /dev/null
+++ b/third_party/rust/anyhow/src/backtrace.rs
@@ -0,0 +1,401 @@
+#[cfg(backtrace)]
+pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};
+
+#[cfg(all(not(backtrace), feature = "backtrace"))]
+pub(crate) use self::capture::{Backtrace, BacktraceStatus};
+
+#[cfg(not(any(backtrace, feature = "backtrace")))]
+pub(crate) enum Backtrace {}
+
+#[cfg(backtrace)]
+macro_rules! impl_backtrace {
+ () => {
+ std::backtrace::Backtrace
+ };
+}
+
+#[cfg(all(not(backtrace), feature = "backtrace"))]
+macro_rules! impl_backtrace {
+ () => {
+ impl core::fmt::Debug + core::fmt::Display
+ };
+}
+
+#[cfg(any(backtrace, feature = "backtrace"))]
+macro_rules! backtrace {
+ () => {
+ Some(crate::backtrace::Backtrace::capture())
+ };
+}
+
+#[cfg(not(any(backtrace, feature = "backtrace")))]
+macro_rules! backtrace {
+ () => {
+ None
+ };
+}
+
+#[cfg(backtrace)]
+macro_rules! backtrace_if_absent {
+ ($err:expr) => {
+ match ($err as &dyn std::error::Error).request_ref::<std::backtrace::Backtrace>() {
+ Some(_) => None,
+ None => backtrace!(),
+ }
+ };
+}
+
+#[cfg(all(feature = "std", not(backtrace), feature = "backtrace"))]
+macro_rules! backtrace_if_absent {
+ ($err:expr) => {
+ backtrace!()
+ };
+}
+
+#[cfg(all(feature = "std", not(backtrace), not(feature = "backtrace")))]
+macro_rules! backtrace_if_absent {
+ ($err:expr) => {
+ None
+ };
+}
+
+#[cfg(all(not(backtrace), feature = "backtrace"))]
+mod capture {
+ use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
+ use core::cell::UnsafeCell;
+ use core::fmt::{self, Debug, Display};
+ use core::sync::atomic::{AtomicUsize, Ordering};
+ use std::borrow::Cow;
+ use std::env;
+ use std::path::{self, Path, PathBuf};
+ use std::sync::Once;
+
+ pub(crate) struct Backtrace {
+ inner: Inner,
+ }
+
+ pub(crate) enum BacktraceStatus {
+ Unsupported,
+ Disabled,
+ Captured,
+ }
+
+ enum Inner {
+ Unsupported,
+ Disabled,
+ Captured(LazilyResolvedCapture),
+ }
+
+ struct Capture {
+ actual_start: usize,
+ resolved: bool,
+ frames: Vec<BacktraceFrame>,
+ }
+
+ struct BacktraceFrame {
+ frame: Frame,
+ symbols: Vec<BacktraceSymbol>,
+ }
+
+ struct BacktraceSymbol {
+ name: Option<Vec<u8>>,
+ filename: Option<BytesOrWide>,
+ lineno: Option<u32>,
+ colno: Option<u32>,
+ }
+
+ enum BytesOrWide {
+ Bytes(Vec<u8>),
+ Wide(Vec<u16>),
+ }
+
+ impl Debug for Backtrace {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let capture = match &self.inner {
+ Inner::Unsupported => return fmt.write_str("<unsupported>"),
+ Inner::Disabled => return fmt.write_str("<disabled>"),
+ Inner::Captured(c) => c.force(),
+ };
+
+ let frames = &capture.frames[capture.actual_start..];
+
+ write!(fmt, "Backtrace ")?;
+
+ let mut dbg = fmt.debug_list();
+
+ for frame in frames {
+ if frame.frame.ip().is_null() {
+ continue;
+ }
+
+ dbg.entries(&frame.symbols);
+ }
+
+ dbg.finish()
+ }
+ }
+
+ impl Debug for BacktraceFrame {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let mut dbg = fmt.debug_list();
+ dbg.entries(&self.symbols);
+ dbg.finish()
+ }
+ }
+
+ impl Debug for BacktraceSymbol {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(fmt, "{{ ")?;
+
+ if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) {
+ write!(fmt, "fn: \"{:#}\"", fn_name)?;
+ } else {
+ write!(fmt, "fn: <unknown>")?;
+ }
+
+ if let Some(fname) = self.filename.as_ref() {
+ write!(fmt, ", file: \"{:?}\"", fname)?;
+ }
+
+ if let Some(line) = self.lineno {
+ write!(fmt, ", line: {:?}", line)?;
+ }
+
+ write!(fmt, " }}")
+ }
+ }
+
+ impl Debug for BytesOrWide {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ output_filename(
+ fmt,
+ match self {
+ BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
+ BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
+ },
+ PrintFmt::Short,
+ env::current_dir().as_ref().ok(),
+ )
+ }
+ }
+
+ impl Backtrace {
+ fn enabled() -> bool {
+ static ENABLED: AtomicUsize = AtomicUsize::new(0);
+ match ENABLED.load(Ordering::Relaxed) {
+ 0 => {}
+ 1 => return false,
+ _ => return true,
+ }
+ let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
+ Some(s) => s != "0",
+ None => match env::var_os("RUST_BACKTRACE") {
+ Some(s) => s != "0",
+ None => false,
+ },
+ };
+ ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
+ enabled
+ }
+
+ #[inline(never)] // want to make sure there's a frame here to remove
+ pub(crate) fn capture() -> Backtrace {
+ if Backtrace::enabled() {
+ Backtrace::create(Backtrace::capture as usize)
+ } else {
+ let inner = Inner::Disabled;
+ Backtrace { inner }
+ }
+ }
+
+ // Capture a backtrace which starts just before the function addressed
+ // by `ip`
+ fn create(ip: usize) -> Backtrace {
+ let mut frames = Vec::new();
+ let mut actual_start = None;
+ backtrace::trace(|frame| {
+ frames.push(BacktraceFrame {
+ frame: frame.clone(),
+ symbols: Vec::new(),
+ });
+ if frame.symbol_address() as usize == ip && actual_start.is_none() {
+ actual_start = Some(frames.len() + 1);
+ }
+ true
+ });
+
+ // If no frames came out assume that this is an unsupported platform
+ // since `backtrace` doesn't provide a way of learning this right
+ // now, and this should be a good enough approximation.
+ let inner = if frames.is_empty() {
+ Inner::Unsupported
+ } else {
+ Inner::Captured(LazilyResolvedCapture::new(Capture {
+ actual_start: actual_start.unwrap_or(0),
+ frames,
+ resolved: false,
+ }))
+ };
+
+ Backtrace { inner }
+ }
+
+ pub(crate) fn status(&self) -> BacktraceStatus {
+ match self.inner {
+ Inner::Unsupported => BacktraceStatus::Unsupported,
+ Inner::Disabled => BacktraceStatus::Disabled,
+ Inner::Captured(_) => BacktraceStatus::Captured,
+ }
+ }
+ }
+
+ impl Display for Backtrace {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let capture = match &self.inner {
+ Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
+ Inner::Disabled => return fmt.write_str("disabled backtrace"),
+ Inner::Captured(c) => c.force(),
+ };
+
+ let full = fmt.alternate();
+ let (frames, style) = if full {
+ (&capture.frames[..], PrintFmt::Full)
+ } else {
+ (&capture.frames[capture.actual_start..], PrintFmt::Short)
+ };
+
+ // When printing paths we try to strip the cwd if it exists,
+ // otherwise we just print the path as-is. Note that we also only do
+ // this for the short format, because if it's full we presumably
+ // want to print everything.
+ let cwd = env::current_dir();
+ let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
+ output_filename(fmt, path, style, cwd.as_ref().ok())
+ };
+
+ let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
+ f.add_context()?;
+ for frame in frames {
+ let mut f = f.frame();
+ if frame.symbols.is_empty() {
+ f.print_raw(frame.frame.ip(), None, None, None)?;
+ } else {
+ for symbol in frame.symbols.iter() {
+ f.print_raw_with_column(
+ frame.frame.ip(),
+ symbol.name.as_ref().map(|b| SymbolName::new(b)),
+ symbol.filename.as_ref().map(|b| match b {
+ BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
+ BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
+ }),
+ symbol.lineno,
+ symbol.colno,
+ )?;
+ }
+ }
+ }
+ f.finish()?;
+ Ok(())
+ }
+ }
+
+ struct LazilyResolvedCapture {
+ sync: Once,
+ capture: UnsafeCell<Capture>,
+ }
+
+ impl LazilyResolvedCapture {
+ fn new(capture: Capture) -> Self {
+ LazilyResolvedCapture {
+ sync: Once::new(),
+ capture: UnsafeCell::new(capture),
+ }
+ }
+
+ fn force(&self) -> &Capture {
+ self.sync.call_once(|| {
+ // Safety: This exclusive reference can't overlap with any
+ // others. `Once` guarantees callers will block until this
+ // closure returns. `Once` also guarantees only a single caller
+ // will enter this closure.
+ unsafe { &mut *self.capture.get() }.resolve();
+ });
+
+ // Safety: This shared reference can't overlap with the exclusive
+ // reference above.
+ unsafe { &*self.capture.get() }
+ }
+ }
+
+ // Safety: Access to the inner value is synchronized using a thread-safe
+ // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
+ unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
+
+ impl Capture {
+ fn resolve(&mut self) {
+ // If we're already resolved, nothing to do!
+ if self.resolved {
+ return;
+ }
+ self.resolved = true;
+
+ for frame in self.frames.iter_mut() {
+ let symbols = &mut frame.symbols;
+ let frame = &frame.frame;
+ backtrace::resolve_frame(frame, |symbol| {
+ symbols.push(BacktraceSymbol {
+ name: symbol.name().map(|m| m.as_bytes().to_vec()),
+ filename: symbol.filename_raw().map(|b| match b {
+ BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
+ BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
+ }),
+ lineno: symbol.lineno(),
+ colno: symbol.colno(),
+ });
+ });
+ }
+ }
+ }
+
+ // Prints the filename of the backtrace frame.
+ fn output_filename(
+ fmt: &mut fmt::Formatter,
+ bows: BytesOrWideString,
+ print_fmt: PrintFmt,
+ cwd: Option<&PathBuf>,
+ ) -> fmt::Result {
+ let file: Cow<Path> = match bows {
+ #[cfg(unix)]
+ BytesOrWideString::Bytes(bytes) => {
+ use std::os::unix::ffi::OsStrExt;
+ Path::new(std::ffi::OsStr::from_bytes(bytes)).into()
+ }
+ #[cfg(not(unix))]
+ BytesOrWideString::Bytes(bytes) => {
+ Path::new(std::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
+ }
+ #[cfg(windows)]
+ BytesOrWideString::Wide(wide) => {
+ use std::os::windows::ffi::OsStringExt;
+ Cow::Owned(std::ffi::OsString::from_wide(wide).into())
+ }
+ #[cfg(not(windows))]
+ BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
+ };
+ if print_fmt == PrintFmt::Short && file.is_absolute() {
+ if let Some(cwd) = cwd {
+ if let Ok(stripped) = file.strip_prefix(&cwd) {
+ if let Some(s) = stripped.to_str() {
+ return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
+ }
+ }
+ }
+ }
+ Display::fmt(&file.display(), fmt)
+ }
+}
+
+fn _assert_send_sync() {
+ fn _assert<T: Send + Sync>() {}
+ _assert::<Backtrace>();
+}
diff --git a/third_party/rust/anyhow/src/chain.rs b/third_party/rust/anyhow/src/chain.rs
new file mode 100644
index 0000000000..f7baff29f1
--- /dev/null
+++ b/third_party/rust/anyhow/src/chain.rs
@@ -0,0 +1,102 @@
+use self::ChainState::*;
+use crate::StdError;
+
+#[cfg(feature = "std")]
+use std::vec;
+
+#[cfg(feature = "std")]
+pub(crate) use crate::Chain;
+
+#[cfg(not(feature = "std"))]
+pub(crate) struct Chain<'a> {
+ state: ChainState<'a>,
+}
+
+#[derive(Clone)]
+pub(crate) enum ChainState<'a> {
+ Linked {
+ next: Option<&'a (dyn StdError + 'static)>,
+ },
+ #[cfg(feature = "std")]
+ Buffered {
+ rest: vec::IntoIter<&'a (dyn StdError + 'static)>,
+ },
+}
+
+impl<'a> Chain<'a> {
+ #[cold]
+ pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
+ Chain {
+ state: ChainState::Linked { next: Some(head) },
+ }
+ }
+}
+
+impl<'a> Iterator for Chain<'a> {
+ type Item = &'a (dyn StdError + 'static);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match &mut self.state {
+ Linked { next } => {
+ let error = (*next)?;
+ *next = error.source();
+ Some(error)
+ }
+ #[cfg(feature = "std")]
+ Buffered { rest } => rest.next(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.len();
+ (len, Some(len))
+ }
+}
+
+#[cfg(feature = "std")]
+impl DoubleEndedIterator for Chain<'_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ match &mut self.state {
+ Linked { mut next } => {
+ let mut rest = Vec::new();
+ while let Some(cause) = next {
+ next = cause.source();
+ rest.push(cause);
+ }
+ let mut rest = rest.into_iter();
+ let last = rest.next_back();
+ self.state = Buffered { rest };
+ last
+ }
+ Buffered { rest } => rest.next_back(),
+ }
+ }
+}
+
+impl ExactSizeIterator for Chain<'_> {
+ fn len(&self) -> usize {
+ match &self.state {
+ Linked { mut next } => {
+ let mut len = 0;
+ while let Some(cause) = next {
+ next = cause.source();
+ len += 1;
+ }
+ len
+ }
+ #[cfg(feature = "std")]
+ Buffered { rest } => rest.len(),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Default for Chain<'_> {
+ fn default() -> Self {
+ Chain {
+ state: ChainState::Buffered {
+ rest: Vec::new().into_iter(),
+ },
+ }
+ }
+}
diff --git a/third_party/rust/anyhow/src/context.rs b/third_party/rust/anyhow/src/context.rs
new file mode 100644
index 0000000000..9df86937bd
--- /dev/null
+++ b/third_party/rust/anyhow/src/context.rs
@@ -0,0 +1,193 @@
+use crate::error::ContextError;
+use crate::{Context, Error, StdError};
+use core::convert::Infallible;
+use core::fmt::{self, Debug, Display, Write};
+
+#[cfg(backtrace)]
+use std::any::{Demand, Provider};
+
+mod ext {
+ use super::*;
+
+ pub trait StdError {
+ fn ext_context<C>(self, context: C) -> Error
+ where
+ C: Display + Send + Sync + 'static;
+ }
+
+ #[cfg(feature = "std")]
+ impl<E> StdError for E
+ where
+ E: std::error::Error + Send + Sync + 'static,
+ {
+ fn ext_context<C>(self, context: C) -> Error
+ where
+ C: Display + Send + Sync + 'static,
+ {
+ let backtrace = backtrace_if_absent!(&self);
+ Error::from_context(context, self, backtrace)
+ }
+ }
+
+ impl StdError for Error {
+ fn ext_context<C>(self, context: C) -> Error
+ where
+ C: Display + Send + Sync + 'static,
+ {
+ self.context(context)
+ }
+ }
+}
+
+impl<T, E> Context<T, E> for Result<T, E>
+where
+ E: ext::StdError + Send + Sync + 'static,
+{
+ fn context<C>(self, context: C) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static,
+ {
+ // Not using map_err to save 2 useless frames off the captured backtrace
+ // in ext_context.
+ match self {
+ Ok(ok) => Ok(ok),
+ Err(error) => Err(error.ext_context(context)),
+ }
+ }
+
+ fn with_context<C, F>(self, context: F) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static,
+ F: FnOnce() -> C,
+ {
+ match self {
+ Ok(ok) => Ok(ok),
+ Err(error) => Err(error.ext_context(context())),
+ }
+ }
+}
+
+/// ```
+/// # type T = ();
+/// #
+/// use anyhow::{Context, Result};
+///
+/// fn maybe_get() -> Option<T> {
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unimplemented!()
+/// }
+///
+/// fn demo() -> Result<()> {
+/// let t = maybe_get().context("there is no T")?;
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unimplemented!()
+/// }
+/// ```
+impl<T> Context<T, Infallible> for Option<T> {
+ fn context<C>(self, context: C) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static,
+ {
+ // Not using ok_or_else to save 2 useless frames off the captured
+ // backtrace.
+ match self {
+ Some(ok) => Ok(ok),
+ None => Err(Error::from_display(context, backtrace!())),
+ }
+ }
+
+ fn with_context<C, F>(self, context: F) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static,
+ F: FnOnce() -> C,
+ {
+ match self {
+ Some(ok) => Ok(ok),
+ None => Err(Error::from_display(context(), backtrace!())),
+ }
+ }
+}
+
+impl<C, E> Debug for ContextError<C, E>
+where
+ C: Display,
+ E: Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Error")
+ .field("context", &Quoted(&self.context))
+ .field("source", &self.error)
+ .finish()
+ }
+}
+
+impl<C, E> Display for ContextError<C, E>
+where
+ C: Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.context, f)
+ }
+}
+
+impl<C, E> StdError for ContextError<C, E>
+where
+ C: Display,
+ E: StdError + 'static,
+{
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ Some(&self.error)
+ }
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ StdError::provide(&self.error, demand);
+ }
+}
+
+impl<C> StdError for ContextError<C, Error>
+where
+ C: Display,
+{
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
+ }
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ Provider::provide(&self.error, demand);
+ }
+}
+
+struct Quoted<C>(C);
+
+impl<C> Debug for Quoted<C>
+where
+ C: Display,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_char('"')?;
+ Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?;
+ formatter.write_char('"')?;
+ Ok(())
+ }
+}
+
+impl Write for Quoted<&mut fmt::Formatter<'_>> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ Display::fmt(&s.escape_debug(), self.0)
+ }
+}
+
+pub(crate) mod private {
+ use super::*;
+
+ pub trait Sealed {}
+
+ impl<T, E> Sealed for Result<T, E> where E: ext::StdError {}
+ impl<T> Sealed for Option<T> {}
+}
diff --git a/third_party/rust/anyhow/src/ensure.rs b/third_party/rust/anyhow/src/ensure.rs
new file mode 100644
index 0000000000..0ab4471231
--- /dev/null
+++ b/third_party/rust/anyhow/src/ensure.rs
@@ -0,0 +1,834 @@
+use crate::Error;
+use alloc::string::String;
+use core::fmt::{self, Debug, Write};
+use core::mem::MaybeUninit;
+use core::ptr;
+use core::slice;
+use core::str;
+
+#[doc(hidden)]
+pub trait BothDebug {
+ fn __dispatch_ensure(self, msg: &'static str) -> Error;
+}
+
+impl<A, B> BothDebug for (A, B)
+where
+ A: Debug,
+ B: Debug,
+{
+ fn __dispatch_ensure(self, msg: &'static str) -> Error {
+ render(msg, &self.0, &self.1)
+ }
+}
+
+#[doc(hidden)]
+pub trait NotBothDebug {
+ fn __dispatch_ensure(self, msg: &'static str) -> Error;
+}
+
+impl<A, B> NotBothDebug for &(A, B) {
+ fn __dispatch_ensure(self, msg: &'static str) -> Error {
+ Error::msg(msg)
+ }
+}
+
+struct Buf {
+ bytes: [MaybeUninit<u8>; 40],
+ written: usize,
+}
+
+impl Buf {
+ fn new() -> Self {
+ Buf {
+ bytes: [MaybeUninit::uninit(); 40],
+ written: 0,
+ }
+ }
+
+ fn as_str(&self) -> &str {
+ unsafe {
+ str::from_utf8_unchecked(slice::from_raw_parts(
+ self.bytes.as_ptr().cast::<u8>(),
+ self.written,
+ ))
+ }
+ }
+}
+
+impl Write for Buf {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ if s.bytes().any(|b| b == b' ' || b == b'\n') {
+ return Err(fmt::Error);
+ }
+
+ let remaining = self.bytes.len() - self.written;
+ if s.len() > remaining {
+ return Err(fmt::Error);
+ }
+
+ unsafe {
+ ptr::copy_nonoverlapping(
+ s.as_ptr(),
+ self.bytes.as_mut_ptr().add(self.written).cast::<u8>(),
+ s.len(),
+ );
+ }
+ self.written += s.len();
+ Ok(())
+ }
+}
+
+fn render(msg: &'static str, lhs: &dyn Debug, rhs: &dyn Debug) -> Error {
+ let mut lhs_buf = Buf::new();
+ if fmt::write(&mut lhs_buf, format_args!("{:?}", lhs)).is_ok() {
+ let mut rhs_buf = Buf::new();
+ if fmt::write(&mut rhs_buf, format_args!("{:?}", rhs)).is_ok() {
+ let lhs_str = lhs_buf.as_str();
+ let rhs_str = rhs_buf.as_str();
+ // "{msg} ({lhs} vs {rhs})"
+ let len = msg.len() + 2 + lhs_str.len() + 4 + rhs_str.len() + 1;
+ let mut string = String::with_capacity(len);
+ string.push_str(msg);
+ string.push_str(" (");
+ string.push_str(lhs_str);
+ string.push_str(" vs ");
+ string.push_str(rhs_str);
+ string.push(')');
+ return Error::msg(string);
+ }
+ }
+ Error::msg(msg)
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __parse_ensure {
+ (atom () $bail:tt $fuel:tt {($($rhs:tt)+) ($($lhs:tt)+) $op:tt} $dup:tt $(,)?) => {
+ $crate::__fancy_ensure!($($lhs)+, $op, $($rhs)+)
+ };
+
+ // low precedence control flow constructs
+
+ (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt return $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+
+ (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt break $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+
+ (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt continue $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+
+ (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt yield $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+
+ (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt move $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+
+ // unary operators
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($deref:tt $($dup:tt)*) * $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $deref) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($not:tt $($dup:tt)*) ! $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $not) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($let:tt $($dup:tt)*) let $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $let) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($life:tt $colon:tt $($dup:tt)*) $label:lifetime : $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $life $colon) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) &mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $mut:tt $($dup:tt)*) &&mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // control flow constructs
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($if:tt $($dup:tt)*) if $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $if) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($match:tt $($dup:tt)*) match $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $match) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($while:tt $($dup:tt)*) while $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $while) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $($dup:tt)*) for $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat (cond $stack) $bail ($($fuel)*) {($($buf)* $for) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom (cond $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(cond $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $if:tt $($dup:tt)*) else if $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $else $if) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $brace:tt $($dup:tt)*) else {$($block:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $else $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (cond $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) $parse $dup $($rest)*)
+ };
+
+ // atomic expressions
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($array:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($loop:tt $block:tt $($dup:tt)*) loop {$($body:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $loop $block) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $block:tt $($dup:tt)*) async {$($body:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $block) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $move:tt $block:tt $($dup:tt)*) async move {$($body:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $move $block) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $block:tt $($dup:tt)*) unsafe {$($body:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $unsafe $block) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // path expressions
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (qpath (epath (atom $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: << $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
+ };
+
+ (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: <- $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (- $($rest)*) - $($rest)*)
+ };
+
+ (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(epath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
+ };
+
+ // trailer expressions
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($call:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($index:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($init:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($question:tt $($dup:tt)*) ? $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $question) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: < $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $($dup:tt)*) . $i:ident :: << $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $($dup:tt)*) . $i:ident :: <- $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons <) $($parse)*} (- $($rest)*) - $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $($dup:tt)*) . $field:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $field) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $index:tt $($dup:tt)*) . $lit:literal $($rest:tt)*) => {
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $index) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (atom $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // types
+
+ (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $const:tt $($dup:tt)*) *const $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $const) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $mut:tt $($dup:tt)*) *mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $mut:tt $($dup:tt)*) & $l:lifetime mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) & mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $($dup:tt)*) & $l:lifetime $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $mut:tt $($dup:tt)*) && $l:lifetime mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) && mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $($dup:tt)*) && $l:lifetime $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $(extern $($abi:literal)?)? fn $($dup:tt)*) unsafe $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $unsafe) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt $abi:literal fn $($dup:tt)*) extern $lit:literal $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern $abi) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt fn $($dup:tt)*) extern $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $arrow:tt $($dup:tt)*) fn ($($args:tt)*) -> $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $fn $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $($dup:tt)*) fn ($($args:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $fn $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($impl:tt $($dup:tt)*) impl $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $impl) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dyn:tt $($dup:tt)*) dyn $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $dyn) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($never:tt $($dup:tt)*) ! $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $never) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $langle:tt $($dup:tt)*) for < $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (type $stack) $bail ($($fuel)*) {($($buf)* $for $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // path types
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (qpath (tpath $stack)) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt << $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* <) $($parse)*} (< $($rest)*) < $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt <- $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* <) $($parse)*} (- $($rest)*) - $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: << $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: <- $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (- $($rest)*) - $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $arrow:tt $($dup:tt)*) ($($args:tt)*) -> $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $arrow:tt $($dup:tt)*) :: ($($args:tt)*) -> $($rest:tt)*) => {
+ $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $colons $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (tpath $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
+ $crate::__parse_ensure!(object $stack $bail ($($fuel)*) $parse $dup $($rest)*)
+ };
+
+ // qualified paths
+
+ (qpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $($dup:tt)*) > :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (qpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (qpath $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // trait objects
+
+ (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $colons:tt $($dup:tt)*) + :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $($dup:tt)*) + $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (object ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
+ };
+
+ // angle bracketed generic arguments
+
+ (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* >) $($parse)*} (> $($rest)*) > $($rest)*)
+ };
+
+ (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
+ $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $life:lifetime $($rest:tt)*) => {
+ $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $life) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assoc:ident $eq:tt $($dup:tt)*) $ident:ident = $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) {($($buf)* $assoc $eq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (generic $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) $parse $dup $($rest)*)
+ };
+
+ (arglist $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($comma:tt $($dup:tt)*) , $($rest:tt)*) => {
+ $crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $comma) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => {
+ $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* >) $($parse)*} (> $($rest)*) > $($rest)*)
+ };
+
+ // patterns
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($pipe:tt $($dup:tt)*) | $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $pipe) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) = $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($in:tt $($dup:tt)*) in $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $in) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ref:tt $($dup:tt)*) ref $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $ref) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mut:tt $($dup:tt)*) mut $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $mut) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($at:tt $($dup:tt)*) @ $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $at) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) .. $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) ..= $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($content:tt)*} $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
+ $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
+ $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(type (qpath (epath (pat $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // high precedence binary operators
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($add:tt $($dup:tt)*) + $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $add) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($sub:tt $($dup:tt)*) - $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $sub) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mul:tt $($dup:tt)*) * $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $mul) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($div:tt $($dup:tt)*) / $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $div) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rem:tt $($dup:tt)*) % $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rem) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxor:tt $($dup:tt)*) ^ $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitxor) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitand:tt $($dup:tt)*) & $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitand) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitor:tt $($dup:tt)*) | $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitor) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shl:tt $($dup:tt)*) << $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shl) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shr:tt $($dup:tt)*) >> $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shr) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // comparison binary operators
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $eq} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $le} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $le) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $lt} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lt) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ne} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ne) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ge} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ge) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $gt} ($($rest)*) $($rest)*)
+ };
+
+ (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $gt) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // low precedence binary operators
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($or:tt $($dup:tt)*) || $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $or) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assign:tt $($dup:tt)*) = $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $assign) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($addeq:tt $($dup:tt)*) += $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $addeq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($subeq:tt $($dup:tt)*) -= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $subeq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($muleq:tt $($dup:tt)*) *= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $muleq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($diveq:tt $($dup:tt)*) /= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $diveq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($remeq:tt $($dup:tt)*) %= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $remeq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxoreq:tt $($dup:tt)*) ^= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitxoreq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitandeq:tt $($dup:tt)*) &= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitandeq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitoreq:tt $($dup:tt)*) |= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitoreq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shleq:tt $($dup:tt)*) <<= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shleq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shreq:tt $($dup:tt)*) >>= $($rest:tt)*) => {
+ $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shreq) $($parse)*} ($($rest)*) $($rest)*)
+ };
+
+ // unrecognized expression
+
+ ($state:tt $stack:tt ($($bail:tt)*) $($rest:tt)*) => {
+ $crate::__fallback_ensure!($($bail)*)
+ };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __fancy_ensure {
+ ($lhs:expr, $op:tt, $rhs:expr) => {
+ match (&$lhs, &$rhs) {
+ (lhs, rhs) => {
+ if !(lhs $op rhs) {
+ #[allow(unused_imports)]
+ use $crate::__private::{BothDebug, NotBothDebug};
+ return Err((lhs, rhs).__dispatch_ensure(
+ $crate::__private::concat!(
+ "Condition failed: `",
+ $crate::__private::stringify!($lhs),
+ " ",
+ $crate::__private::stringify!($op),
+ " ",
+ $crate::__private::stringify!($rhs),
+ "`",
+ ),
+ ));
+ }
+ }
+ }
+ };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __fallback_ensure {
+ ($cond:expr $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::Error::msg(
+ $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
+ ));
+ }
+ };
+ ($cond:expr, $msg:literal $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($msg));
+ }
+ };
+ ($cond:expr, $err:expr $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($err));
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)*) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
+ }
+ };
+}
diff --git a/third_party/rust/anyhow/src/error.rs b/third_party/rust/anyhow/src/error.rs
new file mode 100644
index 0000000000..9f6ce8c10b
--- /dev/null
+++ b/third_party/rust/anyhow/src/error.rs
@@ -0,0 +1,992 @@
+use crate::backtrace::Backtrace;
+use crate::chain::Chain;
+#[cfg(any(feature = "std", anyhow_no_ptr_addr_of))]
+use crate::ptr::Mut;
+use crate::ptr::{Own, Ref};
+use crate::{Error, StdError};
+use alloc::boxed::Box;
+#[cfg(backtrace)]
+use core::any::Demand;
+use core::any::TypeId;
+use core::fmt::{self, Debug, Display};
+use core::mem::ManuallyDrop;
+#[cfg(not(anyhow_no_ptr_addr_of))]
+use core::ptr;
+use core::ptr::NonNull;
+
+#[cfg(feature = "std")]
+use core::ops::{Deref, DerefMut};
+
+impl Error {
+ /// Create a new error object from any error type.
+ ///
+ /// The error type must be threadsafe and `'static`, so that the `Error`
+ /// will be as well.
+ ///
+ /// If the error type does not provide a backtrace, a backtrace will be
+ /// created here to ensure that a backtrace exists.
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ #[cold]
+ #[must_use]
+ pub fn new<E>(error: E) -> Self
+ where
+ E: StdError + Send + Sync + 'static,
+ {
+ let backtrace = backtrace_if_absent!(&error);
+ Error::from_std(error, backtrace)
+ }
+
+ /// Create a new error object from a printable error message.
+ ///
+ /// If the argument implements std::error::Error, prefer `Error::new`
+ /// instead which preserves the underlying error's cause chain and
+ /// backtrace. If the argument may or may not implement std::error::Error
+ /// now or in the future, use `anyhow!(err)` which handles either way
+ /// correctly.
+ ///
+ /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
+ /// convenient in places where a function is preferable over a macro, such
+ /// as iterator or stream combinators:
+ ///
+ /// ```
+ /// # mod ffi {
+ /// # pub struct Input;
+ /// # pub struct Output;
+ /// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # use ffi::{Input, Output};
+ /// #
+ /// use anyhow::{Error, Result};
+ /// use futures::stream::{Stream, StreamExt, TryStreamExt};
+ ///
+ /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
+ /// where
+ /// S: Stream<Item = Input>,
+ /// {
+ /// stream
+ /// .then(ffi::do_some_work) // returns Result<Output, &str>
+ /// .map_err(Error::msg)
+ /// .try_collect()
+ /// .await
+ /// }
+ /// ```
+ #[cold]
+ #[must_use]
+ pub fn msg<M>(message: M) -> Self
+ where
+ M: Display + Debug + Send + Sync + 'static,
+ {
+ Error::from_adhoc(message, backtrace!())
+ }
+
+ #[cfg(feature = "std")]
+ #[cold]
+ pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
+ where
+ E: StdError + Send + Sync + 'static,
+ {
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<E>,
+ object_ref: object_ref::<E>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_mut: object_mut::<E>,
+ object_boxed: object_boxed::<E>,
+ object_downcast: object_downcast::<E>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: object_downcast_mut::<E>,
+ object_drop_rest: object_drop_front::<E>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: no_backtrace,
+ };
+
+ // Safety: passing vtable that operates on the right type E.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ #[cold]
+ pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
+ where
+ M: Display + Debug + Send + Sync + 'static,
+ {
+ use crate::wrapper::MessageError;
+ let error: MessageError<M> = MessageError(message);
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<MessageError<M>>,
+ object_ref: object_ref::<MessageError<M>>,
+ #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+ object_mut: object_mut::<MessageError<M>>,
+ object_boxed: object_boxed::<MessageError<M>>,
+ object_downcast: object_downcast::<M>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: object_downcast_mut::<M>,
+ object_drop_rest: object_drop_front::<M>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: no_backtrace,
+ };
+
+ // Safety: MessageError is repr(transparent) so it is okay for the
+ // vtable to allow casting the MessageError<M> to M.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ #[cold]
+ pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
+ where
+ M: Display + Send + Sync + 'static,
+ {
+ use crate::wrapper::DisplayError;
+ let error: DisplayError<M> = DisplayError(message);
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<DisplayError<M>>,
+ object_ref: object_ref::<DisplayError<M>>,
+ #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+ object_mut: object_mut::<DisplayError<M>>,
+ object_boxed: object_boxed::<DisplayError<M>>,
+ object_downcast: object_downcast::<M>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: object_downcast_mut::<M>,
+ object_drop_rest: object_drop_front::<M>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: no_backtrace,
+ };
+
+ // Safety: DisplayError is repr(transparent) so it is okay for the
+ // vtable to allow casting the DisplayError<M> to M.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ #[cfg(feature = "std")]
+ #[cold]
+ pub(crate) fn from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self
+ where
+ C: Display + Send + Sync + 'static,
+ E: StdError + Send + Sync + 'static,
+ {
+ let error: ContextError<C, E> = ContextError { context, error };
+
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<ContextError<C, E>>,
+ object_ref: object_ref::<ContextError<C, E>>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_mut: object_mut::<ContextError<C, E>>,
+ object_boxed: object_boxed::<ContextError<C, E>>,
+ object_downcast: context_downcast::<C, E>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: context_downcast_mut::<C, E>,
+ object_drop_rest: context_drop_rest::<C, E>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: no_backtrace,
+ };
+
+ // Safety: passing vtable that operates on the right type.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ #[cfg(feature = "std")]
+ #[cold]
+ pub(crate) fn from_boxed(
+ error: Box<dyn StdError + Send + Sync>,
+ backtrace: Option<Backtrace>,
+ ) -> Self {
+ use crate::wrapper::BoxedError;
+ let error = BoxedError(error);
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<BoxedError>,
+ object_ref: object_ref::<BoxedError>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_mut: object_mut::<BoxedError>,
+ object_boxed: object_boxed::<BoxedError>,
+ object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>,
+ object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: no_backtrace,
+ };
+
+ // Safety: BoxedError is repr(transparent) so it is okay for the vtable
+ // to allow casting to Box<dyn StdError + Send + Sync>.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ // Takes backtrace as argument rather than capturing it here so that the
+ // user sees one fewer layer of wrapping noise in the backtrace.
+ //
+ // Unsafe because the given vtable must have sensible behavior on the error
+ // value of type E.
+ #[cold]
+ unsafe fn construct<E>(
+ error: E,
+ vtable: &'static ErrorVTable,
+ backtrace: Option<Backtrace>,
+ ) -> Self
+ where
+ E: StdError + Send + Sync + 'static,
+ {
+ let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
+ vtable,
+ backtrace,
+ _object: error,
+ });
+ // Erase the concrete type of E from the compile-time type system. This
+ // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
+ // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
+ // result is a thin pointer. The necessary behavior for manipulating the
+ // underlying ErrorImpl<E> is preserved in the vtable provided by the
+ // caller rather than a builtin fat pointer vtable.
+ let inner = Own::new(inner).cast::<ErrorImpl>();
+ Error { inner }
+ }
+
+ /// Wrap the error value with additional context.
+ ///
+ /// For attaching context to a `Result` as it is propagated, the
+ /// [`Context`][crate::Context] extension trait may be more convenient than
+ /// this function.
+ ///
+ /// The primary reason to use `error.context(...)` instead of
+ /// `result.context(...)` via the `Context` trait would be if the context
+ /// needs to depend on some data held by the underlying error:
+ ///
+ /// ```
+ /// # use std::fmt::{self, Debug, Display};
+ /// #
+ /// # type T = ();
+ /// #
+ /// # impl std::error::Error for ParseError {}
+ /// # impl Debug for ParseError {
+ /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// # impl Display for ParseError {
+ /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// use anyhow::Result;
+ /// use std::fs::File;
+ /// use std::path::Path;
+ ///
+ /// struct ParseError {
+ /// line: usize,
+ /// column: usize,
+ /// }
+ ///
+ /// fn parse_impl(file: File) -> Result<T, ParseError> {
+ /// # const IGNORE: &str = stringify! {
+ /// ...
+ /// # };
+ /// # unimplemented!()
+ /// }
+ ///
+ /// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
+ /// let file = File::open(&path)?;
+ /// parse_impl(file).map_err(|error| {
+ /// let context = format!(
+ /// "only the first {} lines of {} are valid",
+ /// error.line, path.as_ref().display(),
+ /// );
+ /// anyhow::Error::new(error).context(context)
+ /// })
+ /// }
+ /// ```
+ #[cold]
+ #[must_use]
+ pub fn context<C>(self, context: C) -> Self
+ where
+ C: Display + Send + Sync + 'static,
+ {
+ let error: ContextError<C, Error> = ContextError {
+ context,
+ error: self,
+ };
+
+ let vtable = &ErrorVTable {
+ object_drop: object_drop::<ContextError<C, Error>>,
+ object_ref: object_ref::<ContextError<C, Error>>,
+ #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+ object_mut: object_mut::<ContextError<C, Error>>,
+ object_boxed: object_boxed::<ContextError<C, Error>>,
+ object_downcast: context_chain_downcast::<C>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: context_chain_downcast_mut::<C>,
+ object_drop_rest: context_chain_drop_rest::<C>,
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: context_backtrace::<C>,
+ };
+
+ // As the cause is anyhow::Error, we already have a backtrace for it.
+ let backtrace = None;
+
+ // Safety: passing vtable that operates on the right type.
+ unsafe { Error::construct(error, vtable, backtrace) }
+ }
+
+ /// Get the backtrace for this Error.
+ ///
+ /// In order for the backtrace to be meaningful, one of the two environment
+ /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
+ /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
+ /// expensive to capture in Rust, so we don't necessarily want to be
+ /// capturing them all over the place all the time.
+ ///
+ /// - If you want panics and errors to both have backtraces, set
+ /// `RUST_BACKTRACE=1`;
+ /// - If you want only errors to have backtraces, set
+ /// `RUST_LIB_BACKTRACE=1`;
+ /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
+ /// `RUST_LIB_BACKTRACE=0`.
+ ///
+ /// # Stability
+ ///
+ /// Standard library backtraces are only available on the nightly channel.
+ /// Tracking issue: [rust-lang/rust#53487][tracking].
+ ///
+ /// On stable compilers, this function is only available if the crate's
+ /// "backtrace" feature is enabled, and will use the `backtrace` crate as
+ /// the underlying backtrace implementation.
+ ///
+ /// ```toml
+ /// [dependencies]
+ /// anyhow = { version = "1.0", features = ["backtrace"] }
+ /// ```
+ ///
+ /// [tracking]: https://github.com/rust-lang/rust/issues/53487
+ #[cfg(any(backtrace, feature = "backtrace"))]
+ #[cfg_attr(doc_cfg, doc(cfg(any(nightly, feature = "backtrace"))))]
+ pub fn backtrace(&self) -> &impl_backtrace!() {
+ unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
+ }
+
+ /// An iterator of the chain of source errors contained by this Error.
+ ///
+ /// This iterator will visit every error in the cause chain of this error
+ /// object, beginning with the error that this error object was created
+ /// from.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use anyhow::Error;
+ /// use std::io;
+ ///
+ /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
+ /// for cause in error.chain() {
+ /// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
+ /// return Some(io_error.kind());
+ /// }
+ /// }
+ /// None
+ /// }
+ /// ```
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ #[cold]
+ pub fn chain(&self) -> Chain {
+ unsafe { ErrorImpl::chain(self.inner.by_ref()) }
+ }
+
+ /// The lowest level cause of this error &mdash; this error's cause's
+ /// cause's cause etc.
+ ///
+ /// The root cause is the last error in the iterator produced by
+ /// [`chain()`][Error::chain].
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ pub fn root_cause(&self) -> &(dyn StdError + 'static) {
+ self.chain().last().unwrap()
+ }
+
+ /// Returns true if `E` is the type held by this error object.
+ ///
+ /// For errors with context, this method returns true if `E` matches the
+ /// type of the context `C` **or** the type of the error on which the
+ /// context has been attached. For details about the interaction between
+ /// context and downcasting, [see here].
+ ///
+ /// [see here]: trait.Context.html#effect-on-downcasting
+ pub fn is<E>(&self) -> bool
+ where
+ E: Display + Debug + Send + Sync + 'static,
+ {
+ self.downcast_ref::<E>().is_some()
+ }
+
+ /// Attempt to downcast the error object to a concrete type.
+ pub fn downcast<E>(mut self) -> Result<E, Self>
+ where
+ E: Display + Debug + Send + Sync + 'static,
+ {
+ let target = TypeId::of::<E>();
+ let inner = self.inner.by_mut();
+ unsafe {
+ // Use vtable to find NonNull<()> which points to a value of type E
+ // somewhere inside the data structure.
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
+ Some(addr) => addr.by_mut().extend(),
+ None => return Err(self),
+ };
+ #[cfg(anyhow_no_ptr_addr_of)]
+ let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) {
+ Some(addr) => addr.extend(),
+ None => return Err(self),
+ };
+
+ // Prepare to read E out of the data structure. We'll drop the rest
+ // of the data structure separately so that E is not dropped.
+ let outer = ManuallyDrop::new(self);
+
+ // Read E from where the vtable found it.
+ let error = addr.cast::<E>().read();
+
+ // Drop rest of the data structure outside of E.
+ (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
+
+ Ok(error)
+ }
+ }
+
+ /// Downcast this error object by reference.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use anyhow::anyhow;
+ /// # use std::fmt::{self, Display};
+ /// # use std::task::Poll;
+ /// #
+ /// # #[derive(Debug)]
+ /// # enum DataStoreError {
+ /// # Censored(()),
+ /// # }
+ /// #
+ /// # impl Display for DataStoreError {
+ /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # impl std::error::Error for DataStoreError {}
+ /// #
+ /// # const REDACTED_CONTENT: () = ();
+ /// #
+ /// # let error = anyhow!("...");
+ /// # let root_cause = &error;
+ /// #
+ /// # let ret =
+ /// // If the error was caused by redaction, then return a tombstone instead
+ /// // of the content.
+ /// match root_cause.downcast_ref::<DataStoreError>() {
+ /// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
+ /// None => Err(error),
+ /// }
+ /// # ;
+ /// ```
+ pub fn downcast_ref<E>(&self) -> Option<&E>
+ where
+ E: Display + Debug + Send + Sync + 'static,
+ {
+ let target = TypeId::of::<E>();
+ unsafe {
+ // Use vtable to find NonNull<()> which points to a value of type E
+ // somewhere inside the data structure.
+ let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
+ Some(addr.cast::<E>().deref())
+ }
+ }
+
+ /// Downcast this error object by mutable reference.
+ pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
+ where
+ E: Display + Debug + Send + Sync + 'static,
+ {
+ let target = TypeId::of::<E>();
+ unsafe {
+ // Use vtable to find NonNull<()> which points to a value of type E
+ // somewhere inside the data structure.
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ let addr =
+ (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
+
+ #[cfg(anyhow_no_ptr_addr_of)]
+ let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?;
+
+ Some(addr.cast::<E>().deref_mut())
+ }
+ }
+}
+
+#[cfg(backtrace)]
+impl std::any::Provider for Error {
+ // Called by thiserror when you have `#[source] anyhow::Error`. This provide
+ // implementation includes the anyhow::Error's Backtrace if any, unlike
+ // deref'ing to dyn Error where the provide implementation would include
+ // only the original error's Backtrace from before it got wrapped into an
+ // anyhow::Error.
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ unsafe { ErrorImpl::provide(self.inner.by_ref(), demand) }
+ }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+impl<E> From<E> for Error
+where
+ E: StdError + Send + Sync + 'static,
+{
+ #[cold]
+ fn from(error: E) -> Self {
+ let backtrace = backtrace_if_absent!(&error);
+ Error::from_std(error, backtrace)
+ }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+impl Deref for Error {
+ type Target = dyn StdError + Send + Sync + 'static;
+
+ fn deref(&self) -> &Self::Target {
+ unsafe { ErrorImpl::error(self.inner.by_ref()) }
+ }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+impl DerefMut for Error {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
+ }
+}
+
+impl Debug for Error {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
+ }
+}
+
+impl Drop for Error {
+ fn drop(&mut self) {
+ unsafe {
+ // Invoke the vtable's drop behavior.
+ (vtable(self.inner.ptr).object_drop)(self.inner);
+ }
+ }
+}
+
+struct ErrorVTable {
+ object_drop: unsafe fn(Own<ErrorImpl>),
+ object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
+ #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+ object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
+ object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
+ object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
+ #[cfg(anyhow_no_ptr_addr_of)]
+ object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>,
+ object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
+ #[cfg(all(not(backtrace), feature = "backtrace"))]
+ object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
+ // Cast back to ErrorImpl<E> so that the allocator receives the correct
+ // Layout to deallocate the Box's memory.
+ let unerased = e.cast::<ErrorImpl<E>>().boxed();
+ drop(unerased);
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
+ // Drop the fields of ErrorImpl other than E as well as the Box allocation,
+ // without dropping E itself. This is used by downcast after doing a
+ // ptr::read to take ownership of the E.
+ let _ = target;
+ let unerased = e.cast::<ErrorImpl<ManuallyDrop<E>>>().boxed();
+ drop(unerased);
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
+where
+ E: StdError + Send + Sync + 'static,
+{
+ // Attach E's native StdError vtable onto a pointer to self._object.
+
+ let unerased = e.cast::<ErrorImpl<E>>();
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ return Ref::from_raw(NonNull::new_unchecked(
+ ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
+ ));
+
+ #[cfg(anyhow_no_ptr_addr_of)]
+ return Ref::new(&unerased.deref()._object);
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
+// from a `&mut`
+#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
+where
+ E: StdError + Send + Sync + 'static,
+{
+ // Attach E's native StdError vtable onto a pointer to self._object.
+ &mut e.cast::<ErrorImpl<E>>().deref_mut()._object
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
+where
+ E: StdError + Send + Sync + 'static,
+{
+ // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
+ e.cast::<ErrorImpl<E>>().boxed()
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
+where
+ E: 'static,
+{
+ if TypeId::of::<E>() == target {
+ // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
+ // pointer to its E field.
+
+ let unerased = e.cast::<ErrorImpl<E>>();
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ return Some(
+ Ref::from_raw(NonNull::new_unchecked(
+ ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
+ ))
+ .cast::<()>(),
+ );
+
+ #[cfg(anyhow_no_ptr_addr_of)]
+ return Some(Ref::new(&unerased.deref()._object).cast::<()>());
+ } else {
+ None
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<E>.
+#[cfg(anyhow_no_ptr_addr_of)]
+unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
+where
+ E: 'static,
+{
+ if TypeId::of::<E>() == target {
+ // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
+ // pointer to its E field.
+ let unerased = e.cast::<ErrorImpl<E>>().deref_mut();
+ Some(Mut::new(&mut unerased._object).cast::<()>())
+ } else {
+ None
+ }
+}
+
+#[cfg(all(not(backtrace), feature = "backtrace"))]
+fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
+ let _ = e;
+ None
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
+#[cfg(feature = "std")]
+unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
+where
+ C: 'static,
+ E: 'static,
+{
+ if TypeId::of::<C>() == target {
+ let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
+ Some(Ref::new(&unerased._object.context).cast::<()>())
+ } else if TypeId::of::<E>() == target {
+ let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
+ Some(Ref::new(&unerased._object.error).cast::<()>())
+ } else {
+ None
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
+#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
+unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
+where
+ C: 'static,
+ E: 'static,
+{
+ if TypeId::of::<C>() == target {
+ let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
+ Some(Mut::new(&mut unerased._object.context).cast::<()>())
+ } else if TypeId::of::<E>() == target {
+ let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
+ Some(Mut::new(&mut unerased._object.error).cast::<()>())
+ } else {
+ None
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
+#[cfg(feature = "std")]
+unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
+where
+ C: 'static,
+ E: 'static,
+{
+ // Called after downcasting by value to either the C or the E and doing a
+ // ptr::read to take ownership of that value.
+ if TypeId::of::<C>() == target {
+ let unerased = e
+ .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>()
+ .boxed();
+ drop(unerased);
+ } else {
+ let unerased = e
+ .cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>()
+ .boxed();
+ drop(unerased);
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
+unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
+where
+ C: 'static,
+{
+ let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
+ if TypeId::of::<C>() == target {
+ Some(Ref::new(&unerased._object.context).cast::<()>())
+ } else {
+ // Recurse down the context chain per the inner error's vtable.
+ let source = &unerased._object.error;
+ (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target)
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
+#[cfg(anyhow_no_ptr_addr_of)]
+unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
+where
+ C: 'static,
+{
+ let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref_mut();
+ if TypeId::of::<C>() == target {
+ Some(Mut::new(&mut unerased._object.context).cast::<()>())
+ } else {
+ // Recurse down the context chain per the inner error's vtable.
+ let source = &mut unerased._object.error;
+ (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target)
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
+unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
+where
+ C: 'static,
+{
+ // Called after downcasting by value to either the C or one of the causes
+ // and doing a ptr::read to take ownership of that value.
+ if TypeId::of::<C>() == target {
+ let unerased = e
+ .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>()
+ .boxed();
+ // Drop the entire rest of the data structure rooted in the next Error.
+ drop(unerased);
+ } else {
+ let unerased = e
+ .cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>()
+ .boxed();
+ // Read the Own<ErrorImpl> from the next error.
+ let inner = unerased._object.error.inner;
+ drop(unerased);
+ let vtable = vtable(inner.ptr);
+ // Recursively drop the next error using the same target typeid.
+ (vtable.object_drop_rest)(inner, target);
+ }
+}
+
+// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
+#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[allow(clippy::unnecessary_wraps)]
+unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
+where
+ C: 'static,
+{
+ let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
+ let backtrace = ErrorImpl::backtrace(unerased._object.error.inner.by_ref());
+ Some(backtrace)
+}
+
+// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
+// of raw pointers and `NonNull`.
+// repr C to ensure that E remains in the final position.
+#[repr(C)]
+pub(crate) struct ErrorImpl<E = ()> {
+ vtable: &'static ErrorVTable,
+ backtrace: Option<Backtrace>,
+ // NOTE: Don't use directly. Use only through vtable. Erased type may have
+ // different alignment.
+ _object: E,
+}
+
+// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
+// avoids converting `p` into a reference.
+unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
+ // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
+ *(p.as_ptr() as *const &'static ErrorVTable)
+}
+
+// repr C to ensure that ContextError<C, E> has the same layout as
+// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
+#[repr(C)]
+pub(crate) struct ContextError<C, E> {
+ pub context: C,
+ pub error: E,
+}
+
+impl<E> ErrorImpl<E> {
+ fn erase(&self) -> Ref<ErrorImpl> {
+ // Erase the concrete type of E but preserve the vtable in self.vtable
+ // for manipulating the resulting thin pointer. This is analogous to an
+ // unsize coercion.
+ Ref::new(self).cast::<ErrorImpl>()
+ }
+}
+
+impl ErrorImpl {
+ pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
+ // Use vtable to attach E's native StdError vtable for the right
+ // original type E.
+ (vtable(this.ptr).object_ref)(this).deref()
+ }
+
+ #[cfg(feature = "std")]
+ pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
+ // Use vtable to attach E's native StdError vtable for the right
+ // original type E.
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ return (vtable(this.ptr).object_ref)(this.by_ref())
+ .by_mut()
+ .deref_mut();
+
+ #[cfg(anyhow_no_ptr_addr_of)]
+ return (vtable(this.ptr).object_mut)(this);
+ }
+
+ #[cfg(any(backtrace, feature = "backtrace"))]
+ pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
+ // This unwrap can only panic if the underlying error's backtrace method
+ // is nondeterministic, which would only happen in maliciously
+ // constructed code.
+ this.deref()
+ .backtrace
+ .as_ref()
+ .or_else(|| {
+ #[cfg(backtrace)]
+ return Self::error(this).request_ref::<Backtrace>();
+ #[cfg(not(backtrace))]
+ return (vtable(this.ptr).object_backtrace)(this);
+ })
+ .expect("backtrace capture failed")
+ }
+
+ #[cfg(backtrace)]
+ unsafe fn provide<'a>(this: Ref<'a, Self>, demand: &mut Demand<'a>) {
+ if let Some(backtrace) = &this.deref().backtrace {
+ demand.provide_ref(backtrace);
+ }
+ Self::error(this).provide(demand);
+ }
+
+ #[cold]
+ pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
+ Chain::new(Self::error(this))
+ }
+}
+
+impl<E> StdError for ErrorImpl<E>
+where
+ E: StdError,
+{
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ unsafe { ErrorImpl::error(self.erase()).source() }
+ }
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ unsafe { ErrorImpl::provide(self.erase(), demand) }
+ }
+}
+
+impl<E> Debug for ErrorImpl<E>
+where
+ E: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ unsafe { ErrorImpl::debug(self.erase(), formatter) }
+ }
+}
+
+impl<E> Display for ErrorImpl<E>
+where
+ E: Display,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
+ }
+}
+
+impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
+ #[cold]
+ fn from(error: Error) -> Self {
+ let outer = ManuallyDrop::new(error);
+ unsafe {
+ // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
+ // the right original type E.
+ (vtable(outer.inner.ptr).object_boxed)(outer.inner)
+ }
+ }
+}
+
+impl From<Error> for Box<dyn StdError + Send + 'static> {
+ fn from(error: Error) -> Self {
+ Box::<dyn StdError + Send + Sync>::from(error)
+ }
+}
+
+impl From<Error> for Box<dyn StdError + 'static> {
+ fn from(error: Error) -> Self {
+ Box::<dyn StdError + Send + Sync>::from(error)
+ }
+}
+
+#[cfg(feature = "std")]
+impl AsRef<dyn StdError + Send + Sync> for Error {
+ fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
+ &**self
+ }
+}
+
+#[cfg(feature = "std")]
+impl AsRef<dyn StdError> for Error {
+ fn as_ref(&self) -> &(dyn StdError + 'static) {
+ &**self
+ }
+}
diff --git a/third_party/rust/anyhow/src/fmt.rs b/third_party/rust/anyhow/src/fmt.rs
new file mode 100644
index 0000000000..03d8fd3940
--- /dev/null
+++ b/third_party/rust/anyhow/src/fmt.rs
@@ -0,0 +1,155 @@
+use crate::chain::Chain;
+use crate::error::ErrorImpl;
+use crate::ptr::Ref;
+use core::fmt::{self, Debug, Write};
+
+impl ErrorImpl {
+ pub(crate) unsafe fn display(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", Self::error(this))?;
+
+ if f.alternate() {
+ for cause in Self::chain(this).skip(1) {
+ write!(f, ": {}", cause)?;
+ }
+ }
+
+ Ok(())
+ }
+
+ pub(crate) unsafe fn debug(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
+ let error = Self::error(this);
+
+ if f.alternate() {
+ return Debug::fmt(error, f);
+ }
+
+ write!(f, "{}", error)?;
+
+ if let Some(cause) = error.source() {
+ write!(f, "\n\nCaused by:")?;
+ let multiple = cause.source().is_some();
+ for (n, error) in Chain::new(cause).enumerate() {
+ writeln!(f)?;
+ let mut indented = Indented {
+ inner: f,
+ number: if multiple { Some(n) } else { None },
+ started: false,
+ };
+ write!(indented, "{}", error)?;
+ }
+ }
+
+ #[cfg(any(backtrace, feature = "backtrace"))]
+ {
+ use crate::backtrace::BacktraceStatus;
+
+ let backtrace = Self::backtrace(this);
+ if let BacktraceStatus::Captured = backtrace.status() {
+ let mut backtrace = backtrace.to_string();
+ write!(f, "\n\n")?;
+ if backtrace.starts_with("stack backtrace:") {
+ // Capitalize to match "Caused by:"
+ backtrace.replace_range(0..1, "S");
+ } else {
+ // "stack backtrace:" prefix was removed in
+ // https://github.com/rust-lang/backtrace-rs/pull/286
+ writeln!(f, "Stack backtrace:")?;
+ }
+ backtrace.truncate(backtrace.trim_end().len());
+ write!(f, "{}", backtrace)?;
+ }
+ }
+
+ Ok(())
+ }
+}
+
+struct Indented<'a, D> {
+ inner: &'a mut D,
+ number: Option<usize>,
+ started: bool,
+}
+
+impl<T> Write for Indented<'_, T>
+where
+ T: Write,
+{
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for (i, line) in s.split('\n').enumerate() {
+ if !self.started {
+ self.started = true;
+ match self.number {
+ Some(number) => write!(self.inner, "{: >5}: ", number)?,
+ None => self.inner.write_str(" ")?,
+ }
+ } else if i > 0 {
+ self.inner.write_char('\n')?;
+ if self.number.is_some() {
+ self.inner.write_str(" ")?;
+ } else {
+ self.inner.write_str(" ")?;
+ }
+ }
+
+ self.inner.write_str(line)?;
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn one_digit() {
+ let input = "verify\nthis";
+ let expected = " 2: verify\n this";
+ let mut output = String::new();
+
+ Indented {
+ inner: &mut output,
+ number: Some(2),
+ started: false,
+ }
+ .write_str(input)
+ .unwrap();
+
+ assert_eq!(expected, output);
+ }
+
+ #[test]
+ fn two_digits() {
+ let input = "verify\nthis";
+ let expected = " 12: verify\n this";
+ let mut output = String::new();
+
+ Indented {
+ inner: &mut output,
+ number: Some(12),
+ started: false,
+ }
+ .write_str(input)
+ .unwrap();
+
+ assert_eq!(expected, output);
+ }
+
+ #[test]
+ fn no_digits() {
+ let input = "verify\nthis";
+ let expected = " verify\n this";
+ let mut output = String::new();
+
+ Indented {
+ inner: &mut output,
+ number: None,
+ started: false,
+ }
+ .write_str(input)
+ .unwrap();
+
+ assert_eq!(expected, output);
+ }
+}
diff --git a/third_party/rust/anyhow/src/kind.rs b/third_party/rust/anyhow/src/kind.rs
new file mode 100644
index 0000000000..f47fe44ba2
--- /dev/null
+++ b/third_party/rust/anyhow/src/kind.rs
@@ -0,0 +1,116 @@
+// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`.
+//
+// When anyhow! is given a single expr argument to turn into anyhow::Error, we
+// want the resulting Error to pick up the input's implementation of source()
+// and backtrace() if it has a std::error::Error impl, otherwise require nothing
+// more than Display and Debug.
+//
+// Expressed in terms of specialization, we want something like:
+//
+// trait AnyhowNew {
+// fn new(self) -> Error;
+// }
+//
+// impl<T> AnyhowNew for T
+// where
+// T: Display + Debug + Send + Sync + 'static,
+// {
+// default fn new(self) -> Error {
+// /* no std error impl */
+// }
+// }
+//
+// impl<T> AnyhowNew for T
+// where
+// T: std::error::Error + Send + Sync + 'static,
+// {
+// fn new(self) -> Error {
+// /* use std error's source() and backtrace() */
+// }
+// }
+//
+// Since specialization is not stable yet, instead we rely on autoref behavior
+// of method resolution to perform tagged dispatch. Here we have two traits
+// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is
+// implemented whether or not the caller's type has a std error impl, while
+// TraitKind is implemented only when a std error impl does exist. The ambiguity
+// is resolved by AdhocKind requiring an extra autoref so that it has lower
+// precedence.
+//
+// The anyhow! macro will set up the call in this form:
+//
+// #[allow(unused_imports)]
+// use $crate::__private::{AdhocKind, TraitKind};
+// let error = $msg;
+// (&error).anyhow_kind().new(error)
+
+use crate::Error;
+use core::fmt::{Debug, Display};
+
+#[cfg(feature = "std")]
+use crate::StdError;
+
+pub struct Adhoc;
+
+pub trait AdhocKind: Sized {
+ #[inline]
+ fn anyhow_kind(&self) -> Adhoc {
+ Adhoc
+ }
+}
+
+impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
+
+impl Adhoc {
+ #[cold]
+ pub fn new<M>(self, message: M) -> Error
+ where
+ M: Display + Debug + Send + Sync + 'static,
+ {
+ Error::from_adhoc(message, backtrace!())
+ }
+}
+
+pub struct Trait;
+
+pub trait TraitKind: Sized {
+ #[inline]
+ fn anyhow_kind(&self) -> Trait {
+ Trait
+ }
+}
+
+impl<E> TraitKind for E where E: Into<Error> {}
+
+impl Trait {
+ #[cold]
+ pub fn new<E>(self, error: E) -> Error
+ where
+ E: Into<Error>,
+ {
+ error.into()
+ }
+}
+
+#[cfg(feature = "std")]
+pub struct Boxed;
+
+#[cfg(feature = "std")]
+pub trait BoxedKind: Sized {
+ #[inline]
+ fn anyhow_kind(&self) -> Boxed {
+ Boxed
+ }
+}
+
+#[cfg(feature = "std")]
+impl BoxedKind for Box<dyn StdError + Send + Sync> {}
+
+#[cfg(feature = "std")]
+impl Boxed {
+ #[cold]
+ pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
+ let backtrace = backtrace_if_absent!(&*error);
+ Error::from_boxed(error, backtrace)
+ }
+}
diff --git a/third_party/rust/anyhow/src/lib.rs b/third_party/rust/anyhow/src/lib.rs
new file mode 100644
index 0000000000..e570d6e9e3
--- /dev/null
+++ b/third_party/rust/anyhow/src/lib.rs
@@ -0,0 +1,680 @@
+//! [![github]](https://github.com/dtolnay/anyhow)&ensp;[![crates-io]](https://crates.io/crates/anyhow)&ensp;[![docs-rs]](https://docs.rs/anyhow)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! This library provides [`anyhow::Error`][Error], a trait object based error
+//! type for easy idiomatic error handling in Rust applications.
+//!
+//! <br>
+//!
+//! # Details
+//!
+//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
+//! the return type of any fallible function.
+//!
+//! Within the function, use `?` to easily propagate any error that implements
+//! the `std::error::Error` trait.
+//!
+//! ```
+//! # pub trait Deserialize {}
+//! #
+//! # mod serde_json {
+//! # use super::Deserialize;
+//! # use std::io;
+//! #
+//! # pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
+//! # unimplemented!()
+//! # }
+//! # }
+//! #
+//! # struct ClusterMap;
+//! #
+//! # impl Deserialize for ClusterMap {}
+//! #
+//! use anyhow::Result;
+//!
+//! fn get_cluster_info() -> Result<ClusterMap> {
+//! let config = std::fs::read_to_string("cluster.json")?;
+//! let map: ClusterMap = serde_json::from_str(&config)?;
+//! Ok(map)
+//! }
+//! #
+//! # fn main() {}
+//! ```
+//!
+//! - Attach context to help the person troubleshooting the error understand
+//! where things went wrong. A low-level error like "No such file or
+//! directory" can be annoying to debug without more context about what higher
+//! level step the application was in the middle of.
+//!
+//! ```
+//! # struct It;
+//! #
+//! # impl It {
+//! # fn detach(&self) -> Result<()> {
+//! # unimplemented!()
+//! # }
+//! # }
+//! #
+//! use anyhow::{Context, Result};
+//!
+//! fn main() -> Result<()> {
+//! # return Ok(());
+//! #
+//! # const _: &str = stringify! {
+//! ...
+//! # };
+//! #
+//! # let it = It;
+//! # let path = "./path/to/instrs.json";
+//! #
+//! it.detach().context("Failed to detach the important thing")?;
+//!
+//! let content = std::fs::read(path)
+//! .with_context(|| format!("Failed to read instrs from {}", path))?;
+//! #
+//! # const _: &str = stringify! {
+//! ...
+//! # };
+//! #
+//! # Ok(())
+//! }
+//! ```
+//!
+//! ```console
+//! Error: Failed to read instrs from ./path/to/instrs.json
+//!
+//! Caused by:
+//! No such file or directory (os error 2)
+//! ```
+//!
+//! - Downcasting is supported and can be by value, by shared reference, or by
+//! mutable reference as needed.
+//!
+//! ```
+//! # use anyhow::anyhow;
+//! # use std::fmt::{self, Display};
+//! # use std::task::Poll;
+//! #
+//! # #[derive(Debug)]
+//! # enum DataStoreError {
+//! # Censored(()),
+//! # }
+//! #
+//! # impl Display for DataStoreError {
+//! # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+//! # unimplemented!()
+//! # }
+//! # }
+//! #
+//! # impl std::error::Error for DataStoreError {}
+//! #
+//! # const REDACTED_CONTENT: () = ();
+//! #
+//! # let error = anyhow!("...");
+//! # let root_cause = &error;
+//! #
+//! # let ret =
+//! // If the error was caused by redaction, then return a
+//! // tombstone instead of the content.
+//! match root_cause.downcast_ref::<DataStoreError>() {
+//! Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
+//! None => Err(error),
+//! }
+//! # ;
+//! ```
+//!
+//! - If using the nightly channel, or stable with `features = ["backtrace"]`, a
+//! backtrace is captured and printed with the error if the underlying error
+//! type does not already provide its own. In order to see backtraces, they
+//! must be enabled through the environment variables described in
+//! [`std::backtrace`]:
+//!
+//! - If you want panics and errors to both have backtraces, set
+//! `RUST_BACKTRACE=1`;
+//! - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
+//! - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
+//! `RUST_LIB_BACKTRACE=0`.
+//!
+//! The tracking issue for this feature is [rust-lang/rust#53487].
+//!
+//! [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
+//! [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
+//!
+//! - Anyhow works with any error type that has an impl of `std::error::Error`,
+//! including ones defined in your crate. We do not bundle a `derive(Error)`
+//! macro but you can write the impls yourself or use a standalone macro like
+//! [thiserror].
+//!
+//! [thiserror]: https://github.com/dtolnay/thiserror
+//!
+//! ```
+//! use thiserror::Error;
+//!
+//! #[derive(Error, Debug)]
+//! pub enum FormatError {
+//! #[error("Invalid header (expected {expected:?}, got {found:?})")]
+//! InvalidHeader {
+//! expected: String,
+//! found: String,
+//! },
+//! #[error("Missing attribute: {0}")]
+//! MissingAttribute(String),
+//! }
+//! ```
+//!
+//! - One-off error messages can be constructed using the `anyhow!` macro, which
+//! supports string interpolation and produces an `anyhow::Error`.
+//!
+//! ```
+//! # use anyhow::{anyhow, Result};
+//! #
+//! # fn demo() -> Result<()> {
+//! # let missing = "...";
+//! return Err(anyhow!("Missing attribute: {}", missing));
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! A `bail!` macro is provided as a shorthand for the same early return.
+//!
+//! ```
+//! # use anyhow::{bail, Result};
+//! #
+//! # fn demo() -> Result<()> {
+//! # let missing = "...";
+//! bail!("Missing attribute: {}", missing);
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! <br>
+//!
+//! # No-std support
+//!
+//! In no_std mode, the same API is almost all available and works the same way.
+//! To depend on Anyhow in no_std mode, disable our default enabled "std"
+//! feature in Cargo.toml. A global allocator is required.
+//!
+//! ```toml
+//! [dependencies]
+//! anyhow = { version = "1.0", default-features = false }
+//! ```
+//!
+//! Since the `?`-based error conversions would normally rely on the
+//! `std::error::Error` trait which is only available through std, no_std mode
+//! will require an explicit `.map_err(Error::msg)` when working with a
+//! non-Anyhow error type inside a function that returns Anyhow's error type.
+
+#![doc(html_root_url = "https://docs.rs/anyhow/1.0.69")]
+#![cfg_attr(backtrace, feature(error_generic_member_access, provide_any))]
+#![cfg_attr(doc_cfg, feature(doc_cfg))]
+#![cfg_attr(not(feature = "std"), no_std)]
+#![deny(dead_code, unused_imports, unused_mut)]
+#![allow(
+ clippy::doc_markdown,
+ clippy::enum_glob_use,
+ clippy::explicit_auto_deref,
+ clippy::missing_errors_doc,
+ clippy::missing_panics_doc,
+ clippy::module_name_repetitions,
+ clippy::must_use_candidate,
+ clippy::needless_doctest_main,
+ clippy::new_ret_no_self,
+ clippy::redundant_else,
+ clippy::return_self_not_must_use,
+ clippy::unused_self,
+ clippy::used_underscore_binding,
+ clippy::wildcard_imports,
+ clippy::wrong_self_convention
+)]
+
+extern crate alloc;
+
+#[macro_use]
+mod backtrace;
+mod chain;
+mod context;
+mod ensure;
+mod error;
+mod fmt;
+mod kind;
+mod macros;
+mod ptr;
+mod wrapper;
+
+use crate::error::ErrorImpl;
+use crate::ptr::Own;
+use core::fmt::Display;
+
+#[cfg(not(feature = "std"))]
+use core::fmt::Debug;
+
+#[cfg(feature = "std")]
+use std::error::Error as StdError;
+
+#[cfg(not(feature = "std"))]
+trait StdError: Debug + Display {
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ None
+ }
+}
+
+pub use anyhow as format_err;
+
+/// The `Error` type, a wrapper around a dynamic error type.
+///
+/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
+/// differences:
+///
+/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
+/// - `Error` guarantees that a backtrace is available, even if the underlying
+/// error type does not provide one.
+/// - `Error` is represented as a narrow pointer &mdash; exactly one word in
+/// size instead of two.
+///
+/// <br>
+///
+/// # Display representations
+///
+/// When you print an error object using "{}" or to_string(), only the outermost
+/// underlying error or context is printed, not any of the lower level causes.
+/// This is exactly as if you had called the Display impl of the error from
+/// which you constructed your anyhow::Error.
+///
+/// ```console
+/// Failed to read instrs from ./path/to/instrs.json
+/// ```
+///
+/// To print causes as well using anyhow's default formatting of causes, use the
+/// alternate selector "{:#}".
+///
+/// ```console
+/// Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2)
+/// ```
+///
+/// The Debug format "{:?}" includes your backtrace if one was captured. Note
+/// that this is the representation you get by default if you return an error
+/// from `fn main` instead of printing it explicitly yourself.
+///
+/// ```console
+/// Error: Failed to read instrs from ./path/to/instrs.json
+///
+/// Caused by:
+/// No such file or directory (os error 2)
+/// ```
+///
+/// and if there is a backtrace available:
+///
+/// ```console
+/// Error: Failed to read instrs from ./path/to/instrs.json
+///
+/// Caused by:
+/// No such file or directory (os error 2)
+///
+/// Stack backtrace:
+/// 0: <E as anyhow::context::ext::StdError>::ext_context
+/// at /git/anyhow/src/backtrace.rs:26
+/// 1: core::result::Result<T,E>::map_err
+/// at /git/rustc/src/libcore/result.rs:596
+/// 2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
+/// at /git/anyhow/src/context.rs:58
+/// 3: testing::main
+/// at src/main.rs:5
+/// 4: std::rt::lang_start
+/// at /git/rustc/src/libstd/rt.rs:61
+/// 5: main
+/// 6: __libc_start_main
+/// 7: _start
+/// ```
+///
+/// To see a conventional struct-style Debug representation, use "{:#?}".
+///
+/// ```console
+/// Error {
+/// context: "Failed to read instrs from ./path/to/instrs.json",
+/// source: Os {
+/// code: 2,
+/// kind: NotFound,
+/// message: "No such file or directory",
+/// },
+/// }
+/// ```
+///
+/// If none of the built-in representations are appropriate and you would prefer
+/// to render the error and its cause chain yourself, it can be done something
+/// like this:
+///
+/// ```
+/// use anyhow::{Context, Result};
+///
+/// fn main() {
+/// if let Err(err) = try_main() {
+/// eprintln!("ERROR: {}", err);
+/// err.chain().skip(1).for_each(|cause| eprintln!("because: {}", cause));
+/// std::process::exit(1);
+/// }
+/// }
+///
+/// fn try_main() -> Result<()> {
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # Ok(())
+/// }
+/// ```
+#[cfg_attr(not(doc), repr(transparent))]
+pub struct Error {
+ inner: Own<ErrorImpl>,
+}
+
+/// Iterator of a chain of source errors.
+///
+/// This type is the iterator returned by [`Error::chain`].
+///
+/// # Example
+///
+/// ```
+/// use anyhow::Error;
+/// use std::io;
+///
+/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
+/// for cause in error.chain() {
+/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
+/// return Some(io_error.kind());
+/// }
+/// }
+/// None
+/// }
+/// ```
+#[cfg(feature = "std")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+#[derive(Clone)]
+pub struct Chain<'a> {
+ state: crate::chain::ChainState<'a>,
+}
+
+/// `Result<T, Error>`
+///
+/// This is a reasonable return type to use throughout your application but also
+/// for `fn main`; if you do, failures will be printed along with any
+/// [context][Context] and a backtrace if one was captured.
+///
+/// `anyhow::Result` may be used with one *or* two type parameters.
+///
+/// ```rust
+/// use anyhow::Result;
+///
+/// # const IGNORE: &str = stringify! {
+/// fn demo1() -> Result<T> {...}
+/// // ^ equivalent to std::result::Result<T, anyhow::Error>
+///
+/// fn demo2() -> Result<T, OtherError> {...}
+/// // ^ equivalent to std::result::Result<T, OtherError>
+/// # };
+/// ```
+///
+/// # Example
+///
+/// ```
+/// # pub trait Deserialize {}
+/// #
+/// # mod serde_json {
+/// # use super::Deserialize;
+/// # use std::io;
+/// #
+/// # pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// # #[derive(Debug)]
+/// # struct ClusterMap;
+/// #
+/// # impl Deserialize for ClusterMap {}
+/// #
+/// use anyhow::Result;
+///
+/// fn main() -> Result<()> {
+/// # return Ok(());
+/// let config = std::fs::read_to_string("cluster.json")?;
+/// let map: ClusterMap = serde_json::from_str(&config)?;
+/// println!("cluster info: {:#?}", map);
+/// Ok(())
+/// }
+/// ```
+pub type Result<T, E = Error> = core::result::Result<T, E>;
+
+/// Provides the `context` method for `Result`.
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `anyhow`.
+///
+/// <br>
+///
+/// # Example
+///
+/// ```
+/// use anyhow::{Context, Result};
+/// use std::fs;
+/// use std::path::PathBuf;
+///
+/// pub struct ImportantThing {
+/// path: PathBuf,
+/// }
+///
+/// impl ImportantThing {
+/// # const IGNORE: &'static str = stringify! {
+/// pub fn detach(&mut self) -> Result<()> {...}
+/// # };
+/// # fn detach(&mut self) -> Result<()> {
+/// # unimplemented!()
+/// # }
+/// }
+///
+/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
+/// it.detach().context("Failed to detach the important thing")?;
+///
+/// let path = &it.path;
+/// let content = fs::read(path)
+/// .with_context(|| format!("Failed to read instrs from {}", path.display()))?;
+///
+/// Ok(content)
+/// }
+/// ```
+///
+/// When printed, the outermost context would be printed first and the lower
+/// level underlying causes would be enumerated below.
+///
+/// ```console
+/// Error: Failed to read instrs from ./path/to/instrs.json
+///
+/// Caused by:
+/// No such file or directory (os error 2)
+/// ```
+///
+/// Refer to the [Display representations] documentation for other forms in
+/// which this context chain can be rendered.
+///
+/// [Display representations]: Error#display-representations
+///
+/// <br>
+///
+/// # Effect on downcasting
+///
+/// After attaching context of type `C` onto an error of type `E`, the resulting
+/// `anyhow::Error` may be downcast to `C` **or** to `E`.
+///
+/// That is, in codebases that rely on downcasting, Anyhow's context supports
+/// both of the following use cases:
+///
+/// - **Attaching context whose type is insignificant onto errors whose type
+/// is used in downcasts.**
+///
+/// In other error libraries whose context is not designed this way, it can
+/// be risky to introduce context to existing code because new context might
+/// break existing working downcasts. In Anyhow, any downcast that worked
+/// before adding context will continue to work after you add a context, so
+/// you should freely add human-readable context to errors wherever it would
+/// be helpful.
+///
+/// ```
+/// # use anyhow::bail;
+/// # use thiserror::Error;
+/// #
+/// # #[derive(Error, Debug)]
+/// # #[error("???")]
+/// # struct SuspiciousError;
+/// #
+/// # fn helper() -> Result<()> {
+/// # bail!(SuspiciousError);
+/// # }
+/// #
+/// use anyhow::{Context, Result};
+///
+/// fn do_it() -> Result<()> {
+/// helper().context("Failed to complete the work")?;
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unreachable!()
+/// }
+///
+/// fn main() {
+/// let err = do_it().unwrap_err();
+/// if let Some(e) = err.downcast_ref::<SuspiciousError>() {
+/// // If helper() returned SuspiciousError, this downcast will
+/// // correctly succeed even with the context in between.
+/// # return;
+/// }
+/// # panic!("expected downcast to succeed");
+/// }
+/// ```
+///
+/// - **Attaching context whose type is used in downcasts onto errors whose
+/// type is insignificant.**
+///
+/// Some codebases prefer to use machine-readable context to categorize
+/// lower level errors in a way that will be actionable to higher levels of
+/// the application.
+///
+/// ```
+/// # use anyhow::bail;
+/// # use thiserror::Error;
+/// #
+/// # #[derive(Error, Debug)]
+/// # #[error("???")]
+/// # struct HelperFailed;
+/// #
+/// # fn helper() -> Result<()> {
+/// # bail!("no such file or directory");
+/// # }
+/// #
+/// use anyhow::{Context, Result};
+///
+/// fn do_it() -> Result<()> {
+/// helper().context(HelperFailed)?;
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unreachable!()
+/// }
+///
+/// fn main() {
+/// let err = do_it().unwrap_err();
+/// if let Some(e) = err.downcast_ref::<HelperFailed>() {
+/// // If helper failed, this downcast will succeed because
+/// // HelperFailed is the context that has been attached to
+/// // that error.
+/// # return;
+/// }
+/// # panic!("expected downcast to succeed");
+/// }
+/// ```
+pub trait Context<T, E>: context::private::Sealed {
+ /// Wrap the error value with additional context.
+ fn context<C>(self, context: C) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static;
+
+ /// Wrap the error value with additional context that is evaluated lazily
+ /// only once an error does occur.
+ fn with_context<C, F>(self, f: F) -> Result<T, Error>
+ where
+ C: Display + Send + Sync + 'static,
+ F: FnOnce() -> C;
+}
+
+/// Equivalent to Ok::<_, anyhow::Error>(value).
+///
+/// This simplifies creation of an anyhow::Result in places where type inference
+/// cannot deduce the `E` type of the result &mdash; without needing to write
+/// `Ok::<_, anyhow::Error>(value)`.
+///
+/// One might think that `anyhow::Result::Ok(value)` would work in such cases
+/// but it does not.
+///
+/// ```console
+/// error[E0282]: type annotations needed for `std::result::Result<i32, E>`
+/// --> src/main.rs:11:13
+/// |
+/// 11 | let _ = anyhow::Result::Ok(1);
+/// | - ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the enum `Result`
+/// | |
+/// | consider giving this pattern the explicit type `std::result::Result<i32, E>`, where the type parameter `E` is specified
+/// ```
+#[allow(non_snake_case)]
+pub fn Ok<T>(t: T) -> Result<T> {
+ Result::Ok(t)
+}
+
+// Not public API. Referenced by macro-generated code.
+#[doc(hidden)]
+pub mod __private {
+ use crate::Error;
+ use alloc::fmt;
+ use core::fmt::Arguments;
+
+ pub use crate::ensure::{BothDebug, NotBothDebug};
+ pub use alloc::format;
+ pub use core::result::Result::Err;
+ pub use core::{concat, format_args, stringify};
+
+ #[doc(hidden)]
+ pub mod kind {
+ pub use crate::kind::{AdhocKind, TraitKind};
+
+ #[cfg(feature = "std")]
+ pub use crate::kind::BoxedKind;
+ }
+
+ #[doc(hidden)]
+ #[inline]
+ #[cold]
+ pub fn format_err(args: Arguments) -> Error {
+ #[cfg(anyhow_no_fmt_arguments_as_str)]
+ let fmt_arguments_as_str = None::<&str>;
+ #[cfg(not(anyhow_no_fmt_arguments_as_str))]
+ let fmt_arguments_as_str = args.as_str();
+
+ if let Some(message) = fmt_arguments_as_str {
+ // anyhow!("literal"), can downcast to &'static str
+ Error::msg(message)
+ } else {
+ // anyhow!("interpolate {var}"), can downcast to String
+ Error::msg(fmt::format(args))
+ }
+ }
+
+ #[doc(hidden)]
+ #[inline]
+ #[cold]
+ #[must_use]
+ pub fn must_use(error: Error) -> Error {
+ error
+ }
+}
diff --git a/third_party/rust/anyhow/src/macros.rs b/third_party/rust/anyhow/src/macros.rs
new file mode 100644
index 0000000000..6dd22743b7
--- /dev/null
+++ b/third_party/rust/anyhow/src/macros.rs
@@ -0,0 +1,231 @@
+/// Return early with an error.
+///
+/// This macro is equivalent to `return Err(`[`anyhow!($args...)`][anyhow!]`)`.
+///
+/// The surrounding function's or closure's return value is required to be
+/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
+///
+/// [anyhow!]: crate::anyhow
+///
+/// # Example
+///
+/// ```
+/// # use anyhow::{bail, Result};
+/// #
+/// # fn has_permission(user: usize, resource: usize) -> bool {
+/// # true
+/// # }
+/// #
+/// # fn main() -> Result<()> {
+/// # let user = 0;
+/// # let resource = 0;
+/// #
+/// if !has_permission(user, resource) {
+/// bail!("permission denied for accessing {}", resource);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// ```
+/// # use anyhow::{bail, Result};
+/// # use thiserror::Error;
+/// #
+/// # const MAX_DEPTH: usize = 1;
+/// #
+/// #[derive(Error, Debug)]
+/// enum ScienceError {
+/// #[error("recursion limit exceeded")]
+/// RecursionLimitExceeded,
+/// # #[error("...")]
+/// # More = (stringify! {
+/// ...
+/// # }, 1).1,
+/// }
+///
+/// # fn main() -> Result<()> {
+/// # let depth = 0;
+/// #
+/// if depth > MAX_DEPTH {
+/// bail!(ScienceError::RecursionLimitExceeded);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+#[macro_export]
+macro_rules! bail {
+ ($msg:literal $(,)?) => {
+ return $crate::__private::Err($crate::__anyhow!($msg))
+ };
+ ($err:expr $(,)?) => {
+ return $crate::__private::Err($crate::__anyhow!($err))
+ };
+ ($fmt:expr, $($arg:tt)*) => {
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*))
+ };
+}
+
+/// Return early with an error if a condition is not satisfied.
+///
+/// This macro is equivalent to `if !$cond { return
+/// Err(`[`anyhow!($args...)`][anyhow!]`); }`.
+///
+/// The surrounding function's or closure's return value is required to be
+/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
+///
+/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
+/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
+/// rather than panicking.
+///
+/// [anyhow!]: crate::anyhow
+///
+/// # Example
+///
+/// ```
+/// # use anyhow::{ensure, Result};
+/// #
+/// # fn main() -> Result<()> {
+/// # let user = 0;
+/// #
+/// ensure!(user == 0, "only user 0 is allowed");
+/// # Ok(())
+/// # }
+/// ```
+///
+/// ```
+/// # use anyhow::{ensure, Result};
+/// # use thiserror::Error;
+/// #
+/// # const MAX_DEPTH: usize = 1;
+/// #
+/// #[derive(Error, Debug)]
+/// enum ScienceError {
+/// #[error("recursion limit exceeded")]
+/// RecursionLimitExceeded,
+/// # #[error("...")]
+/// # More = (stringify! {
+/// ...
+/// # }, 1).1,
+/// }
+///
+/// # fn main() -> Result<()> {
+/// # let depth = 0;
+/// #
+/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
+/// # Ok(())
+/// # }
+/// ```
+#[cfg(doc)]
+#[macro_export]
+macro_rules! ensure {
+ ($cond:expr $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::Error::msg(
+ $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
+ ));
+ }
+ };
+ ($cond:expr, $msg:literal $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($msg));
+ }
+ };
+ ($cond:expr, $err:expr $(,)?) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($err));
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)*) => {
+ if !$cond {
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
+ }
+ };
+}
+
+#[cfg(not(doc))]
+#[macro_export]
+macro_rules! ensure {
+ ($($tt:tt)*) => {
+ $crate::__parse_ensure!(
+ /* state */ 0
+ /* stack */ ()
+ /* bail */ ($($tt)*)
+ /* fuel */ (~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~)
+ /* parse */ {()}
+ /* dup */ ($($tt)*)
+ /* rest */ $($tt)*
+ )
+ };
+}
+
+/// Construct an ad-hoc error from a string or existing non-`anyhow` error
+/// value.
+///
+/// This evaluates to an [`Error`][crate::Error]. It can take either just a
+/// string, or a format string with arguments. It also can take any custom type
+/// which implements `Debug` and `Display`.
+///
+/// If called with a single argument whose type implements `std::error::Error`
+/// (in addition to `Debug` and `Display`, which are always required), then that
+/// Error impl's `source` is preserved as the `source` of the resulting
+/// `anyhow::Error`.
+///
+/// # Example
+///
+/// ```
+/// # type V = ();
+/// #
+/// use anyhow::{anyhow, Result};
+///
+/// fn lookup(key: &str) -> Result<V> {
+/// if key.len() != 16 {
+/// return Err(anyhow!("key length must be 16 characters, got {:?}", key));
+/// }
+///
+/// // ...
+/// # Ok(())
+/// }
+/// ```
+#[macro_export]
+macro_rules! anyhow {
+ ($msg:literal $(,)?) => {
+ $crate::__private::must_use({
+ let error = $crate::__private::format_err($crate::__private::format_args!($msg));
+ error
+ })
+ };
+ ($err:expr $(,)?) => {
+ $crate::__private::must_use({
+ use $crate::__private::kind::*;
+ let error = match $err {
+ error => (&error).anyhow_kind().new(error),
+ };
+ error
+ })
+ };
+ ($fmt:expr, $($arg:tt)*) => {
+ $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
+ };
+}
+
+// Not public API. This is used in the implementation of some of the other
+// macros, in which the must_use call is not needed because the value is known
+// to be used.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __anyhow {
+ ($msg:literal $(,)?) => ({
+ let error = $crate::__private::format_err($crate::__private::format_args!($msg));
+ error
+ });
+ ($err:expr $(,)?) => ({
+ use $crate::__private::kind::*;
+ let error = match $err {
+ error => (&error).anyhow_kind().new(error),
+ };
+ error
+ });
+ ($fmt:expr, $($arg:tt)*) => {
+ $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
+ };
+}
diff --git a/third_party/rust/anyhow/src/ptr.rs b/third_party/rust/anyhow/src/ptr.rs
new file mode 100644
index 0000000000..c7fe488b6f
--- /dev/null
+++ b/third_party/rust/anyhow/src/ptr.rs
@@ -0,0 +1,199 @@
+use alloc::boxed::Box;
+use core::marker::PhantomData;
+use core::ptr::NonNull;
+
+#[repr(transparent)]
+pub struct Own<T>
+where
+ T: ?Sized,
+{
+ pub ptr: NonNull<T>,
+}
+
+unsafe impl<T> Send for Own<T> where T: ?Sized {}
+
+unsafe impl<T> Sync for Own<T> where T: ?Sized {}
+
+impl<T> Copy for Own<T> where T: ?Sized {}
+
+impl<T> Clone for Own<T>
+where
+ T: ?Sized,
+{
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<T> Own<T>
+where
+ T: ?Sized,
+{
+ pub fn new(ptr: Box<T>) -> Self {
+ Own {
+ ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) },
+ }
+ }
+
+ pub fn cast<U: CastTo>(self) -> Own<U::Target> {
+ Own {
+ ptr: self.ptr.cast(),
+ }
+ }
+
+ pub unsafe fn boxed(self) -> Box<T> {
+ Box::from_raw(self.ptr.as_ptr())
+ }
+
+ pub fn by_ref(&self) -> Ref<T> {
+ Ref {
+ ptr: self.ptr,
+ lifetime: PhantomData,
+ }
+ }
+
+ pub fn by_mut(&mut self) -> Mut<T> {
+ Mut {
+ ptr: self.ptr,
+ lifetime: PhantomData,
+ }
+ }
+}
+
+#[repr(transparent)]
+pub struct Ref<'a, T>
+where
+ T: ?Sized,
+{
+ pub ptr: NonNull<T>,
+ lifetime: PhantomData<&'a T>,
+}
+
+impl<'a, T> Copy for Ref<'a, T> where T: ?Sized {}
+
+impl<'a, T> Clone for Ref<'a, T>
+where
+ T: ?Sized,
+{
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, T> Ref<'a, T>
+where
+ T: ?Sized,
+{
+ pub fn new(ptr: &'a T) -> Self {
+ Ref {
+ ptr: NonNull::from(ptr),
+ lifetime: PhantomData,
+ }
+ }
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ pub fn from_raw(ptr: NonNull<T>) -> Self {
+ Ref {
+ ptr,
+ lifetime: PhantomData,
+ }
+ }
+
+ pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
+ Ref {
+ ptr: self.ptr.cast(),
+ lifetime: PhantomData,
+ }
+ }
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ pub fn by_mut(self) -> Mut<'a, T> {
+ Mut {
+ ptr: self.ptr,
+ lifetime: PhantomData,
+ }
+ }
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ pub fn as_ptr(self) -> *const T {
+ self.ptr.as_ptr() as *const T
+ }
+
+ pub unsafe fn deref(self) -> &'a T {
+ &*self.ptr.as_ptr()
+ }
+}
+
+#[repr(transparent)]
+pub struct Mut<'a, T>
+where
+ T: ?Sized,
+{
+ pub ptr: NonNull<T>,
+ lifetime: PhantomData<&'a mut T>,
+}
+
+impl<'a, T> Copy for Mut<'a, T> where T: ?Sized {}
+
+impl<'a, T> Clone for Mut<'a, T>
+where
+ T: ?Sized,
+{
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, T> Mut<'a, T>
+where
+ T: ?Sized,
+{
+ #[cfg(anyhow_no_ptr_addr_of)]
+ pub fn new(ptr: &'a mut T) -> Self {
+ Mut {
+ ptr: NonNull::from(ptr),
+ lifetime: PhantomData,
+ }
+ }
+
+ pub fn cast<U: CastTo>(self) -> Mut<'a, U::Target> {
+ Mut {
+ ptr: self.ptr.cast(),
+ lifetime: PhantomData,
+ }
+ }
+
+ #[cfg(not(anyhow_no_ptr_addr_of))]
+ pub fn by_ref(self) -> Ref<'a, T> {
+ Ref {
+ ptr: self.ptr,
+ lifetime: PhantomData,
+ }
+ }
+
+ pub fn extend<'b>(self) -> Mut<'b, T> {
+ Mut {
+ ptr: self.ptr,
+ lifetime: PhantomData,
+ }
+ }
+
+ pub unsafe fn deref_mut(self) -> &'a mut T {
+ &mut *self.ptr.as_ptr()
+ }
+}
+
+impl<'a, T> Mut<'a, T> {
+ pub unsafe fn read(self) -> T {
+ self.ptr.as_ptr().read()
+ }
+}
+
+// Force turbofish on all calls of `.cast::<U>()`.
+pub trait CastTo {
+ type Target;
+}
+
+impl<T> CastTo for T {
+ type Target = T;
+}
diff --git a/third_party/rust/anyhow/src/wrapper.rs b/third_party/rust/anyhow/src/wrapper.rs
new file mode 100644
index 0000000000..5f18a50313
--- /dev/null
+++ b/third_party/rust/anyhow/src/wrapper.rs
@@ -0,0 +1,81 @@
+use crate::StdError;
+use core::fmt::{self, Debug, Display};
+
+#[cfg(backtrace)]
+use std::any::Demand;
+
+#[repr(transparent)]
+pub struct MessageError<M>(pub M);
+
+impl<M> Debug for MessageError<M>
+where
+ M: Display + Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.0, f)
+ }
+}
+
+impl<M> Display for MessageError<M>
+where
+ M: Display + Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.0, f)
+ }
+}
+
+impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
+
+#[repr(transparent)]
+pub struct DisplayError<M>(pub M);
+
+impl<M> Debug for DisplayError<M>
+where
+ M: Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.0, f)
+ }
+}
+
+impl<M> Display for DisplayError<M>
+where
+ M: Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.0, f)
+ }
+}
+
+impl<M> StdError for DisplayError<M> where M: Display + 'static {}
+
+#[cfg(feature = "std")]
+#[repr(transparent)]
+pub struct BoxedError(pub Box<dyn StdError + Send + Sync>);
+
+#[cfg(feature = "std")]
+impl Debug for BoxedError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.0, f)
+ }
+}
+
+#[cfg(feature = "std")]
+impl Display for BoxedError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.0, f)
+ }
+}
+
+#[cfg(feature = "std")]
+impl StdError for BoxedError {
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ self.0.source()
+ }
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.0.provide(demand);
+ }
+}