@@ -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,84 @@ 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 [`context`] and [`context_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_in_core)]
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 = "generic_member_access" , issue = "none" ) ]
368+ fn provide < ' a > ( & ' a self , _req : & mut Demand < ' a > ) { }
369+ }
370+
371+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
372+ impl Provider for dyn Error + ' static {
373+ fn provide < ' a > ( & ' a self , req : & mut Demand < ' a > ) {
374+ self . provide ( req)
375+ }
298376}
299377
300378mod private {
@@ -831,6 +909,18 @@ impl dyn Error + 'static {
831909 None
832910 }
833911 }
912+
913+ /// Request a reference to context of type `T`.
914+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
915+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
916+ core:: any:: request_ref ( self )
917+ }
918+
919+ /// Request a value to context of type `T`.
920+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
921+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
922+ core:: any:: request_value ( self )
923+ }
834924}
835925
836926impl dyn Error + ' static + Send {
@@ -854,6 +944,18 @@ impl dyn Error + 'static + Send {
854944 pub fn downcast_mut < T : Error + ' static > ( & mut self ) -> Option < & mut T > {
855945 <dyn Error + ' static >:: downcast_mut :: < T > ( self )
856946 }
947+
948+ /// Request a reference to context of type `T`.
949+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
950+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
951+ <dyn Error + ' static >:: request_ref ( self )
952+ }
953+
954+ /// Request a value to context of type `T`.
955+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
956+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
957+ <dyn Error + ' static >:: request_value ( self )
958+ }
857959}
858960
859961impl dyn Error + ' static + Send + Sync {
@@ -877,6 +979,18 @@ impl dyn Error + 'static + Send + Sync {
877979 pub fn downcast_mut < T : Error + ' static > ( & mut self ) -> Option < & mut T > {
878980 <dyn Error + ' static >:: downcast_mut :: < T > ( self )
879981 }
982+
983+ /// Request a reference to context of type `T`.
984+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
985+ pub fn request_ref < T : ?Sized + ' static > ( & self ) -> Option < & T > {
986+ <dyn Error + ' static >:: request_ref ( self )
987+ }
988+
989+ /// Request a value to context of type `T`.
990+ #[ unstable( feature = "generic_member_access" , issue = "none" ) ]
991+ pub fn request_value < T : ' static > ( & self ) -> Option < T > {
992+ <dyn Error + ' static >:: request_value ( self )
993+ }
880994}
881995
882996impl dyn Error {
0 commit comments