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 {}