Movatterモバイル変換


[0]ホーム

URL:


core/
error.rs

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 {}

[8]ページ先頭

©2009-2025 Movatter.jp