mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-10-02 15:26:08 +00:00
Document tagged dispatch approach
This commit is contained in:
parent
14bab22e06
commit
443cc8dedb
46
src/kind.rs
46
src/kind.rs
@ -1,3 +1,49 @@
|
|||||||
|
// 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 crate::Error;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user