@@ -156,7 +156,7 @@ use core::array;
156156use core:: convert:: Infallible ;
157157
158158use crate :: alloc:: { AllocError , LayoutError } ;
159- use crate :: any:: TypeId ;
159+ use crate :: any:: { Demand , Provider , TypeId } ;
160160use crate :: backtrace:: Backtrace ;
161161use crate :: borrow:: Cow ;
162162use crate :: cell;
@@ -295,6 +295,85 @@ pub trait Error: Debug + Display {
295295 fn cause ( & self ) -> Option < & dyn Error > {
296296 self . source ( )
297297 }
298+
299+ /// Provides type based access to context intended for error reports.
300+ ///
301+ /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
302+ /// references to member variables from `dyn Error` trait objects.
303+ ///
304+ /// # Example
305+ ///
306+ /// ```rust
307+ /// #![feature(provide_any)]
308+ /// #![feature(error_generic_member_access)]
309+ /// use core::fmt;
310+ /// use core::any::Demand;
311+ ///
312+ /// #[derive(Debug)]
313+ /// struct MyBacktrace {
314+ /// // ...
315+ /// }
316+ ///
317+ /// impl MyBacktrace {
318+ /// fn new() -> MyBacktrace {
319+ /// // ...
320+ /// # MyBacktrace {}
321+ /// }
322+ /// }
323+ ///
324+ /// #[derive(Debug)]
325+ /// struct SourceError {
326+ /// // ...
327+ /// }
328+ ///
329+ /// impl fmt::Display for SourceError {
330+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331+ /// write!(f, "Example Source Error")
332+ /// }
333+ /// }
334+ ///
335+ /// impl std::error::Error for SourceError {}
336+ ///
337+ /// #[derive(Debug)]
338+ /// struct Error {
339+ /// source: SourceError,
340+ /// backtrace: MyBacktrace,
341+ /// }
342+ ///
343+ /// impl fmt::Display for Error {
344+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345+ /// write!(f, "Example Error")
346+ /// }
347+ /// }
348+ ///
349+ /// impl std::error::Error for Error {
350+ /// fn provide<'a>(&'a self, req: &mut Demand<'a>) {
351+ /// req
352+ /// .provide_ref::<MyBacktrace>(&self.backtrace)
353+ /// .provide_ref::<dyn std::error::Error + 'static>(&self.source);
354+ /// }
355+ /// }
356+ ///
357+ /// fn main() {
358+ /// let backtrace = MyBacktrace::new();
359+ /// let source = SourceError {};
360+ /// let error = Error { source, backtrace };
361+ /// let dyn_error = &error as &dyn std::error::Error;
362+ /// let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
363+ ///
364+ /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
365+ /// }
366+ /// ```
367+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
368+ #[ allow( unused_variables) ]
369+ fn provide < ' a > ( & ' a self , req : & mut Demand < ' a > ) { }
370+ }
371+
372+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
373+ impl Provider for dyn Error + ' static {
374+ fn provide < ' a > ( & ' a self , req : & mut Demand < ' a > ) {
375+ self . provide ( req)
376+ }
298377}
299378
300379mod private {
@@ -831,6 +910,18 @@ impl dyn Error + 'static {
831910 None
832911 }
833912 }
913+
914+ /// Request a reference of type `T` as context about this error.
915+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
916+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
917+ core:: any:: request_ref ( self )
918+ }
919+
920+ /// Request a value of type `T` as context about this error.
921+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
922+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
923+ core:: any:: request_value ( self )
924+ }
834925}
835926
836927impl dyn Error + ' static + Send {
@@ -854,6 +945,18 @@ impl dyn Error + 'static + Send {
854945 pub fn downcast_mut < T : Error + ' static > ( & mut self ) -> Option < & mut T > {
855946 <dyn Error + ' static >:: downcast_mut :: < T > ( self )
856947 }
948+
949+ /// Request a reference of type `T` as context about this error.
950+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
951+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
952+ <dyn Error + ' static >:: request_ref ( self )
953+ }
954+
955+ /// Request a value of type `T` as context about this error.
956+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
957+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
958+ <dyn Error + ' static >:: request_value ( self )
959+ }
857960}
858961
859962impl dyn Error + ' static + Send + Sync {
@@ -877,6 +980,18 @@ impl dyn Error + 'static + Send + Sync {
877980 pub fn downcast_mut < T : Error + ' static > ( & mut self ) -> Option < & mut T > {
878981 <dyn Error + ' static >:: downcast_mut :: < T > ( self )
879982 }
983+
984+ /// Request a reference of type `T` as context about this error.
985+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
986+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
987+ <dyn Error + ' static >:: request_ref ( self )
988+ }
989+
990+ /// Request a value of type `T` as context about this error.
991+ #[ unstable( feature = "error_generic_member_access" , issue = "none" ) ]
992+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
993+ <dyn Error + ' static >:: request_value ( self )
994+ }
880995}
881996
882997impl dyn Error {
0 commit comments