]> git.lizzy.rs Git - rust.git/blob - library/core/src/error.rs
Auto merge of #107443 - cjgillot:generator-less-query, r=compiler-errors
[rust.git] / library / core / src / error.rs
1 #![doc = include_str!("error.md")]
2 #![unstable(feature = "error_in_core", issue = "103765")]
3
4 #[cfg(test)]
5 mod tests;
6
7 use crate::any::{Demand, Provider, TypeId};
8 use crate::fmt::{Debug, Display};
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 #[cfg_attr(not(bootstrap), allow(multiple_supertrait_upcastable))]
32 pub 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 [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
127     /// references to member variables from `dyn Error` trait objects.
128     ///
129     /// # Example
130     ///
131     /// ```rust
132     /// #![feature(provide_any)]
133     /// #![feature(error_generic_member_access)]
134     /// use core::fmt;
135     /// use core::any::Demand;
136     ///
137     /// #[derive(Debug)]
138     /// struct MyBacktrace {
139     ///     // ...
140     /// }
141     ///
142     /// impl MyBacktrace {
143     ///     fn new() -> MyBacktrace {
144     ///         // ...
145     ///         # MyBacktrace {}
146     ///     }
147     /// }
148     ///
149     /// #[derive(Debug)]
150     /// struct SourceError {
151     ///     // ...
152     /// }
153     ///
154     /// impl fmt::Display for SourceError {
155     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156     ///         write!(f, "Example Source Error")
157     ///     }
158     /// }
159     ///
160     /// impl std::error::Error for SourceError {}
161     ///
162     /// #[derive(Debug)]
163     /// struct Error {
164     ///     source: SourceError,
165     ///     backtrace: MyBacktrace,
166     /// }
167     ///
168     /// impl fmt::Display for Error {
169     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170     ///         write!(f, "Example Error")
171     ///     }
172     /// }
173     ///
174     /// impl std::error::Error for Error {
175     ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
176     ///         demand
177     ///             .provide_ref::<MyBacktrace>(&self.backtrace)
178     ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
179     ///     }
180     /// }
181     ///
182     /// fn main() {
183     ///     let backtrace = MyBacktrace::new();
184     ///     let source = SourceError {};
185     ///     let error = Error { source, backtrace };
186     ///     let dyn_error = &error as &dyn std::error::Error;
187     ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
188     ///
189     ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
190     /// }
191     /// ```
192     #[unstable(feature = "error_generic_member_access", issue = "99301")]
193     #[allow(unused_variables)]
194     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
195 }
196
197 #[unstable(feature = "error_generic_member_access", issue = "99301")]
198 impl<E> Provider for E
199 where
200     E: Error + ?Sized,
201 {
202     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
203         self.provide(demand)
204     }
205 }
206
207 mod 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")]
216 impl Error for ! {}
217
218 impl<'a> dyn Error + 'a {
219     /// Request a reference of type `T` as context about this error.
220     #[unstable(feature = "error_generic_member_access", issue = "99301")]
221     pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
222         core::any::request_ref(self)
223     }
224
225     /// Request a value of type `T` as context about this error.
226     #[unstable(feature = "error_generic_member_access", issue = "99301")]
227     pub fn request_value<T: 'static>(&'a self) -> Option<T> {
228         core::any::request_value(self)
229     }
230 }
231
232 // Copied from `any.rs`.
233 impl dyn Error + 'static {
234     /// Returns `true` if the inner type is the same as `T`.
235     #[stable(feature = "error_downcast", since = "1.3.0")]
236     #[inline]
237     pub fn is<T: Error + 'static>(&self) -> bool {
238         // Get `TypeId` of the type this function is instantiated with.
239         let t = TypeId::of::<T>();
240
241         // Get `TypeId` of the type in the trait object (`self`).
242         let concrete = self.type_id(private::Internal);
243
244         // Compare both `TypeId`s on equality.
245         t == concrete
246     }
247
248     /// Returns some reference to the inner value if it is of type `T`, or
249     /// `None` if it isn't.
250     #[stable(feature = "error_downcast", since = "1.3.0")]
251     #[inline]
252     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
253         if self.is::<T>() {
254             // SAFETY: `is` ensures this type cast is correct
255             unsafe { Some(&*(self as *const dyn Error as *const T)) }
256         } else {
257             None
258         }
259     }
260
261     /// Returns some mutable reference to the inner value if it is of type `T`, or
262     /// `None` if it isn't.
263     #[stable(feature = "error_downcast", since = "1.3.0")]
264     #[inline]
265     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
266         if self.is::<T>() {
267             // SAFETY: `is` ensures this type cast is correct
268             unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
269         } else {
270             None
271         }
272     }
273 }
274
275 impl dyn Error + 'static + Send {
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 is<T: Error + 'static>(&self) -> bool {
280         <dyn Error + 'static>::is::<T>(self)
281     }
282
283     /// Forwards to the method defined on the type `dyn Error`.
284     #[stable(feature = "error_downcast", since = "1.3.0")]
285     #[inline]
286     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
287         <dyn Error + 'static>::downcast_ref::<T>(self)
288     }
289
290     /// Forwards to the method defined on the type `dyn Error`.
291     #[stable(feature = "error_downcast", since = "1.3.0")]
292     #[inline]
293     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
294         <dyn Error + 'static>::downcast_mut::<T>(self)
295     }
296
297     /// Request a reference of type `T` as context about this error.
298     #[unstable(feature = "error_generic_member_access", issue = "99301")]
299     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
300         <dyn Error>::request_ref(self)
301     }
302
303     /// Request a value of type `T` as context about this error.
304     #[unstable(feature = "error_generic_member_access", issue = "99301")]
305     pub fn request_value<T: 'static>(&self) -> Option<T> {
306         <dyn Error>::request_value(self)
307     }
308 }
309
310 impl dyn Error + 'static + Send + Sync {
311     /// Forwards to the method defined on the type `dyn Error`.
312     #[stable(feature = "error_downcast", since = "1.3.0")]
313     #[inline]
314     pub fn is<T: Error + 'static>(&self) -> bool {
315         <dyn Error + 'static>::is::<T>(self)
316     }
317
318     /// Forwards to the method defined on the type `dyn Error`.
319     #[stable(feature = "error_downcast", since = "1.3.0")]
320     #[inline]
321     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
322         <dyn Error + 'static>::downcast_ref::<T>(self)
323     }
324
325     /// Forwards to the method defined on the type `dyn Error`.
326     #[stable(feature = "error_downcast", since = "1.3.0")]
327     #[inline]
328     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
329         <dyn Error + 'static>::downcast_mut::<T>(self)
330     }
331
332     /// Request a reference of type `T` as context about this error.
333     #[unstable(feature = "error_generic_member_access", issue = "99301")]
334     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
335         <dyn Error>::request_ref(self)
336     }
337
338     /// Request a value of type `T` as context about this error.
339     #[unstable(feature = "error_generic_member_access", issue = "99301")]
340     pub fn request_value<T: 'static>(&self) -> Option<T> {
341         <dyn Error>::request_value(self)
342     }
343 }
344
345 impl dyn Error {
346     /// Returns an iterator starting with the current error and continuing with
347     /// recursively calling [`Error::source`].
348     ///
349     /// If you want to omit the current error and only use its sources,
350     /// use `skip(1)`.
351     ///
352     /// # Examples
353     ///
354     /// ```
355     /// #![feature(error_iter)]
356     /// use std::error::Error;
357     /// use std::fmt;
358     ///
359     /// #[derive(Debug)]
360     /// struct A;
361     ///
362     /// #[derive(Debug)]
363     /// struct B(Option<Box<dyn Error + 'static>>);
364     ///
365     /// impl fmt::Display for A {
366     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367     ///         write!(f, "A")
368     ///     }
369     /// }
370     ///
371     /// impl fmt::Display for B {
372     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373     ///         write!(f, "B")
374     ///     }
375     /// }
376     ///
377     /// impl Error for A {}
378     ///
379     /// impl Error for B {
380     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
381     ///         self.0.as_ref().map(|e| e.as_ref())
382     ///     }
383     /// }
384     ///
385     /// let b = B(Some(Box::new(A)));
386     ///
387     /// // let err : Box<Error> = b.into(); // or
388     /// let err = &b as &(dyn Error);
389     ///
390     /// let mut iter = err.sources();
391     ///
392     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
393     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
394     /// assert!(iter.next().is_none());
395     /// assert!(iter.next().is_none());
396     /// ```
397     #[unstable(feature = "error_iter", issue = "58520")]
398     #[inline]
399     pub fn sources(&self) -> Source<'_> {
400         // You may think this method would be better in the Error trait, and you'd be right.
401         // Unfortunately that doesn't work, not because of the object safety rules but because we
402         // save a reference to self in Sources below as a trait object. If this method was
403         // declared in Error, then self would have the type &T where T is some concrete type which
404         // implements Error. We would need to coerce self to have type &dyn Error, but that requires
405         // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
406         // since that would forbid Error trait objects, and we can't put that bound on the method
407         // because that means the method can't be called on trait objects (we'd also need the
408         // 'static bound, but that isn't allowed because methods with bounds on Self other than
409         // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
410
411         Source { current: Some(self) }
412     }
413 }
414
415 /// An iterator over an [`Error`] and its sources.
416 ///
417 /// If you want to omit the initial error and only process
418 /// its sources, use `skip(1)`.
419 #[unstable(feature = "error_iter", issue = "58520")]
420 #[derive(Clone, Debug)]
421 pub struct Source<'a> {
422     current: Option<&'a (dyn Error + 'static)>,
423 }
424
425 #[unstable(feature = "error_iter", issue = "58520")]
426 impl<'a> Iterator for Source<'a> {
427     type Item = &'a (dyn Error + 'static);
428
429     fn next(&mut self) -> Option<Self::Item> {
430         let current = self.current;
431         self.current = self.current.and_then(Error::source);
432         current
433     }
434 }
435
436 #[stable(feature = "error_by_ref", since = "1.51.0")]
437 impl<'a, T: Error + ?Sized> Error for &'a T {
438     #[allow(deprecated, deprecated_in_future)]
439     fn description(&self) -> &str {
440         Error::description(&**self)
441     }
442
443     #[allow(deprecated)]
444     fn cause(&self) -> Option<&dyn Error> {
445         Error::cause(&**self)
446     }
447
448     fn source(&self) -> Option<&(dyn Error + 'static)> {
449         Error::source(&**self)
450     }
451
452     fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
453         Error::provide(&**self, demand);
454     }
455 }
456
457 #[stable(feature = "fmt_error", since = "1.11.0")]
458 impl Error for crate::fmt::Error {
459     #[allow(deprecated)]
460     fn description(&self) -> &str {
461         "an error occurred when formatting an argument"
462     }
463 }
464
465 #[stable(feature = "try_borrow", since = "1.13.0")]
466 impl Error for crate::cell::BorrowError {
467     #[allow(deprecated)]
468     fn description(&self) -> &str {
469         "already mutably borrowed"
470     }
471 }
472
473 #[stable(feature = "try_borrow", since = "1.13.0")]
474 impl Error for crate::cell::BorrowMutError {
475     #[allow(deprecated)]
476     fn description(&self) -> &str {
477         "already borrowed"
478     }
479 }
480
481 #[stable(feature = "try_from", since = "1.34.0")]
482 impl Error for crate::char::CharTryFromError {
483     #[allow(deprecated)]
484     fn description(&self) -> &str {
485         "converted integer out of range for `char`"
486     }
487 }
488
489 #[stable(feature = "char_from_str", since = "1.20.0")]
490 impl Error for crate::char::ParseCharError {
491     #[allow(deprecated)]
492     fn description(&self) -> &str {
493         self.__description()
494     }
495 }
496
497 #[stable(feature = "duration_checked_float", since = "1.66.0")]
498 impl Error for crate::time::TryFromFloatSecsError {}
499
500 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
501 impl Error for crate::ffi::FromBytesWithNulError {
502     #[allow(deprecated)]
503     fn description(&self) -> &str {
504         self.__description()
505     }
506 }
507
508 #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
509 impl Error for crate::ffi::FromBytesUntilNulError {}
510
511 #[unstable(feature = "get_many_mut", issue = "104642")]
512 impl<const N: usize> Error for crate::slice::GetManyMutError<N> {}