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