core/
error.rs

1#![doc = include_str!("error.md")]
2#![stable(feature = "error_in_core", since = "1.81.0")]
3
4use crate::any::TypeId;
5use crate::fmt::{self, Debug, Display, Formatter};
6
7/// `Error` is a trait representing the basic expectations for error values,
8/// i.e., values of type `E` in [`Result<T, E>`].
9///
10/// Errors must describe themselves through the [`Display`] and [`Debug`]
11/// traits. Error messages are typically concise lowercase sentences without
12/// trailing punctuation:
13///
14/// ```
15/// let err = "NaN".parse::<u32>().unwrap_err();
16/// assert_eq!(err.to_string(), "invalid digit found in string");
17/// ```
18///
19/// Errors may provide cause information. [`Error::source()`] is generally
20/// used when errors cross "abstraction boundaries". If one module must report
21/// an error that is caused by an error from a lower-level module, it can allow
22/// accessing that error via [`Error::source()`]. This makes it possible for the
23/// high-level module to provide its own errors while also revealing some of the
24/// implementation for debugging.
25#[stable(feature = "rust1", since = "1.0.0")]
26#[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
27#[rustc_has_incoherent_inherent_impls]
28#[allow(multiple_supertrait_upcastable)]
29pub trait Error: Debug + Display {
30    /// Returns the lower-level source of this error, if any.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// use std::error::Error;
36    /// use std::fmt;
37    ///
38    /// #[derive(Debug)]
39    /// struct SuperError {
40    ///     source: SuperErrorSideKick,
41    /// }
42    ///
43    /// impl fmt::Display for SuperError {
44    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45    ///         write!(f, "SuperError is here!")
46    ///     }
47    /// }
48    ///
49    /// impl Error for SuperError {
50    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
51    ///         Some(&self.source)
52    ///     }
53    /// }
54    ///
55    /// #[derive(Debug)]
56    /// struct SuperErrorSideKick;
57    ///
58    /// impl fmt::Display for SuperErrorSideKick {
59    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60    ///         write!(f, "SuperErrorSideKick is here!")
61    ///     }
62    /// }
63    ///
64    /// impl Error for SuperErrorSideKick {}
65    ///
66    /// fn get_super_error() -> Result<(), SuperError> {
67    ///     Err(SuperError { source: SuperErrorSideKick })
68    /// }
69    ///
70    /// fn main() {
71    ///     match get_super_error() {
72    ///         Err(e) => {
73    ///             println!("Error: {e}");
74    ///             println!("Caused by: {}", e.source().unwrap());
75    ///         }
76    ///         _ => println!("No error"),
77    ///     }
78    /// }
79    /// ```
80    #[stable(feature = "error_source", since = "1.30.0")]
81    fn source(&self) -> Option<&(dyn Error + 'static)> {
82        None
83    }
84
85    /// Gets the `TypeId` of `self`.
86    #[doc(hidden)]
87    #[unstable(
88        feature = "error_type_id",
89        reason = "this is memory-unsafe to override in user code",
90        issue = "60784"
91    )]
92    fn type_id(&self, _: private::Internal) -> TypeId
93    where
94        Self: 'static,
95    {
96        TypeId::of::<Self>()
97    }
98
99    /// ```
100    /// if let Err(e) = "xc".parse::<u32>() {
101    ///     // Print `e` itself, no need for description().
102    ///     eprintln!("Error: {e}");
103    /// }
104    /// ```
105    #[stable(feature = "rust1", since = "1.0.0")]
106    #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
107    fn description(&self) -> &str {
108        "description() is deprecated; use Display"
109    }
110
111    #[stable(feature = "rust1", since = "1.0.0")]
112    #[deprecated(
113        since = "1.33.0",
114        note = "replaced by Error::source, which can support downcasting"
115    )]
116    #[allow(missing_docs)]
117    fn cause(&self) -> Option<&dyn Error> {
118        self.source()
119    }
120
121    /// Provides type-based access to context intended for error reports.
122    ///
123    /// Used in conjunction with [`Request::provide_value`] and [`Request::provide_ref`] to extract
124    /// references to member variables from `dyn Error` trait objects.
125    ///
126    /// # Example
127    ///
128    /// ```rust
129    /// #![feature(error_generic_member_access)]
130    /// use core::fmt;
131    /// use core::error::{request_ref, Request};
132    ///
133    /// #[derive(Debug)]
134    /// enum MyLittleTeaPot {
135    ///     Empty,
136    /// }
137    ///
138    /// #[derive(Debug)]
139    /// struct MyBacktrace {
140    ///     // ...
141    /// }
142    ///
143    /// impl MyBacktrace {
144    ///     fn new() -> MyBacktrace {
145    ///         // ...
146    ///         # MyBacktrace {}
147    ///     }
148    /// }
149    ///
150    /// #[derive(Debug)]
151    /// struct Error {
152    ///     backtrace: MyBacktrace,
153    /// }
154    ///
155    /// impl fmt::Display for Error {
156    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157    ///         write!(f, "Example Error")
158    ///     }
159    /// }
160    ///
161    /// impl std::error::Error for Error {
162    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
163    ///         request
164    ///             .provide_ref::<MyBacktrace>(&self.backtrace);
165    ///     }
166    /// }
167    ///
168    /// fn main() {
169    ///     let backtrace = MyBacktrace::new();
170    ///     let error = Error { backtrace };
171    ///     let dyn_error = &error as &dyn std::error::Error;
172    ///     let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();
173    ///
174    ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
175    ///     assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
176    /// }
177    /// ```
178    #[unstable(feature = "error_generic_member_access", issue = "99301")]
179    #[allow(unused_variables)]
180    fn provide<'a>(&'a self, request: &mut Request<'a>) {}
181}
182
183mod private {
184    // This is a hack to prevent `type_id` from being overridden by `Error`
185    // implementations, since that can enable unsound downcasting.
186    #[unstable(feature = "error_type_id", issue = "60784")]
187    #[derive(Debug)]
188    pub struct Internal;
189}
190
191#[unstable(feature = "never_type", issue = "35121")]
192impl Error for ! {}
193
194// Copied from `any.rs`.
195impl dyn Error + 'static {
196    /// Returns `true` if the inner type is the same as `T`.
197    #[stable(feature = "error_downcast", since = "1.3.0")]
198    #[inline]
199    pub fn is<T: Error + 'static>(&self) -> bool {
200        // Get `TypeId` of the type this function is instantiated with.
201        let t = TypeId::of::<T>();
202
203        // Get `TypeId` of the type in the trait object (`self`).
204        let concrete = self.type_id(private::Internal);
205
206        // Compare both `TypeId`s on equality.
207        t == concrete
208    }
209
210    /// Returns some reference to the inner value if it is of type `T`, or
211    /// `None` if it isn't.
212    #[stable(feature = "error_downcast", since = "1.3.0")]
213    #[inline]
214    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
215        if self.is::<T>() {
216            // SAFETY: `is` ensures this type cast is correct
217            unsafe { Some(&*(self as *const dyn Error as *const T)) }
218        } else {
219            None
220        }
221    }
222
223    /// Returns some mutable reference to the inner value if it is of type `T`, or
224    /// `None` if it isn't.
225    #[stable(feature = "error_downcast", since = "1.3.0")]
226    #[inline]
227    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
228        if self.is::<T>() {
229            // SAFETY: `is` ensures this type cast is correct
230            unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
231        } else {
232            None
233        }
234    }
235}
236
237impl dyn Error + 'static + Send {
238    /// Forwards to the method defined on the type `dyn Error`.
239    #[stable(feature = "error_downcast", since = "1.3.0")]
240    #[inline]
241    pub fn is<T: Error + 'static>(&self) -> bool {
242        <dyn Error + 'static>::is::<T>(self)
243    }
244
245    /// Forwards to the method defined on the type `dyn Error`.
246    #[stable(feature = "error_downcast", since = "1.3.0")]
247    #[inline]
248    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
249        <dyn Error + 'static>::downcast_ref::<T>(self)
250    }
251
252    /// Forwards to the method defined on the type `dyn Error`.
253    #[stable(feature = "error_downcast", since = "1.3.0")]
254    #[inline]
255    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
256        <dyn Error + 'static>::downcast_mut::<T>(self)
257    }
258}
259
260impl dyn Error + 'static + Send + Sync {
261    /// Forwards to the method defined on the type `dyn Error`.
262    #[stable(feature = "error_downcast", since = "1.3.0")]
263    #[inline]
264    pub fn is<T: Error + 'static>(&self) -> bool {
265        <dyn Error + 'static>::is::<T>(self)
266    }
267
268    /// Forwards to the method defined on the type `dyn Error`.
269    #[stable(feature = "error_downcast", since = "1.3.0")]
270    #[inline]
271    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
272        <dyn Error + 'static>::downcast_ref::<T>(self)
273    }
274
275    /// Forwards to the method defined on the type `dyn Error`.
276    #[stable(feature = "error_downcast", since = "1.3.0")]
277    #[inline]
278    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
279        <dyn Error + 'static>::downcast_mut::<T>(self)
280    }
281}
282
283impl dyn Error {
284    /// Returns an iterator starting with the current error and continuing with
285    /// recursively calling [`Error::source`].
286    ///
287    /// If you want to omit the current error and only use its sources,
288    /// use `skip(1)`.
289    ///
290    /// # Examples
291    ///
292    /// ```
293    /// #![feature(error_iter)]
294    /// use std::error::Error;
295    /// use std::fmt;
296    ///
297    /// #[derive(Debug)]
298    /// struct A;
299    ///
300    /// #[derive(Debug)]
301    /// struct B(Option<Box<dyn Error + 'static>>);
302    ///
303    /// impl fmt::Display for A {
304    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305    ///         write!(f, "A")
306    ///     }
307    /// }
308    ///
309    /// impl fmt::Display for B {
310    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311    ///         write!(f, "B")
312    ///     }
313    /// }
314    ///
315    /// impl Error for A {}
316    ///
317    /// impl Error for B {
318    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
319    ///         self.0.as_ref().map(|e| e.as_ref())
320    ///     }
321    /// }
322    ///
323    /// let b = B(Some(Box::new(A)));
324    ///
325    /// // let err : Box<Error> = b.into(); // or
326    /// let err = &b as &(dyn Error);
327    ///
328    /// let mut iter = err.sources();
329    ///
330    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
331    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
332    /// assert!(iter.next().is_none());
333    /// assert!(iter.next().is_none());
334    /// ```
335    #[unstable(feature = "error_iter", issue = "58520")]
336    #[inline]
337    pub fn sources(&self) -> Source<'_> {
338        // You may think this method would be better in the `Error` trait, and you'd be right.
339        // Unfortunately that doesn't work, not because of the dyn-incompatibility rules but
340        // because we save a reference to `self` in `Source`s below as a trait object.
341        // If this method was declared in `Error`, then `self` would have the type `&T` where
342        // `T` is some concrete type which implements `Error`. We would need to coerce `self`
343        // to have type `&dyn Error`, but that requires that `Self` has a known size
344        // (i.e., `Self: Sized`). We can't put that bound on `Error` since that would forbid
345        // `Error` trait objects, and we can't put that bound on the method because that means
346        // the method can't be called on trait objects (we'd also need the `'static` bound,
347        // but that isn't allowed because methods with bounds on `Self` other than `Sized` are
348        // dyn-incompatible). Requiring an `Unsize` bound is not backwards compatible.
349
350        Source { current: Some(self) }
351    }
352}
353
354/// Requests a value of type `T` from the given `impl Error`.
355///
356/// # Examples
357///
358/// Get a string value from an error.
359///
360/// ```rust
361/// #![feature(error_generic_member_access)]
362/// use std::error::Error;
363/// use core::error::request_value;
364///
365/// fn get_string(err: &impl Error) -> String {
366///     request_value::<String>(err).unwrap()
367/// }
368/// ```
369#[unstable(feature = "error_generic_member_access", issue = "99301")]
370pub fn request_value<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<T>
371where
372    T: 'static,
373{
374    request_by_type_tag::<'a, tags::Value<T>>(err)
375}
376
377/// Requests a reference of type `T` from the given `impl Error`.
378///
379/// # Examples
380///
381/// Get a string reference from an error.
382///
383/// ```rust
384/// #![feature(error_generic_member_access)]
385/// use core::error::Error;
386/// use core::error::request_ref;
387///
388/// fn get_str(err: &impl Error) -> &str {
389///     request_ref::<str>(err).unwrap()
390/// }
391/// ```
392#[unstable(feature = "error_generic_member_access", issue = "99301")]
393pub fn request_ref<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<&'a T>
394where
395    T: 'static + ?Sized,
396{
397    request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(err)
398}
399
400/// Request a specific value by tag from the `Error`.
401fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reified>
402where
403    I: tags::Type<'a>,
404{
405    let mut tagged = Tagged { tag_id: TypeId::of::<I>(), value: TaggedOption::<'a, I>(None) };
406    err.provide(tagged.as_request());
407    tagged.value.0
408}
409
410///////////////////////////////////////////////////////////////////////////////
411// Request and its methods
412///////////////////////////////////////////////////////////////////////////////
413
414/// `Request` supports generic, type-driven access to data. Its use is currently restricted to the
415/// standard library in cases where trait authors wish to allow trait implementors to share generic
416/// information across trait boundaries. The motivating and prototypical use case is
417/// `core::error::Error` which would otherwise require a method per concrete type (eg.
418/// `std::backtrace::Backtrace` instance that implementors want to expose to users).
419///
420/// # Data flow
421///
422/// To describe the intended data flow for Request objects, let's consider two conceptual users
423/// separated by API boundaries:
424///
425/// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers
426/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
427///
428/// * Producer - the producer provides objects when requested via Request; eg. a library with an
429/// an `Error` implementation that automatically captures backtraces at the time instances are
430/// created.
431///
432/// The consumer only needs to know where to submit their request and are expected to handle the
433/// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.
434///
435/// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise
436/// prepared to generate a value requested). eg, `backtrace::Backtrace` or
437/// `std::backtrace::Backtrace`
438/// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the
439/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
440/// `request_value` to simplify obtaining an `Option<T>` for a given type.
441/// * The Producer, when requested, populates the given Request object which is given as a mutable
442/// reference.
443/// * The Consumer extracts a value or reference to the requested type from the `Request` object
444/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
445/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
446/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
447/// Producer cannot currently offer an instance of the requested type, not it can't or never will.
448///
449/// # Examples
450///
451/// The best way to demonstrate this is using an example implementation of `Error`'s `provide` trait
452/// method:
453///
454/// ```
455/// #![feature(error_generic_member_access)]
456/// use core::fmt;
457/// use core::error::Request;
458/// use core::error::request_ref;
459///
460/// #[derive(Debug)]
461/// enum MyLittleTeaPot {
462///     Empty,
463/// }
464///
465/// #[derive(Debug)]
466/// struct MyBacktrace {
467///     // ...
468/// }
469///
470/// impl MyBacktrace {
471///     fn new() -> MyBacktrace {
472///         // ...
473///         # MyBacktrace {}
474///     }
475/// }
476///
477/// #[derive(Debug)]
478/// struct Error {
479///     backtrace: MyBacktrace,
480/// }
481///
482/// impl fmt::Display for Error {
483///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484///         write!(f, "Example Error")
485///     }
486/// }
487///
488/// impl std::error::Error for Error {
489///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
490///         request
491///             .provide_ref::<MyBacktrace>(&self.backtrace);
492///     }
493/// }
494///
495/// fn main() {
496///     let backtrace = MyBacktrace::new();
497///     let error = Error { backtrace };
498///     let dyn_error = &error as &dyn std::error::Error;
499///     let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();
500///
501///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
502///     assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
503/// }
504/// ```
505///
506#[unstable(feature = "error_generic_member_access", issue = "99301")]
507#[repr(transparent)]
508pub struct Request<'a>(Tagged<dyn Erased<'a> + 'a>);
509
510impl<'a> Request<'a> {
511    /// Provides a value or other type with only static lifetimes.
512    ///
513    /// # Examples
514    ///
515    /// Provides an `u8`.
516    ///
517    /// ```rust
518    /// #![feature(error_generic_member_access)]
519    ///
520    /// use core::error::Request;
521    ///
522    /// #[derive(Debug)]
523    /// struct SomeConcreteType { field: u8 }
524    ///
525    /// impl std::fmt::Display for SomeConcreteType {
526    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
527    ///         write!(f, "{} failed", self.field)
528    ///     }
529    /// }
530    ///
531    /// impl std::error::Error for SomeConcreteType {
532    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
533    ///         request.provide_value::<u8>(self.field);
534    ///     }
535    /// }
536    /// ```
537    #[unstable(feature = "error_generic_member_access", issue = "99301")]
538    pub fn provide_value<T>(&mut self, value: T) -> &mut Self
539    where
540        T: 'static,
541    {
542        self.provide::<tags::Value<T>>(value)
543    }
544
545    /// Provides a value or other type with only static lifetimes computed using a closure.
546    ///
547    /// # Examples
548    ///
549    /// Provides a `String` by cloning.
550    ///
551    /// ```rust
552    /// #![feature(error_generic_member_access)]
553    ///
554    /// use core::error::Request;
555    ///
556    /// #[derive(Debug)]
557    /// struct SomeConcreteType { field: String }
558    ///
559    /// impl std::fmt::Display for SomeConcreteType {
560    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
561    ///         write!(f, "{} failed", self.field)
562    ///     }
563    /// }
564    ///
565    /// impl std::error::Error for SomeConcreteType {
566    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
567    ///         request.provide_value_with::<String>(|| self.field.clone());
568    ///     }
569    /// }
570    /// ```
571    #[unstable(feature = "error_generic_member_access", issue = "99301")]
572    pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
573    where
574        T: 'static,
575    {
576        self.provide_with::<tags::Value<T>>(fulfil)
577    }
578
579    /// Provides a reference. The referee type must be bounded by `'static`,
580    /// but may be unsized.
581    ///
582    /// # Examples
583    ///
584    /// Provides a reference to a field as a `&str`.
585    ///
586    /// ```rust
587    /// #![feature(error_generic_member_access)]
588    ///
589    /// use core::error::Request;
590    ///
591    /// #[derive(Debug)]
592    /// struct SomeConcreteType { field: String }
593    ///
594    /// impl std::fmt::Display for SomeConcreteType {
595    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
596    ///         write!(f, "{} failed", self.field)
597    ///     }
598    /// }
599    ///
600    /// impl std::error::Error for SomeConcreteType {
601    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
602    ///         request.provide_ref::<str>(&self.field);
603    ///     }
604    /// }
605    /// ```
606    #[unstable(feature = "error_generic_member_access", issue = "99301")]
607    pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
608        self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
609    }
610
611    /// Provides a reference computed using a closure. The referee type
612    /// must be bounded by `'static`, but may be unsized.
613    ///
614    /// # Examples
615    ///
616    /// Provides a reference to a field as a `&str`.
617    ///
618    /// ```rust
619    /// #![feature(error_generic_member_access)]
620    ///
621    /// use core::error::Request;
622    ///
623    /// #[derive(Debug)]
624    /// struct SomeConcreteType { business: String, party: String }
625    /// fn today_is_a_weekday() -> bool { true }
626    ///
627    /// impl std::fmt::Display for SomeConcreteType {
628    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
629    ///         write!(f, "{} failed", self.business)
630    ///     }
631    /// }
632    ///
633    /// impl std::error::Error for SomeConcreteType {
634    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
635    ///         request.provide_ref_with::<str>(|| {
636    ///             if today_is_a_weekday() {
637    ///                 &self.business
638    ///             } else {
639    ///                 &self.party
640    ///             }
641    ///         });
642    ///     }
643    /// }
644    /// ```
645    #[unstable(feature = "error_generic_member_access", issue = "99301")]
646    pub fn provide_ref_with<T: ?Sized + 'static>(
647        &mut self,
648        fulfil: impl FnOnce() -> &'a T,
649    ) -> &mut Self {
650        self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
651    }
652
653    /// Provides a value with the given `Type` tag.
654    fn provide<I>(&mut self, value: I::Reified) -> &mut Self
655    where
656        I: tags::Type<'a>,
657    {
658        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
659            res.0 = Some(value);
660        }
661        self
662    }
663
664    /// Provides a value with the given `Type` tag, using a closure to prevent unnecessary work.
665    fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
666    where
667        I: tags::Type<'a>,
668    {
669        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
670            res.0 = Some(fulfil());
671        }
672        self
673    }
674
675    /// Checks if the `Request` would be satisfied if provided with a
676    /// value of the specified type. If the type does not match or has
677    /// already been provided, returns false.
678    ///
679    /// # Examples
680    ///
681    /// Checks if a `u8` still needs to be provided and then provides
682    /// it.
683    ///
684    /// ```rust
685    /// #![feature(error_generic_member_access)]
686    ///
687    /// use core::error::Request;
688    /// use core::error::request_value;
689    ///
690    /// #[derive(Debug)]
691    /// struct Parent(Option<u8>);
692    ///
693    /// impl std::fmt::Display for Parent {
694    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
695    ///         write!(f, "a parent failed")
696    ///     }
697    /// }
698    ///
699    /// impl std::error::Error for Parent {
700    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
701    ///         if let Some(v) = self.0 {
702    ///             request.provide_value::<u8>(v);
703    ///         }
704    ///     }
705    /// }
706    ///
707    /// #[derive(Debug)]
708    /// struct Child {
709    ///     parent: Parent,
710    /// }
711    ///
712    /// impl Child {
713    ///     // Pretend that this takes a lot of resources to evaluate.
714    ///     fn an_expensive_computation(&self) -> Option<u8> {
715    ///         Some(99)
716    ///     }
717    /// }
718    ///
719    /// impl std::fmt::Display for Child {
720    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
721    ///         write!(f, "child failed: \n  because of parent: {}", self.parent)
722    ///     }
723    /// }
724    ///
725    /// impl std::error::Error for Child {
726    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
727    ///         // In general, we don't know if this call will provide
728    ///         // an `u8` value or not...
729    ///         self.parent.provide(request);
730    ///
731    ///         // ...so we check to see if the `u8` is needed before
732    ///         // we run our expensive computation.
733    ///         if request.would_be_satisfied_by_value_of::<u8>() {
734    ///             if let Some(v) = self.an_expensive_computation() {
735    ///                 request.provide_value::<u8>(v);
736    ///             }
737    ///         }
738    ///
739    ///         // The request will be satisfied now, regardless of if
740    ///         // the parent provided the value or we did.
741    ///         assert!(!request.would_be_satisfied_by_value_of::<u8>());
742    ///     }
743    /// }
744    ///
745    /// let parent = Parent(Some(42));
746    /// let child = Child { parent };
747    /// assert_eq!(Some(42), request_value::<u8>(&child));
748    ///
749    /// let parent = Parent(None);
750    /// let child = Child { parent };
751    /// assert_eq!(Some(99), request_value::<u8>(&child));
752    ///
753    /// ```
754    #[unstable(feature = "error_generic_member_access", issue = "99301")]
755    pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
756    where
757        T: 'static,
758    {
759        self.would_be_satisfied_by::<tags::Value<T>>()
760    }
761
762    /// Checks if the `Request` would be satisfied if provided with a
763    /// reference to a value of the specified type.
764    ///
765    /// If the type does not match or has already been provided, returns false.
766    ///
767    /// # Examples
768    ///
769    /// Checks if a `&str` still needs to be provided and then provides
770    /// it.
771    ///
772    /// ```rust
773    /// #![feature(error_generic_member_access)]
774    ///
775    /// use core::error::Request;
776    /// use core::error::request_ref;
777    ///
778    /// #[derive(Debug)]
779    /// struct Parent(Option<String>);
780    ///
781    /// impl std::fmt::Display for Parent {
782    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
783    ///         write!(f, "a parent failed")
784    ///     }
785    /// }
786    ///
787    /// impl std::error::Error for Parent {
788    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
789    ///         if let Some(v) = &self.0 {
790    ///             request.provide_ref::<str>(v);
791    ///         }
792    ///     }
793    /// }
794    ///
795    /// #[derive(Debug)]
796    /// struct Child {
797    ///     parent: Parent,
798    ///     name: String,
799    /// }
800    ///
801    /// impl Child {
802    ///     // Pretend that this takes a lot of resources to evaluate.
803    ///     fn an_expensive_computation(&self) -> Option<&str> {
804    ///         Some(&self.name)
805    ///     }
806    /// }
807    ///
808    /// impl std::fmt::Display for Child {
809    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
810    ///         write!(f, "{} failed: \n  {}", self.name, self.parent)
811    ///     }
812    /// }
813    ///
814    /// impl std::error::Error for Child {
815    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
816    ///         // In general, we don't know if this call will provide
817    ///         // a `str` reference or not...
818    ///         self.parent.provide(request);
819    ///
820    ///         // ...so we check to see if the `&str` is needed before
821    ///         // we run our expensive computation.
822    ///         if request.would_be_satisfied_by_ref_of::<str>() {
823    ///             if let Some(v) = self.an_expensive_computation() {
824    ///                 request.provide_ref::<str>(v);
825    ///             }
826    ///         }
827    ///
828    ///         // The request will be satisfied now, regardless of if
829    ///         // the parent provided the reference or we did.
830    ///         assert!(!request.would_be_satisfied_by_ref_of::<str>());
831    ///     }
832    /// }
833    ///
834    /// let parent = Parent(Some("parent".into()));
835    /// let child = Child { parent, name: "child".into() };
836    /// assert_eq!(Some("parent"), request_ref::<str>(&child));
837    ///
838    /// let parent = Parent(None);
839    /// let child = Child { parent, name: "child".into() };
840    /// assert_eq!(Some("child"), request_ref::<str>(&child));
841    /// ```
842    #[unstable(feature = "error_generic_member_access", issue = "99301")]
843    pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
844    where
845        T: ?Sized + 'static,
846    {
847        self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
848    }
849
850    fn would_be_satisfied_by<I>(&self) -> bool
851    where
852        I: tags::Type<'a>,
853    {
854        matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
855    }
856}
857
858#[unstable(feature = "error_generic_member_access", issue = "99301")]
859impl<'a> Debug for Request<'a> {
860    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
861        f.debug_struct("Request").finish_non_exhaustive()
862    }
863}
864
865///////////////////////////////////////////////////////////////////////////////
866// Type tags
867///////////////////////////////////////////////////////////////////////////////
868
869pub(crate) mod tags {
870    //! Type tags are used to identify a type using a separate value. This module includes type tags
871    //! for some very common types.
872    //!
873    //! Currently type tags are not exposed to the user. But in the future, if you want to use the
874    //! Request API with more complex types (typically those including lifetime parameters), you
875    //! will need to write your own tags.
876
877    use crate::marker::PhantomData;
878
879    /// This trait is implemented by specific tag types in order to allow
880    /// describing a type which can be requested for a given lifetime `'a`.
881    ///
882    /// A few example implementations for type-driven tags can be found in this
883    /// module, although crates may also implement their own tags for more
884    /// complex types with internal lifetimes.
885    pub(crate) trait Type<'a>: Sized + 'static {
886        /// The type of values which may be tagged by this tag for the given
887        /// lifetime.
888        type Reified: 'a;
889    }
890
891    /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
892    /// `?Sized` bound). E.g., `str`.
893    pub(crate) trait MaybeSizedType<'a>: Sized + 'static {
894        type Reified: 'a + ?Sized;
895    }
896
897    impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
898        type Reified = T::Reified;
899    }
900
901    /// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.
902    #[derive(Debug)]
903    pub(crate) struct Value<T: 'static>(PhantomData<T>);
904
905    impl<'a, T: 'static> Type<'a> for Value<T> {
906        type Reified = T;
907    }
908
909    /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).
910    #[derive(Debug)]
911    pub(crate) struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
912
913    impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
914        type Reified = T;
915    }
916
917    /// Type-based tag for reference types (`&'a T`, where T is represented by
918    /// `<I as MaybeSizedType<'a>>::Reified`.
919    #[derive(Debug)]
920    pub(crate) struct Ref<I>(PhantomData<I>);
921
922    impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
923        type Reified = &'a I::Reified;
924    }
925}
926
927/// An `Option` with a type tag `I`.
928///
929/// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
930/// option. The type can be checked dynamically using `Tagged::tag_id` and since this is statically
931/// checked for the concrete type, there is some degree of type safety.
932#[repr(transparent)]
933pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);
934
935impl<'a, I: tags::Type<'a>> Tagged<TaggedOption<'a, I>> {
936    pub(crate) fn as_request(&mut self) -> &mut Request<'a> {
937        let erased = self as &mut Tagged<dyn Erased<'a> + 'a>;
938        // SAFETY: transmuting `&mut Tagged<dyn Erased<'a> + 'a>` to `&mut Request<'a>` is safe since
939        // `Request` is repr(transparent).
940        unsafe { &mut *(erased as *mut Tagged<dyn Erased<'a>> as *mut Request<'a>) }
941    }
942}
943
944/// Represents a type-erased but identifiable object.
945///
946/// This trait is exclusively implemented by the `TaggedOption` type.
947unsafe trait Erased<'a>: 'a {}
948
949unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {}
950
951struct Tagged<E: ?Sized> {
952    tag_id: TypeId,
953    value: E,
954}
955
956impl<'a> Tagged<dyn Erased<'a> + 'a> {
957    /// Returns some reference to the dynamic value if it is tagged with `I`,
958    /// or `None` otherwise.
959    #[inline]
960    fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
961    where
962        I: tags::Type<'a>,
963    {
964        if self.tag_id == TypeId::of::<I>() {
965            // SAFETY: Just checked whether we're pointing to an I.
966            Some(&unsafe { &*(self as *const Self).cast::<Tagged<TaggedOption<'a, I>>>() }.value)
967        } else {
968            None
969        }
970    }
971
972    /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
973    /// or `None` otherwise.
974    #[inline]
975    fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
976    where
977        I: tags::Type<'a>,
978    {
979        if self.tag_id == TypeId::of::<I>() {
980            Some(
981                // SAFETY: Just checked whether we're pointing to an I.
982                &mut unsafe { &mut *(self as *mut Self).cast::<Tagged<TaggedOption<'a, I>>>() }
983                    .value,
984            )
985        } else {
986            None
987        }
988    }
989}
990
991/// An iterator over an [`Error`] and its sources.
992///
993/// If you want to omit the initial error and only process
994/// its sources, use `skip(1)`.
995#[unstable(feature = "error_iter", issue = "58520")]
996#[derive(Clone, Debug)]
997pub struct Source<'a> {
998    current: Option<&'a (dyn Error + 'static)>,
999}
1000
1001#[unstable(feature = "error_iter", issue = "58520")]
1002impl<'a> Iterator for Source<'a> {
1003    type Item = &'a (dyn Error + 'static);
1004
1005    fn next(&mut self) -> Option<Self::Item> {
1006        let current = self.current;
1007        self.current = self.current.and_then(Error::source);
1008        current
1009    }
1010
1011    fn size_hint(&self) -> (usize, Option<usize>) {
1012        if self.current.is_some() { (1, None) } else { (0, Some(0)) }
1013    }
1014}
1015
1016#[unstable(feature = "error_iter", issue = "58520")]
1017impl<'a> crate::iter::FusedIterator for Source<'a> {}
1018
1019#[stable(feature = "error_by_ref", since = "1.51.0")]
1020impl<'a, T: Error + ?Sized> Error for &'a T {
1021    #[allow(deprecated, deprecated_in_future)]
1022    fn description(&self) -> &str {
1023        Error::description(&**self)
1024    }
1025
1026    #[allow(deprecated)]
1027    fn cause(&self) -> Option<&dyn Error> {
1028        Error::cause(&**self)
1029    }
1030
1031    fn source(&self) -> Option<&(dyn Error + 'static)> {
1032        Error::source(&**self)
1033    }
1034
1035    fn provide<'b>(&'b self, request: &mut Request<'b>) {
1036        Error::provide(&**self, request);
1037    }
1038}
1039
1040#[stable(feature = "fmt_error", since = "1.11.0")]
1041impl Error for crate::fmt::Error {
1042    #[allow(deprecated)]
1043    fn description(&self) -> &str {
1044        "an error occurred when formatting an argument"
1045    }
1046}
1047
1048#[stable(feature = "try_borrow", since = "1.13.0")]
1049impl Error for crate::cell::BorrowError {
1050    #[allow(deprecated)]
1051    fn description(&self) -> &str {
1052        "already mutably borrowed"
1053    }
1054}
1055
1056#[stable(feature = "try_borrow", since = "1.13.0")]
1057impl Error for crate::cell::BorrowMutError {
1058    #[allow(deprecated)]
1059    fn description(&self) -> &str {
1060        "already borrowed"
1061    }
1062}
1063
1064#[stable(feature = "try_from", since = "1.34.0")]
1065impl Error for crate::char::CharTryFromError {
1066    #[allow(deprecated)]
1067    fn description(&self) -> &str {
1068        "converted integer out of range for `char`"
1069    }
1070}
1071
1072#[stable(feature = "duration_checked_float", since = "1.66.0")]
1073impl Error for crate::time::TryFromFloatSecsError {}
1074
1075#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
1076impl Error for crate::ffi::FromBytesUntilNulError {}
1077
1078#[stable(feature = "get_many_mut", since = "1.86.0")]
1079impl Error for crate::slice::GetDisjointMutError {}