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#[stable(feature = "rust1", since = "1.0.0")]
50#[rustc_diagnostic_item = "Error"]
51#[rustc_has_incoherent_inherent_impls]
52#[allow(multiple_supertrait_upcastable)]
53pub trait Error: Debug + Display {
54 #[stable(feature = "error_source", since = "1.30.0")]
105 fn source(&self) -> Option<&(dyn Error + 'static)> {
106 None
107 }
108
109 #[doc(hidden)]
111 #[unstable(
112 feature = "error_type_id",
113 reason = "this is memory-unsafe to override in user code",
114 issue = "60784"
115 )]
116 fn type_id(&self, _: private::Internal) -> TypeId
117 where
118 Self: 'static,
119 {
120 TypeId::of::<Self>()
121 }
122
123 #[stable(feature = "rust1", since = "1.0.0")]
130 #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
131 fn description(&self) -> &str {
132 "description() is deprecated; use Display"
133 }
134
135 #[stable(feature = "rust1", since = "1.0.0")]
136 #[deprecated(
137 since = "1.33.0",
138 note = "replaced by Error::source, which can support downcasting"
139 )]
140 #[allow(missing_docs)]
141 fn cause(&self) -> Option<&dyn Error> {
142 self.source()
143 }
144
145 #[unstable(feature = "error_generic_member_access", issue = "99301")]
203 #[allow(unused_variables)]
204 fn provide<'a>(&'a self, request: &mut Request<'a>) {}
205}
206
207mod private {
208 #[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 dyn Error + 'static {
220 #[stable(feature = "error_downcast", since = "1.3.0")]
222 #[inline]
223 pub fn is<T: Error + 'static>(&self) -> bool {
224 let t = TypeId::of::<T>();
226
227 let concrete = self.type_id(private::Internal);
229
230 t == concrete
232 }
233
234 #[stable(feature = "error_downcast", since = "1.3.0")]
237 #[inline]
238 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
239 if self.is::<T>() {
240 unsafe { Some(&*(self as *const dyn Error as *const T)) }
242 } else {
243 None
244 }
245 }
246
247 #[stable(feature = "error_downcast", since = "1.3.0")]
250 #[inline]
251 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
252 if self.is::<T>() {
253 unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
255 } else {
256 None
257 }
258 }
259}
260
261impl dyn Error + 'static + Send {
262 #[stable(feature = "error_downcast", since = "1.3.0")]
264 #[inline]
265 pub fn is<T: Error + 'static>(&self) -> bool {
266 <dyn Error + 'static>::is::<T>(self)
267 }
268
269 #[stable(feature = "error_downcast", since = "1.3.0")]
271 #[inline]
272 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
273 <dyn Error + 'static>::downcast_ref::<T>(self)
274 }
275
276 #[stable(feature = "error_downcast", since = "1.3.0")]
278 #[inline]
279 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
280 <dyn Error + 'static>::downcast_mut::<T>(self)
281 }
282}
283
284impl dyn Error + 'static + Send + Sync {
285 #[stable(feature = "error_downcast", since = "1.3.0")]
287 #[inline]
288 pub fn is<T: Error + 'static>(&self) -> bool {
289 <dyn Error + 'static>::is::<T>(self)
290 }
291
292 #[stable(feature = "error_downcast", since = "1.3.0")]
294 #[inline]
295 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
296 <dyn Error + 'static>::downcast_ref::<T>(self)
297 }
298
299 #[stable(feature = "error_downcast", since = "1.3.0")]
301 #[inline]
302 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
303 <dyn Error + 'static>::downcast_mut::<T>(self)
304 }
305}
306
307impl dyn Error {
308 #[unstable(feature = "error_iter", issue = "58520")]
360 #[inline]
361 pub fn sources(&self) -> Source<'_> {
362 Source { current: Some(self) }
375 }
376}
377
378#[unstable(feature = "error_generic_member_access", issue = "99301")]
394pub fn request_value<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<T>
395where
396 T: 'static,
397{
398 request_by_type_tag::<'a, tags::Value<T>>(err)
399}
400
401#[unstable(feature = "error_generic_member_access", issue = "99301")]
417pub fn request_ref<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<&'a T>
418where
419 T: 'static + ?Sized,
420{
421 request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(err)
422}
423
424fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reified>
426where
427 I: tags::Type<'a>,
428{
429 let mut tagged = Tagged { tag_id: TypeId::of::<I>(), value: TaggedOption::<'a, I>(None) };
430 err.provide(tagged.as_request());
431 tagged.value.0
432}
433
434#[unstable(feature = "error_generic_member_access", issue = "99301")]
531#[repr(transparent)]
532pub struct Request<'a>(Tagged<dyn Erased<'a> + 'a>);
533
534impl<'a> Request<'a> {
535 #[unstable(feature = "error_generic_member_access", issue = "99301")]
562 pub fn provide_value<T>(&mut self, value: T) -> &mut Self
563 where
564 T: 'static,
565 {
566 self.provide::<tags::Value<T>>(value)
567 }
568
569 #[unstable(feature = "error_generic_member_access", issue = "99301")]
596 pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
597 where
598 T: 'static,
599 {
600 self.provide_with::<tags::Value<T>>(fulfil)
601 }
602
603 #[unstable(feature = "error_generic_member_access", issue = "99301")]
631 pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
632 self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
633 }
634
635 #[unstable(feature = "error_generic_member_access", issue = "99301")]
670 pub fn provide_ref_with<T: ?Sized + 'static>(
671 &mut self,
672 fulfil: impl FnOnce() -> &'a T,
673 ) -> &mut Self {
674 self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
675 }
676
677 fn provide<I>(&mut self, value: I::Reified) -> &mut Self
679 where
680 I: tags::Type<'a>,
681 {
682 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
683 res.0 = Some(value);
684 }
685 self
686 }
687
688 fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
690 where
691 I: tags::Type<'a>,
692 {
693 if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
694 res.0 = Some(fulfil());
695 }
696 self
697 }
698
699 #[unstable(feature = "error_generic_member_access", issue = "99301")]
779 pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
780 where
781 T: 'static,
782 {
783 self.would_be_satisfied_by::<tags::Value<T>>()
784 }
785
786 #[unstable(feature = "error_generic_member_access", issue = "99301")]
867 pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
868 where
869 T: ?Sized + 'static,
870 {
871 self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
872 }
873
874 fn would_be_satisfied_by<I>(&self) -> bool
875 where
876 I: tags::Type<'a>,
877 {
878 matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
879 }
880}
881
882#[unstable(feature = "error_generic_member_access", issue = "99301")]
883impl<'a> Debug for Request<'a> {
884 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
885 f.debug_struct("Request").finish_non_exhaustive()
886 }
887}
888
889pub(crate) mod tags {
894 use crate::marker::PhantomData;
902
903 pub(crate) trait Type<'a>: Sized + 'static {
910 type Reified: 'a;
913 }
914
915 pub(crate) trait MaybeSizedType<'a>: Sized + 'static {
918 type Reified: 'a + ?Sized;
919 }
920
921 impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
922 type Reified = T::Reified;
923 }
924
925 #[derive(Debug)]
927 pub(crate) struct Value<T: 'static>(PhantomData<T>);
928
929 impl<'a, T: 'static> Type<'a> for Value<T> {
930 type Reified = T;
931 }
932
933 #[derive(Debug)]
935 pub(crate) struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
936
937 impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
938 type Reified = T;
939 }
940
941 #[derive(Debug)]
944 pub(crate) struct Ref<I>(PhantomData<I>);
945
946 impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
947 type Reified = &'a I::Reified;
948 }
949}
950
951#[repr(transparent)]
957pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);
958
959impl<'a, I: tags::Type<'a>> Tagged<TaggedOption<'a, I>> {
960 pub(crate) fn as_request(&mut self) -> &mut Request<'a> {
961 let erased = self as &mut Tagged<dyn Erased<'a> + 'a>;
962 unsafe { &mut *(erased as *mut Tagged<dyn Erased<'a>> as *mut Request<'a>) }
965 }
966}
967
968unsafe trait Erased<'a>: 'a {}
972
973unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {}
974
975struct Tagged<E: ?Sized> {
976 tag_id: TypeId,
977 value: E,
978}
979
980impl<'a> Tagged<dyn Erased<'a> + 'a> {
981 #[inline]
984 fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
985 where
986 I: tags::Type<'a>,
987 {
988 if self.tag_id == TypeId::of::<I>() {
989 Some(&unsafe { &*(self as *const Self).cast::<Tagged<TaggedOption<'a, I>>>() }.value)
991 } else {
992 None
993 }
994 }
995
996 #[inline]
999 fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
1000 where
1001 I: tags::Type<'a>,
1002 {
1003 if self.tag_id == TypeId::of::<I>() {
1004 Some(
1005 &mut unsafe { &mut *(self as *mut Self).cast::<Tagged<TaggedOption<'a, I>>>() }
1007 .value,
1008 )
1009 } else {
1010 None
1011 }
1012 }
1013}
1014
1015#[unstable(feature = "error_iter", issue = "58520")]
1020#[derive(Clone, Debug)]
1021pub struct Source<'a> {
1022 current: Option<&'a (dyn Error + 'static)>,
1023}
1024
1025#[unstable(feature = "error_iter", issue = "58520")]
1026impl<'a> Iterator for Source<'a> {
1027 type Item = &'a (dyn Error + 'static);
1028
1029 fn next(&mut self) -> Option<Self::Item> {
1030 let current = self.current;
1031 self.current = self.current.and_then(Error::source);
1032 current
1033 }
1034
1035 fn size_hint(&self) -> (usize, Option<usize>) {
1036 if self.current.is_some() { (1, None) } else { (0, Some(0)) }
1037 }
1038}
1039
1040#[unstable(feature = "error_iter", issue = "58520")]
1041impl<'a> crate::iter::FusedIterator for Source<'a> {}
1042
1043#[stable(feature = "error_by_ref", since = "1.51.0")]
1044impl<'a, T: Error + ?Sized> Error for &'a T {
1045 #[allow(deprecated, deprecated_in_future)]
1046 fn description(&self) -> &str {
1047 Error::description(&**self)
1048 }
1049
1050 #[allow(deprecated)]
1051 fn cause(&self) -> Option<&dyn Error> {
1052 Error::cause(&**self)
1053 }
1054
1055 fn source(&self) -> Option<&(dyn Error + 'static)> {
1056 Error::source(&**self)
1057 }
1058
1059 fn provide<'b>(&'b self, request: &mut Request<'b>) {
1060 Error::provide(&**self, request);
1061 }
1062}
1063
1064#[stable(feature = "fmt_error", since = "1.11.0")]
1065impl Error for crate::fmt::Error {
1066 #[allow(deprecated)]
1067 fn description(&self) -> &str {
1068 "an error occurred when formatting an argument"
1069 }
1070}
1071
1072#[stable(feature = "try_borrow", since = "1.13.0")]
1073impl Error for crate::cell::BorrowError {
1074 #[allow(deprecated)]
1075 fn description(&self) -> &str {
1076 "already mutably borrowed"
1077 }
1078}
1079
1080#[stable(feature = "try_borrow", since = "1.13.0")]
1081impl Error for crate::cell::BorrowMutError {
1082 #[allow(deprecated)]
1083 fn description(&self) -> &str {
1084 "already borrowed"
1085 }
1086}
1087
1088#[stable(feature = "try_from", since = "1.34.0")]
1089impl Error for crate::char::CharTryFromError {
1090 #[allow(deprecated)]
1091 fn description(&self) -> &str {
1092 "converted integer out of range for `char`"
1093 }
1094}
1095
1096#[stable(feature = "duration_checked_float", since = "1.66.0")]
1097impl Error for crate::time::TryFromFloatSecsError {}
1098
1099#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
1100impl Error for crate::ffi::FromBytesUntilNulError {}
1101
1102#[stable(feature = "get_many_mut", since = "1.86.0")]
1103impl Error for crate::slice::GetDisjointMutError {}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4