]> git.proxmox.com Git - rustc.git/blame - library/core/src/error.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / library / core / src / error.rs
CommitLineData
f2b60f7d 1#![doc = include_str!("error.md")]
487cf647 2#![unstable(feature = "error_in_core", issue = "103765")]
f2b60f7d
FG
3
4#[cfg(test)]
5mod tests;
6
7use crate::any::{Demand, Provider, TypeId};
8use 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]
353b0b11 31#[allow(multiple_supertrait_upcastable)]
f2b60f7d
FG
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 [`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")]
198impl<E> Provider for E
199where
200 E: Error + ?Sized,
201{
202 fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
203 self.provide(demand)
204 }
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
218impl<'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`.
233impl 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
275impl 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
310impl 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
345impl 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)]
421pub struct Source<'a> {
422 current: Option<&'a (dyn Error + 'static)>,
423}
424
425#[unstable(feature = "error_iter", issue = "58520")]
426impl<'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")]
437impl<'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")]
458impl 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")]
466impl 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")]
474impl 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")]
482impl Error for crate::char::CharTryFromError {
483 #[allow(deprecated)]
484 fn description(&self) -> &str {
485 "converted integer out of range for `char`"
486 }
487}
488
2b03887a
FG
489#[stable(feature = "duration_checked_float", since = "1.66.0")]
490impl Error for crate::time::TryFromFloatSecsError {}
f2b60f7d 491
9ffffee4 492#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
f2b60f7d 493impl Error for crate::ffi::FromBytesUntilNulError {}
487cf647
FG
494
495#[unstable(feature = "get_many_mut", issue = "104642")]
496impl<const N: usize> Error for crate::slice::GetManyMutError<N> {}