Coverage Report

Created: 2026-11-12 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.58/src/kind.rs
Line
Count
Source
1
// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`.
2
//
3
// When anyhow! is given a single expr argument to turn into anyhow::Error, we
4
// want the resulting Error to pick up the input's implementation of source()
5
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
6
// more than Display and Debug.
7
//
8
// Expressed in terms of specialization, we want something like:
9
//
10
//     trait AnyhowNew {
11
//         fn new(self) -> Error;
12
//     }
13
//
14
//     impl<T> AnyhowNew for T
15
//     where
16
//         T: Display + Debug + Send + Sync + 'static,
17
//     {
18
//         default fn new(self) -> Error {
19
//             /* no std error impl */
20
//         }
21
//     }
22
//
23
//     impl<T> AnyhowNew for T
24
//     where
25
//         T: std::error::Error + Send + Sync + 'static,
26
//     {
27
//         fn new(self) -> Error {
28
//             /* use std error's source() and backtrace() */
29
//         }
30
//     }
31
//
32
// Since specialization is not stable yet, instead we rely on autoref behavior
33
// of method resolution to perform tagged dispatch. Here we have two traits
34
// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is
35
// implemented whether or not the caller's type has a std error impl, while
36
// TraitKind is implemented only when a std error impl does exist. The ambiguity
37
// is resolved by AdhocKind requiring an extra autoref so that it has lower
38
// precedence.
39
//
40
// The anyhow! macro will set up the call in this form:
41
//
42
//     #[allow(unused_imports)]
43
//     use $crate::private::{AdhocKind, TraitKind};
44
//     let error = $msg;
45
//     (&error).anyhow_kind().new(error)
46
47
use crate::Error;
48
use core::fmt::{Debug, Display};
49
50
#[cfg(feature = "std")]
51
use crate::StdError;
52
53
pub struct Adhoc;
54
55
pub trait AdhocKind: Sized {
56
    #[inline]
57
0
    fn anyhow_kind(&self) -> Adhoc {
58
0
        Adhoc
59
0
    }
Unexecuted instantiation: <&alloc::string::String as anyhow::kind::AdhocKind>::anyhow_kind
Unexecuted instantiation: <_ as anyhow::kind::AdhocKind>::anyhow_kind
60
}
61
62
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
63
64
impl Adhoc {
65
    #[cold]
66
0
    pub fn new<M>(self, message: M) -> Error
67
0
    where
68
0
        M: Display + Debug + Send + Sync + 'static,
69
    {
70
0
        Error::from_adhoc(message, backtrace!())
71
0
    }
Unexecuted instantiation: <anyhow::kind::Adhoc>::new::<alloc::string::String>
Unexecuted instantiation: <anyhow::kind::Adhoc>::new::<_>
72
}
73
74
pub struct Trait;
75
76
pub trait TraitKind: Sized {
77
    #[inline]
78
0
    fn anyhow_kind(&self) -> Trait {
79
0
        Trait
80
0
    }
81
}
82
83
impl<E> TraitKind for E where E: Into<Error> {}
84
85
impl Trait {
86
    #[cold]
87
0
    pub fn new<E>(self, error: E) -> Error
88
0
    where
89
0
        E: Into<Error>,
90
    {
91
0
        error.into()
92
0
    }
93
}
94
95
#[cfg(feature = "std")]
96
pub struct Boxed;
97
98
#[cfg(feature = "std")]
99
pub trait BoxedKind: Sized {
100
    #[inline]
101
0
    fn anyhow_kind(&self) -> Boxed {
102
0
        Boxed
103
0
    }
104
}
105
106
#[cfg(feature = "std")]
107
impl BoxedKind for Box<dyn StdError + Send + Sync> {}
108
109
#[cfg(feature = "std")]
110
impl Boxed {
111
    #[cold]
112
0
    pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
113
0
        let backtrace = backtrace_if_absent!(error);
114
0
        Error::from_boxed(error, backtrace)
115
0
    }
116
}