1#![doc =include_str!("error.md")]2#![stable(feature ="error_in_core", since ="1.81.0")]34usecrate::any::TypeId;5usecrate::fmt::{self, Debug, Display, Formatter};67/// `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 without12/// 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/// # Error source20///21/// Errors may provide cause information. [`Error::source()`] is generally22/// used when errors cross "abstraction boundaries". If one module must report23/// an error that is caused by an error from a lower-level module, it can allow24/// accessing that error via `Error::source()`. This makes it possible for the25/// high-level module to provide its own errors while also revealing some of the26/// implementation for debugging.27///28/// In error types that wrap an underlying error, the underlying error29/// should be either returned by the outer error's `Error::source()`, or rendered30/// by the outer error's `Display` implementation, but not both.31///32/// # Example33///34/// Implementing the `Error` trait only requires that `Debug` and `Display` are implemented too.35///36/// ```37/// use std::error::Error;38/// use std::fmt;39/// use std::path::PathBuf;40///41/// #[derive(Debug)]42/// struct ReadConfigError {43/// path: PathBuf44/// }45///46/// impl fmt::Display for ReadConfigError {47/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {48/// let path = self.path.display();49/// write!(f, "unable to read configuration at {path}")50/// }51/// }52///53/// impl Error for ReadConfigError {}54/// ```55#[stable(feature ="rust1", since ="1.0.0")]56#[rustc_diagnostic_item ="Error"]57#[rustc_has_incoherent_inherent_impls]58#[allow(multiple_supertrait_upcastable)]59pub traitError: Debug + Display {60/// Returns the lower-level source of this error, if any.61 ///62 /// # Examples63 ///64 /// ```65 /// use std::error::Error;66 /// use std::fmt;67 ///68 /// #[derive(Debug)]69 /// struct SuperError {70 /// source: SuperErrorSideKick,71 /// }72 ///73 /// impl fmt::Display for SuperError {74 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {75 /// write!(f, "SuperError is here!")76 /// }77 /// }78 ///79 /// impl Error for SuperError {80 /// fn source(&self) -> Option<&(dyn Error + 'static)> {81 /// Some(&self.source)82 /// }83 /// }84 ///85 /// #[derive(Debug)]86 /// struct SuperErrorSideKick;87 ///88 /// impl fmt::Display for SuperErrorSideKick {89 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {90 /// write!(f, "SuperErrorSideKick is here!")91 /// }92 /// }93 ///94 /// impl Error for SuperErrorSideKick {}95 ///96 /// fn get_super_error() -> Result<(), SuperError> {97 /// Err(SuperError { source: SuperErrorSideKick })98 /// }99 ///100 /// fn main() {101 /// match get_super_error() {102 /// Err(e) => {103 /// println!("Error: {e}");104 /// println!("Caused by: {}", e.source().unwrap());105 /// }106 /// _ => println!("No error"),107 /// }108 /// }109 /// ```110#[stable(feature ="error_source", since ="1.30.0")]111fnsource(&self) ->Option<&(dynError +'static)> {112None113}114115/// Gets the `TypeId` of `self`.116#[doc(hidden)]117 #[unstable(118 feature ="error_type_id",119 reason ="this is memory-unsafe to override in user code",120 issue ="60784"121)]122fntype_id(&self,_: private::Internal) -> TypeId123where124Self:'static,125 {126 TypeId::of::<Self>()127 }128129/// ```130 /// if let Err(e) = "xc".parse::<u32>() {131 /// // Print `e` itself, no need for description().132 /// eprintln!("Error: {e}");133 /// }134 /// ```135#[stable(feature ="rust1", since ="1.0.0")]136 #[deprecated(since ="1.42.0", note ="use the Display impl or to_string()")]137fndescription(&self) ->&str {138"description() is deprecated; use Display"139}140141#[stable(feature ="rust1", since ="1.0.0")]142 #[deprecated(143 since ="1.33.0",144 note ="replaced by Error::source, which can support downcasting"145)]146 #[allow(missing_docs)]147fncause(&self) ->Option<&dynError> {148self.source()149 }150151/// Provides type-based access to context intended for error reports.152 ///153 /// Used in conjunction with [`Request::provide_value`] and [`Request::provide_ref`] to extract154 /// references to member variables from `dyn Error` trait objects.155 ///156 /// # Example157 ///158 /// ```rust159 /// #![feature(error_generic_member_access)]160 /// use core::fmt;161 /// use core::error::{request_ref, Request};162 ///163 /// #[derive(Debug)]164 /// enum MyLittleTeaPot {165 /// Empty,166 /// }167 ///168 /// #[derive(Debug)]169 /// struct MyBacktrace {170 /// // ...171 /// }172 ///173 /// impl MyBacktrace {174 /// fn new() -> MyBacktrace {175 /// // ...176 /// # MyBacktrace {}177 /// }178 /// }179 ///180 /// #[derive(Debug)]181 /// struct Error {182 /// backtrace: MyBacktrace,183 /// }184 ///185 /// impl fmt::Display for Error {186 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {187 /// write!(f, "Example Error")188 /// }189 /// }190 ///191 /// impl std::error::Error for Error {192 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {193 /// request194 /// .provide_ref::<MyBacktrace>(&self.backtrace);195 /// }196 /// }197 ///198 /// fn main() {199 /// let backtrace = MyBacktrace::new();200 /// let error = Error { backtrace };201 /// let dyn_error = &error as &dyn std::error::Error;202 /// let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();203 ///204 /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref));205 /// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());206 /// }207 /// ```208#[unstable(feature ="error_generic_member_access", issue ="99301")]209 #[allow(unused_variables)]210fnprovide<'a>(&'aself, request:&mutRequest<'a>) {}211}212213modprivate {214// This is a hack to prevent `type_id` from being overridden by `Error`215 // implementations, since that can enable unsound downcasting.216#[unstable(feature ="error_type_id", issue ="60784")]217 #[derive(Debug)]218pub structInternal;219}220221#[unstable(feature ="never_type", issue ="35121")]222implErrorfor ! {}223224// Copied from `any.rs`.225impl dynError +'static{226/// Returns `true` if the inner type is the same as `T`.227#[stable(feature ="error_downcast", since ="1.3.0")]228 #[inline]229pub fnis<T: Error +'static>(&self) -> bool {230// Get `TypeId` of the type this function is instantiated with.231lett = TypeId::of::<T>();232233// Get `TypeId` of the type in the trait object (`self`).234letconcrete =self.type_id(private::Internal);235236// Compare both `TypeId`s on equality.237t == concrete238 }239240/// Returns some reference to the inner value if it is of type `T`, or241 /// `None` if it isn't.242#[stable(feature ="error_downcast", since ="1.3.0")]243 #[inline]244pub fndowncast_ref<T: Error +'static>(&self) ->Option<&T> {245ifself.is::<T>() {246// SAFETY: `is` ensures this type cast is correct247unsafe{Some(&*(selfas*constdynErroras*constT)) }248 }else{249None250}251 }252253/// Returns some mutable reference to the inner value if it is of type `T`, or254 /// `None` if it isn't.255#[stable(feature ="error_downcast", since ="1.3.0")]256 #[inline]257pub fndowncast_mut<T: Error +'static>(&mutself) ->Option<&mutT> {258ifself.is::<T>() {259// SAFETY: `is` ensures this type cast is correct260unsafe{Some(&mut *(selfas*mutdynErroras*mutT)) }261 }else{262None263}264 }265}266267impl dynError +'static+ Send {268/// Forwards to the method defined on the type `dyn Error`.269#[stable(feature ="error_downcast", since ="1.3.0")]270 #[inline]271pub fnis<T: Error +'static>(&self) -> bool {272 <dynError +'static>::is::<T>(self)273 }274275/// Forwards to the method defined on the type `dyn Error`.276#[stable(feature ="error_downcast", since ="1.3.0")]277 #[inline]278pub fndowncast_ref<T: Error +'static>(&self) ->Option<&T> {279 <dynError +'static>::downcast_ref::<T>(self)280 }281282/// Forwards to the method defined on the type `dyn Error`.283#[stable(feature ="error_downcast", since ="1.3.0")]284 #[inline]285pub fndowncast_mut<T: Error +'static>(&mutself) ->Option<&mutT> {286 <dynError +'static>::downcast_mut::<T>(self)287 }288}289290impl dynError +'static+ Send + Sync {291/// Forwards to the method defined on the type `dyn Error`.292#[stable(feature ="error_downcast", since ="1.3.0")]293 #[inline]294pub fnis<T: Error +'static>(&self) -> bool {295 <dynError +'static>::is::<T>(self)296 }297298/// Forwards to the method defined on the type `dyn Error`.299#[stable(feature ="error_downcast", since ="1.3.0")]300 #[inline]301pub fndowncast_ref<T: Error +'static>(&self) ->Option<&T> {302 <dynError +'static>::downcast_ref::<T>(self)303 }304305/// Forwards to the method defined on the type `dyn Error`.306#[stable(feature ="error_downcast", since ="1.3.0")]307 #[inline]308pub fndowncast_mut<T: Error +'static>(&mutself) ->Option<&mutT> {309 <dynError +'static>::downcast_mut::<T>(self)310 }311}312313impl dynError {314/// Returns an iterator starting with the current error and continuing with315 /// recursively calling [`Error::source`].316 ///317 /// If you want to omit the current error and only use its sources,318 /// use `skip(1)`.319 ///320 /// # Examples321 ///322 /// ```323 /// #![feature(error_iter)]324 /// use std::error::Error;325 /// use std::fmt;326 ///327 /// #[derive(Debug)]328 /// struct A;329 ///330 /// #[derive(Debug)]331 /// struct B(Option<Box<dyn Error + 'static>>);332 ///333 /// impl fmt::Display for A {334 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {335 /// write!(f, "A")336 /// }337 /// }338 ///339 /// impl fmt::Display for B {340 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {341 /// write!(f, "B")342 /// }343 /// }344 ///345 /// impl Error for A {}346 ///347 /// impl Error for B {348 /// fn source(&self) -> Option<&(dyn Error + 'static)> {349 /// self.0.as_ref().map(|e| e.as_ref())350 /// }351 /// }352 ///353 /// let b = B(Some(Box::new(A)));354 ///355 /// // let err : Box<Error> = b.into(); // or356 /// let err = &b as &dyn Error;357 ///358 /// let mut iter = err.sources();359 ///360 /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());361 /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());362 /// assert!(iter.next().is_none());363 /// assert!(iter.next().is_none());364 /// ```365#[unstable(feature ="error_iter", issue ="58520")]366 #[inline]367pub fnsources(&self) -> Source<'_> {368// You may think this method would be better in the `Error` trait, and you'd be right.369 // Unfortunately that doesn't work, not because of the dyn-incompatibility rules but370 // because we save a reference to `self` in `Source`s below as a trait object.371 // If this method was declared in `Error`, then `self` would have the type `&T` where372 // `T` is some concrete type which implements `Error`. We would need to coerce `self`373 // to have type `&dyn Error`, but that requires that `Self` has a known size374 // (i.e., `Self: Sized`). We can't put that bound on `Error` since that would forbid375 // `Error` trait objects, and we can't put that bound on the method because that means376 // the method can't be called on trait objects (we'd also need the `'static` bound,377 // but that isn't allowed because methods with bounds on `Self` other than `Sized` are378 // dyn-incompatible). Requiring an `Unsize` bound is not backwards compatible.379380Source { current:Some(self) }381 }382}383384/// Requests a value of type `T` from the given `impl Error`.385///386/// # Examples387///388/// Get a string value from an error.389///390/// ```rust391/// #![feature(error_generic_member_access)]392/// use std::error::Error;393/// use core::error::request_value;394///395/// fn get_string(err: &impl Error) -> String {396/// request_value::<String>(err).unwrap()397/// }398/// ```399#[unstable(feature ="error_generic_member_access", issue ="99301")]400pub fnrequest_value<'a, T>(err:&'a(implError +?Sized)) ->Option<T>401where402T:'static,403{404 request_by_type_tag::<'a, tags::Value<T>>(err)405}406407/// Requests a reference of type `T` from the given `impl Error`.408///409/// # Examples410///411/// Get a string reference from an error.412///413/// ```rust414/// #![feature(error_generic_member_access)]415/// use core::error::Error;416/// use core::error::request_ref;417///418/// fn get_str(err: &impl Error) -> &str {419/// request_ref::<str>(err).unwrap()420/// }421/// ```422#[unstable(feature ="error_generic_member_access", issue ="99301")]423pub fnrequest_ref<'a, T>(err:&'a(implError +?Sized)) ->Option<&'aT>424where425T:'static+?Sized,426{427 request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(err)428}429430/// Request a specific value by tag from the `Error`.431fnrequest_by_type_tag<'a, I>(err:&'a(implError +?Sized)) ->Option<I::Reified>432where433I: tags::Type<'a>,434{435letmuttagged = Tagged { tag_id: TypeId::of::<I>(), value: TaggedOption::<'a, I>(None) };436 err.provide(tagged.as_request());437 tagged.value.0438}439440///////////////////////////////////////////////////////////////////////////////441// Request and its methods442///////////////////////////////////////////////////////////////////////////////443444/// `Request` supports generic, type-driven access to data. Its use is currently restricted to the445/// standard library in cases where trait authors wish to allow trait implementors to share generic446/// information across trait boundaries. The motivating and prototypical use case is447/// `core::error::Error` which would otherwise require a method per concrete type (eg.448/// `std::backtrace::Backtrace` instance that implementors want to expose to users).449///450/// # Data flow451///452/// To describe the intended data flow for Request objects, let's consider two conceptual users453/// separated by API boundaries:454///455/// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers456/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.457///458/// * Producer - the producer provides objects when requested via Request; eg. a library with an459/// an `Error` implementation that automatically captures backtraces at the time instances are460/// created.461///462/// The consumer only needs to know where to submit their request and are expected to handle the463/// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.464///465/// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise466/// prepared to generate a value requested). eg, `backtrace::Backtrace` or467/// `std::backtrace::Backtrace`468/// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the469/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and470/// `request_value` to simplify obtaining an `Option<T>` for a given type.471/// * The Producer, when requested, populates the given Request object which is given as a mutable472/// reference.473/// * The Consumer extracts a value or reference to the requested type from the `Request` object474/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `475/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at476/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the477/// Producer cannot currently offer an instance of the requested type, not it can't or never will.478///479/// # Examples480///481/// The best way to demonstrate this is using an example implementation of `Error`'s `provide` trait482/// method:483///484/// ```485/// #![feature(error_generic_member_access)]486/// use core::fmt;487/// use core::error::Request;488/// use core::error::request_ref;489///490/// #[derive(Debug)]491/// enum MyLittleTeaPot {492/// Empty,493/// }494///495/// #[derive(Debug)]496/// struct MyBacktrace {497/// // ...498/// }499///500/// impl MyBacktrace {501/// fn new() -> MyBacktrace {502/// // ...503/// # MyBacktrace {}504/// }505/// }506///507/// #[derive(Debug)]508/// struct Error {509/// backtrace: MyBacktrace,510/// }511///512/// impl fmt::Display for Error {513/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {514/// write!(f, "Example Error")515/// }516/// }517///518/// impl std::error::Error for Error {519/// fn provide<'a>(&'a self, request: &mut Request<'a>) {520/// request521/// .provide_ref::<MyBacktrace>(&self.backtrace);522/// }523/// }524///525/// fn main() {526/// let backtrace = MyBacktrace::new();527/// let error = Error { backtrace };528/// let dyn_error = &error as &dyn std::error::Error;529/// let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();530///531/// assert!(core::ptr::eq(&error.backtrace, backtrace_ref));532/// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());533/// }534/// ```535///536#[unstable(feature ="error_generic_member_access", issue ="99301")]537#[repr(transparent)]538pub structRequest<'a>(Tagged<dynErased<'a> +'a>);539540impl<'a> Request<'a> {541/// Provides a value or other type with only static lifetimes.542 ///543 /// # Examples544 ///545 /// Provides an `u8`.546 ///547 /// ```rust548 /// #![feature(error_generic_member_access)]549 ///550 /// use core::error::Request;551 ///552 /// #[derive(Debug)]553 /// struct SomeConcreteType { field: u8 }554 ///555 /// impl std::fmt::Display for SomeConcreteType {556 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {557 /// write!(f, "{} failed", self.field)558 /// }559 /// }560 ///561 /// impl std::error::Error for SomeConcreteType {562 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {563 /// request.provide_value::<u8>(self.field);564 /// }565 /// }566 /// ```567#[unstable(feature ="error_generic_member_access", issue ="99301")]568pub fnprovide_value<T>(&mutself, value: T) ->&mutSelf569where570T:'static,571 {572self.provide::<tags::Value<T>>(value)573 }574575/// Provides a value or other type with only static lifetimes computed using a closure.576 ///577 /// # Examples578 ///579 /// Provides a `String` by cloning.580 ///581 /// ```rust582 /// #![feature(error_generic_member_access)]583 ///584 /// use core::error::Request;585 ///586 /// #[derive(Debug)]587 /// struct SomeConcreteType { field: String }588 ///589 /// impl std::fmt::Display for SomeConcreteType {590 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {591 /// write!(f, "{} failed", self.field)592 /// }593 /// }594 ///595 /// impl std::error::Error for SomeConcreteType {596 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {597 /// request.provide_value_with::<String>(|| self.field.clone());598 /// }599 /// }600 /// ```601#[unstable(feature ="error_generic_member_access", issue ="99301")]602pub fnprovide_value_with<T>(&mutself, fulfil:implFnOnce() -> T) ->&mutSelf603where604T:'static,605 {606self.provide_with::<tags::Value<T>>(fulfil)607 }608609/// Provides a reference. The referee type must be bounded by `'static`,610 /// but may be unsized.611 ///612 /// # Examples613 ///614 /// Provides a reference to a field as a `&str`.615 ///616 /// ```rust617 /// #![feature(error_generic_member_access)]618 ///619 /// use core::error::Request;620 ///621 /// #[derive(Debug)]622 /// struct SomeConcreteType { field: String }623 ///624 /// impl std::fmt::Display for SomeConcreteType {625 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {626 /// write!(f, "{} failed", self.field)627 /// }628 /// }629 ///630 /// impl std::error::Error for SomeConcreteType {631 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {632 /// request.provide_ref::<str>(&self.field);633 /// }634 /// }635 /// ```636#[unstable(feature ="error_generic_member_access", issue ="99301")]637pub fnprovide_ref<T:?Sized +'static>(&mutself, value:&'aT) ->&mutSelf{638self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)639 }640641/// Provides a reference computed using a closure. The referee type642 /// must be bounded by `'static`, but may be unsized.643 ///644 /// # Examples645 ///646 /// Provides a reference to a field as a `&str`.647 ///648 /// ```rust649 /// #![feature(error_generic_member_access)]650 ///651 /// use core::error::Request;652 ///653 /// #[derive(Debug)]654 /// struct SomeConcreteType { business: String, party: String }655 /// fn today_is_a_weekday() -> bool { true }656 ///657 /// impl std::fmt::Display for SomeConcreteType {658 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {659 /// write!(f, "{} failed", self.business)660 /// }661 /// }662 ///663 /// impl std::error::Error for SomeConcreteType {664 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {665 /// request.provide_ref_with::<str>(|| {666 /// if today_is_a_weekday() {667 /// &self.business668 /// } else {669 /// &self.party670 /// }671 /// });672 /// }673 /// }674 /// ```675#[unstable(feature ="error_generic_member_access", issue ="99301")]676pub fnprovide_ref_with<T:?Sized +'static>(677&mutself,678 fulfil:implFnOnce() ->&'aT,679 ) ->&mutSelf{680self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)681 }682683/// Provides a value with the given `Type` tag.684fnprovide<I>(&mutself, value: I::Reified) ->&mutSelf685where686I: tags::Type<'a>,687 {688if letSome(res @ TaggedOption(None)) =self.0.downcast_mut::<I>() {689 res.0=Some(value);690 }691self692}693694/// Provides a value with the given `Type` tag, using a closure to prevent unnecessary work.695fnprovide_with<I>(&mutself, fulfil:implFnOnce() -> I::Reified) ->&mutSelf696where697I: tags::Type<'a>,698 {699if letSome(res @ TaggedOption(None)) =self.0.downcast_mut::<I>() {700 res.0=Some(fulfil());701 }702self703}704705/// Checks if the `Request` would be satisfied if provided with a706 /// value of the specified type. If the type does not match or has707 /// already been provided, returns false.708 ///709 /// # Examples710 ///711 /// Checks if a `u8` still needs to be provided and then provides712 /// it.713 ///714 /// ```rust715 /// #![feature(error_generic_member_access)]716 ///717 /// use core::error::Request;718 /// use core::error::request_value;719 ///720 /// #[derive(Debug)]721 /// struct Parent(Option<u8>);722 ///723 /// impl std::fmt::Display for Parent {724 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {725 /// write!(f, "a parent failed")726 /// }727 /// }728 ///729 /// impl std::error::Error for Parent {730 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {731 /// if let Some(v) = self.0 {732 /// request.provide_value::<u8>(v);733 /// }734 /// }735 /// }736 ///737 /// #[derive(Debug)]738 /// struct Child {739 /// parent: Parent,740 /// }741 ///742 /// impl Child {743 /// // Pretend that this takes a lot of resources to evaluate.744 /// fn an_expensive_computation(&self) -> Option<u8> {745 /// Some(99)746 /// }747 /// }748 ///749 /// impl std::fmt::Display for Child {750 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {751 /// write!(f, "child failed: \n because of parent: {}", self.parent)752 /// }753 /// }754 ///755 /// impl std::error::Error for Child {756 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {757 /// // In general, we don't know if this call will provide758 /// // an `u8` value or not...759 /// self.parent.provide(request);760 ///761 /// // ...so we check to see if the `u8` is needed before762 /// // we run our expensive computation.763 /// if request.would_be_satisfied_by_value_of::<u8>() {764 /// if let Some(v) = self.an_expensive_computation() {765 /// request.provide_value::<u8>(v);766 /// }767 /// }768 ///769 /// // The request will be satisfied now, regardless of if770 /// // the parent provided the value or we did.771 /// assert!(!request.would_be_satisfied_by_value_of::<u8>());772 /// }773 /// }774 ///775 /// let parent = Parent(Some(42));776 /// let child = Child { parent };777 /// assert_eq!(Some(42), request_value::<u8>(&child));778 ///779 /// let parent = Parent(None);780 /// let child = Child { parent };781 /// assert_eq!(Some(99), request_value::<u8>(&child));782 ///783 /// ```784#[unstable(feature ="error_generic_member_access", issue ="99301")]785pub fnwould_be_satisfied_by_value_of<T>(&self) -> bool786where787T:'static,788 {789self.would_be_satisfied_by::<tags::Value<T>>()790 }791792/// Checks if the `Request` would be satisfied if provided with a793 /// reference to a value of the specified type.794 ///795 /// If the type does not match or has already been provided, returns false.796 ///797 /// # Examples798 ///799 /// Checks if a `&str` still needs to be provided and then provides800 /// it.801 ///802 /// ```rust803 /// #![feature(error_generic_member_access)]804 ///805 /// use core::error::Request;806 /// use core::error::request_ref;807 ///808 /// #[derive(Debug)]809 /// struct Parent(Option<String>);810 ///811 /// impl std::fmt::Display for Parent {812 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {813 /// write!(f, "a parent failed")814 /// }815 /// }816 ///817 /// impl std::error::Error for Parent {818 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {819 /// if let Some(v) = &self.0 {820 /// request.provide_ref::<str>(v);821 /// }822 /// }823 /// }824 ///825 /// #[derive(Debug)]826 /// struct Child {827 /// parent: Parent,828 /// name: String,829 /// }830 ///831 /// impl Child {832 /// // Pretend that this takes a lot of resources to evaluate.833 /// fn an_expensive_computation(&self) -> Option<&str> {834 /// Some(&self.name)835 /// }836 /// }837 ///838 /// impl std::fmt::Display for Child {839 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {840 /// write!(f, "{} failed: \n {}", self.name, self.parent)841 /// }842 /// }843 ///844 /// impl std::error::Error for Child {845 /// fn provide<'a>(&'a self, request: &mut Request<'a>) {846 /// // In general, we don't know if this call will provide847 /// // a `str` reference or not...848 /// self.parent.provide(request);849 ///850 /// // ...so we check to see if the `&str` is needed before851 /// // we run our expensive computation.852 /// if request.would_be_satisfied_by_ref_of::<str>() {853 /// if let Some(v) = self.an_expensive_computation() {854 /// request.provide_ref::<str>(v);855 /// }856 /// }857 ///858 /// // The request will be satisfied now, regardless of if859 /// // the parent provided the reference or we did.860 /// assert!(!request.would_be_satisfied_by_ref_of::<str>());861 /// }862 /// }863 ///864 /// let parent = Parent(Some("parent".into()));865 /// let child = Child { parent, name: "child".into() };866 /// assert_eq!(Some("parent"), request_ref::<str>(&child));867 ///868 /// let parent = Parent(None);869 /// let child = Child { parent, name: "child".into() };870 /// assert_eq!(Some("child"), request_ref::<str>(&child));871 /// ```872#[unstable(feature ="error_generic_member_access", issue ="99301")]873pub fnwould_be_satisfied_by_ref_of<T>(&self) -> bool874where875T:?Sized +'static,876 {877self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()878 }879880fnwould_be_satisfied_by<I>(&self) -> bool881where882I: tags::Type<'a>,883 {884matches!(self.0.downcast::<I>(),Some(TaggedOption(None)))885 }886}887888#[unstable(feature ="error_generic_member_access", issue ="99301")]889impl<'a> DebugforRequest<'a> {890fnfmt(&self, f:&mutFormatter<'_>) -> fmt::Result {891 f.debug_struct("Request").finish_non_exhaustive()892 }893}894895///////////////////////////////////////////////////////////////////////////////896// Type tags897///////////////////////////////////////////////////////////////////////////////898899pub(crate)modtags {900//! Type tags are used to identify a type using a separate value. This module includes type tags901 //! for some very common types.902 //!903 //! Currently type tags are not exposed to the user. But in the future, if you want to use the904 //! Request API with more complex types (typically those including lifetime parameters), you905 //! will need to write your own tags.906907usecrate::marker::PhantomData;908909/// This trait is implemented by specific tag types in order to allow910 /// describing a type which can be requested for a given lifetime `'a`.911 ///912 /// A few example implementations for type-driven tags can be found in this913 /// module, although crates may also implement their own tags for more914 /// complex types with internal lifetimes.915pub(crate)traitType<'a>: Sized +'static{916/// The type of values which may be tagged by this tag for the given917 /// lifetime.918typeReified:'a;919 }920921/// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a922 /// `?Sized` bound). E.g., `str`.923pub(crate)traitMaybeSizedType<'a>: Sized +'static{924typeReified:'a+?Sized;925 }926927impl<'a, T: Type<'a>> MaybeSizedType<'a>forT {928typeReified = T::Reified;929 }930931/// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.932#[derive(Debug)]933pub(crate)structValue<T:'static>(PhantomData<T>);934935impl<'a, T:'static> Type<'a>forValue<T> {936typeReified = T;937 }938939/// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).940#[derive(Debug)]941pub(crate)structMaybeSizedValue<T:?Sized +'static>(PhantomData<T>);942943impl<'a, T:?Sized +'static> MaybeSizedType<'a>forMaybeSizedValue<T> {944typeReified = T;945 }946947/// Type-based tag for reference types (`&'a T`, where T is represented by948 /// `<I as MaybeSizedType<'a>>::Reified`.949#[derive(Debug)]950pub(crate)structRef<I>(PhantomData<I>);951952impl<'a, I: MaybeSizedType<'a>> Type<'a>forRef<I> {953typeReified =&'aI::Reified;954 }955}956957/// An `Option` with a type tag `I`.958///959/// Since this struct implements `Erased`, the type can be erased to make a dynamically typed960/// option. The type can be checked dynamically using `Tagged::tag_id` and since this is statically961/// checked for the concrete type, there is some degree of type safety.962#[repr(transparent)]963pub(crate)structTaggedOption<'a, I: tags::Type<'a>>(pubOption<I::Reified>);964965impl<'a, I: tags::Type<'a>> Tagged<TaggedOption<'a, I>> {966pub(crate)fnas_request(&mutself) ->&mutRequest<'a> {967leterased =selfas&mutTagged<dynErased<'a> +'a>;968// SAFETY: transmuting `&mut Tagged<dyn Erased<'a> + 'a>` to `&mut Request<'a>` is safe since969 // `Request` is repr(transparent).970unsafe{&mut *(erasedas*mutTagged<dynErased<'a>>as*mutRequest<'a>) }971 }972}973974/// Represents a type-erased but identifiable object.975///976/// This trait is exclusively implemented by the `TaggedOption` type.977unsafe traitErased<'a>:'a{}978979unsafe impl<'a, I: tags::Type<'a>> Erased<'a>forTaggedOption<'a, I> {}980981structTagged<E:?Sized> {982 tag_id: TypeId,983 value: E,984}985986impl<'a> Tagged<dynErased<'a> +'a> {987/// Returns some reference to the dynamic value if it is tagged with `I`,988 /// or `None` otherwise.989#[inline]990fndowncast<I>(&self) ->Option<&TaggedOption<'a, I>>991where992I: tags::Type<'a>,993 {994ifself.tag_id == TypeId::of::<I>() {995// SAFETY: Just checked whether we're pointing to an I.996Some(&unsafe{&*(selfas*constSelf).cast::<Tagged<TaggedOption<'a, I>>>() }.value)997 }else{998None999}1000 }10011002/// Returns some mutable reference to the dynamic value if it is tagged with `I`,1003 /// or `None` otherwise.1004#[inline]1005fndowncast_mut<I>(&mutself) ->Option<&mutTaggedOption<'a, I>>1006where1007I: tags::Type<'a>,1008 {1009ifself.tag_id == TypeId::of::<I>() {1010Some(1011// SAFETY: Just checked whether we're pointing to an I.1012&mutunsafe{&mut *(selfas*mutSelf).cast::<Tagged<TaggedOption<'a, I>>>() }1013 .value,1014 )1015 }else{1016None1017}1018 }1019}10201021/// An iterator over an [`Error`] and its sources.1022///1023/// If you want to omit the initial error and only process1024/// its sources, use `skip(1)`.1025#[unstable(feature ="error_iter", issue ="58520")]1026#[derive(Clone, Debug)]1027pub structSource<'a> {1028 current:Option<&'a(dynError +'static)>,1029}10301031#[unstable(feature ="error_iter", issue ="58520")]1032impl<'a> IteratorforSource<'a> {1033typeItem =&'a(dynError +'static);10341035fnnext(&mutself) ->Option<Self::Item> {1036letcurrent =self.current;1037self.current =self.current.and_then(Error::source);1038 current1039 }10401041fnsize_hint(&self) -> (usize,Option<usize>) {1042ifself.current.is_some() { (1,None) }else{ (0,Some(0)) }1043 }1044}10451046#[unstable(feature ="error_iter", issue ="58520")]1047impl<'a>crate::iter::FusedIteratorforSource<'a> {}10481049#[stable(feature ="error_by_ref", since ="1.51.0")]1050impl<'a, T: Error +?Sized> Errorfor&'aT {1051#[allow(deprecated)]1052fncause(&self) ->Option<&dynError> {1053 Error::cause(&**self)1054 }10551056fnsource(&self) ->Option<&(dynError +'static)> {1057 Error::source(&**self)1058 }10591060fnprovide<'b>(&'bself, request:&mutRequest<'b>) {1061 Error::provide(&**self, request);1062 }1063}10641065#[stable(feature ="fmt_error", since ="1.11.0")]1066implErrorforcrate::fmt::Error {}10671068#[stable(feature ="try_borrow", since ="1.13.0")]1069implErrorforcrate::cell::BorrowError {}10701071#[stable(feature ="try_borrow", since ="1.13.0")]1072implErrorforcrate::cell::BorrowMutError {}10731074#[stable(feature ="try_from", since ="1.34.0")]1075implErrorforcrate::char::CharTryFromError {}10761077#[stable(feature ="duration_checked_float", since ="1.66.0")]1078implErrorforcrate::time::TryFromFloatSecsError {}10791080#[stable(feature ="cstr_from_bytes_until_nul", since ="1.69.0")]1081implErrorforcrate::ffi::FromBytesUntilNulError {}10821083#[stable(feature ="get_many_mut", since ="1.86.0")]1084implErrorforcrate::slice::GetDisjointMutError {}