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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy