@@ -50,15 +50,12 @@ macro_rules! error_chain_processed {
5050 }
5151
5252 ) => {
53- /// The Error type.
54- ///
55- /// This struct is made of three things:
56- ///
57- /// - an `ErrorKind` which is used to determine the type of the error.
58- /// - a backtrace, generated when the error is created.
59- /// - an error chain, used for the implementation of `Error::cause()`.
53+ define_error!( $error_name, Inner ) ;
54+
55+ /// Separated for the `boxed-error` feature.
6056 #[ derive( Debug ) ]
61- pub struct $error_name {
57+ #[ doc( hidden) ]
58+ pub struct Inner {
6259 // The members must be `pub` for `links`.
6360 /// The kind of the error.
6461 #[ doc( hidden) ]
@@ -68,16 +65,17 @@ macro_rules! error_chain_processed {
6865 pub state: $crate:: State ,
6966 }
7067
68+ impl Inner {
69+ /// Used in From<ChainedError>.
70+ pub fn into_raw( self ) -> ( $error_kind_name, $crate:: State ) {
71+ ( self . kind, self . state)
72+ }
73+ }
74+
7175 impl $crate:: ChainedError for $error_name {
7276 type ErrorKind = $error_kind_name;
7377
74- fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
75- $error_name {
76- kind: kind,
77- state: state,
78- }
79- }
80-
78+ impl_chained_error_new!( $error_name, $error_kind_name) ;
8179 impl_extract_backtrace!( $error_name
8280 $error_kind_name
8381 $( [ $link_error_path, $( #[ $meta_links] ) * ] ) * ) ;
@@ -87,15 +85,13 @@ macro_rules! error_chain_processed {
8785 impl $error_name {
8886 /// Constructs an error from a kind, and generates a backtrace.
8987 pub fn from_kind( kind: $error_kind_name) -> $error_name {
90- $error_name {
91- kind: kind,
92- state: $crate:: State :: default ( ) ,
93- }
88+ use $crate:: ChainedError ;
89+ Self :: new( kind, $crate:: State :: default ( ) )
9490 }
9591
9692 /// Returns the kind of the error.
9793 pub fn kind( & self ) -> & $error_kind_name {
98- & self . kind
94+ & self . 0 . kind
9995 }
10096
10197 /// Iterates over the error chain.
@@ -105,20 +101,20 @@ macro_rules! error_chain_processed {
105101
106102 /// Returns the backtrace associated with this error.
107103 pub fn backtrace( & self ) -> Option <& $crate:: Backtrace > {
108- self . state. backtrace( )
104+ self . 0 . state. backtrace( )
109105 }
110106 }
111107
112108 impl :: std:: error:: Error for $error_name {
113109 fn description( & self ) -> & str {
114- self . kind. description( )
110+ self . 0 . kind. description( )
115111 }
116112
117113 fn cause( & self ) -> Option <& :: std:: error:: Error > {
118- match self . state. next_error {
114+ match self . 0 . state. next_error {
119115 Some ( ref c) => Some ( & * * c) ,
120116 None => {
121- match self . kind {
117+ match self . 0 . kind {
122118 $(
123119 $( #[ $meta_foreign_links] ) *
124120 $error_kind_name:: $foreign_link_variant( ref foreign_err) => {
@@ -134,18 +130,17 @@ macro_rules! error_chain_processed {
134130
135131 impl :: std:: fmt:: Display for $error_name {
136132 fn fmt( & self , f: & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
137- :: std:: fmt:: Display :: fmt( & self . kind, f)
133+ :: std:: fmt:: Display :: fmt( & self . 0 . kind, f)
138134 }
139135 }
140136
141137 $(
142138 $( #[ $meta_links] ) *
143139 impl From <$link_error_path> for $error_name {
144140 fn from( e: $link_error_path) -> Self {
145- $error_name {
146- kind: $error_kind_name:: $link_variant( e. kind) ,
147- state: e. state,
148- }
141+ use $crate:: ChainedError ;
142+ let ( kind, state) = e. 0 . into_raw( ) ;
143+ Self :: new( $error_kind_name:: $link_variant( kind) , state)
149144 }
150145 }
151146 ) *
@@ -183,7 +178,7 @@ macro_rules! error_chain_processed {
183178 type Target = $error_kind_name;
184179
185180 fn deref( & self ) -> & Self :: Target {
186- & self . kind
181+ & self . 0 . kind
187182 }
188183 }
189184
@@ -245,7 +240,7 @@ macro_rules! error_chain_processed {
245240
246241 impl From <$error_name> for $error_kind_name {
247242 fn from( e: $error_name) -> Self {
248- e. kind
243+ e. 0 . kind
249244 }
250245 }
251246 } ;
@@ -332,13 +327,13 @@ macro_rules! impl_extract_backtrace {
332327 fn extract_backtrace( e: & ( :: std:: error:: Error + Send + ' static ) )
333328 -> Option <Option <:: std:: sync:: Arc <$crate:: Backtrace >>> {
334329 if let Some ( e) = e. downcast_ref:: <$error_name>( ) {
335- return Some ( e. state. backtrace. clone( ) ) ;
330+ return Some ( e. 0 . state. backtrace. clone( ) ) ;
336331 }
337332 $(
338333 $( #[ $meta_links] ) *
339334 {
340335 if let Some ( e) = e. downcast_ref:: <$link_error_path>( ) {
341- return Some ( e. state. backtrace. clone( ) ) ;
336+ return Some ( e. 0 . state. backtrace. clone( ) ) ;
342337 }
343338 }
344339 ) *
@@ -360,3 +355,65 @@ macro_rules! impl_extract_backtrace {
360355 $error_kind_name: ident
361356 $( [ $link_error_path: path, $( #[ $meta_links: meta] ) * ] ) * ) => { }
362357}
358+
359+ #[ macro_export]
360+ #[ doc( hidden) ]
361+ #[ cfg( feature = "boxed-error" ) ]
362+ macro_rules! impl_chained_error_new {
363+ ( $error_name: ident, $error_kind_name: ident) => {
364+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
365+ $error_name( Box :: new( Inner {
366+ kind: kind,
367+ state: state,
368+ } ) )
369+ }
370+ }
371+ }
372+
373+ #[ macro_export]
374+ #[ doc( hidden) ]
375+ #[ cfg( not( feature = "boxed-error" ) ) ]
376+ macro_rules! impl_chained_error_new {
377+ ( $error_name: ident, $error_kind_name: ident) => {
378+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
379+ $error_name( Inner {
380+ kind: kind,
381+ state: state,
382+ } )
383+ }
384+ }
385+ }
386+
387+ #[ macro_export]
388+ #[ doc( hidden) ]
389+ #[ cfg( feature = "boxed-error" ) ]
390+ macro_rules! define_error {
391+ ( $error_name: ident, $inner_name: ident) => {
392+ /// The Error type.
393+ ///
394+ /// This struct is made of three things:
395+ ///
396+ /// - an `ErrorKind` which is used to determine the type of the error.
397+ /// - a backtrace, generated when the error is created.
398+ /// - an error chain, used for the implementation of `Error::cause()`.
399+ #[ derive( Debug ) ]
400+ pub struct $error_name( pub Box <$inner_name>) ;
401+ }
402+ }
403+
404+ #[ macro_export]
405+ #[ doc( hidden) ]
406+ #[ cfg( not( feature = "boxed-error" ) ) ]
407+ macro_rules! define_error {
408+ ( $error_name: ident, $inner_name: ident) => {
409+ /// The Error type.
410+ ///
411+ /// This struct is made of three things:
412+ ///
413+ /// - an `ErrorKind` which is used to determine the type of the error.
414+ /// - a backtrace, generated when the error is created.
415+ /// - an error chain, used for the implementation of `Error::cause()`.
416+ #[ derive( Debug ) ]
417+ pub struct $error_name( pub $inner_name) ;
418+ }
419+ }
0 commit comments