@@ -320,13 +320,11 @@ extern crate backtrace;
320
320
321
321
use std:: error;
322
322
use std:: iter:: Iterator ;
323
+ #[ cfg( feature = "backtrace" ) ]
323
324
use std:: sync:: Arc ;
324
325
325
326
#[ cfg( feature = "backtrace" ) ]
326
327
pub use backtrace:: Backtrace ;
327
- #[ cfg( not( feature = "backtrace" ) ) ]
328
- #[ derive( Debug ) ]
329
- pub enum Backtrace { }
330
328
331
329
mod quick_error;
332
330
@@ -361,6 +359,8 @@ macro_rules! error_chain {
361
359
pub struct $error_name( pub $error_kind_name,
362
360
pub $crate:: State ) ;
363
361
362
+ impl_error!( $error_name $error_kind_name $( $link_error_path) * ) ;
363
+
364
364
impl $error_name {
365
365
/// Returns the kind of the error.
366
366
pub fn kind( & self ) -> & $error_kind_name {
@@ -371,11 +371,6 @@ macro_rules! error_chain {
371
371
pub fn iter( & self ) -> $crate:: ErrorChainIter {
372
372
$crate:: ErrorChainIter ( Some ( self ) )
373
373
}
374
-
375
- /// Returns the backtrace associated with this error.
376
- pub fn backtrace( & self ) -> Option <& $crate:: Backtrace > {
377
- self . 1 . backtrace. as_ref( ) . map( |v| & * * v)
378
- }
379
374
}
380
375
381
376
impl :: std:: error:: Error for $error_name {
@@ -511,29 +506,6 @@ macro_rules! error_chain {
511
506
}
512
507
}
513
508
514
- impl $crate:: ChainedError for $error_name {
515
- type ErrorKind = $error_kind_name;
516
-
517
- fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
518
- $error_name( kind, state)
519
- }
520
-
521
- fn extract_backtrace( e: & ( :: std:: error:: Error + Send + ' static ) )
522
- -> Option <Option <:: std:: sync:: Arc <$crate:: Backtrace >>> {
523
- if let Some ( e) = e. downcast_ref:: <$error_name>( ) {
524
- Some ( e. 1 . backtrace. clone( ) )
525
- }
526
- $(
527
- else if let Some ( e) = e. downcast_ref:: <$link_error_path>( ) {
528
- Some ( e. 1 . backtrace. clone( ) )
529
- }
530
- ) *
531
- else {
532
- None
533
- }
534
- }
535
- }
536
-
537
509
// The Result type
538
510
// ---------------
539
511
@@ -649,6 +621,72 @@ macro_rules! error_chain {
649
621
) ;
650
622
}
651
623
624
+ /// Macro used to manage the `backtrace` feature.
625
+ ///
626
+ /// See
627
+ /// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
628
+ /// for more details.
629
+ #[ macro_export]
630
+ #[ doc( hidden) ]
631
+ #[ cfg( feature = "backtrace" ) ]
632
+ macro_rules! impl_error {
633
+ ( $error_name: ident
634
+ $error_kind_name: ident
635
+ $( $link_error_path: path) * ) => {
636
+ impl $error_name {
637
+ /// Returns the backtrace associated with this error.
638
+ pub fn backtrace( & self ) -> Option <& $crate:: Backtrace > {
639
+ self . 1 . backtrace. as_ref( ) . map( |v| & * * v)
640
+ }
641
+ }
642
+
643
+ impl $crate:: ChainedError for $error_name {
644
+ type ErrorKind = $error_kind_name;
645
+
646
+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
647
+ $error_name( kind, state)
648
+ }
649
+
650
+ fn extract_backtrace( e: & ( :: std:: error:: Error + Send + ' static ) )
651
+ -> Option <Option <:: std:: sync:: Arc <$crate:: Backtrace >>> {
652
+ if let Some ( e) = e. downcast_ref:: <$error_name>( ) {
653
+ Some ( e. 1 . backtrace. clone( ) )
654
+ }
655
+ $(
656
+ else if let Some ( e) = e. downcast_ref:: <$link_error_path>( ) {
657
+ Some ( e. 1 . backtrace. clone( ) )
658
+ }
659
+ ) *
660
+ else {
661
+ None
662
+ }
663
+ }
664
+ }
665
+ }
666
+ }
667
+
668
+ /// Macro used to manage the `backtrace` feature.
669
+ ///
670
+ /// See
671
+ /// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
672
+ /// for more details.
673
+ #[ macro_export]
674
+ #[ doc( hidden) ]
675
+ #[ cfg( not( feature = "backtrace" ) ) ]
676
+ macro_rules! impl_error {
677
+ ( $error_name: ident
678
+ $error_kind_name: ident
679
+ $( $link_error_path: path) * ) => {
680
+ impl $crate:: ChainedError for $error_name {
681
+ type ErrorKind = $error_kind_name;
682
+
683
+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
684
+ $error_name( kind, state)
685
+ }
686
+ }
687
+ }
688
+ }
689
+
652
690
/// Iterator over the error chain.
653
691
pub struct ErrorChainIter < ' a > ( pub Option < & ' a error:: Error > ) ;
654
692
@@ -678,12 +716,6 @@ pub fn make_backtrace() -> Option<Arc<Backtrace>> {
678
716
}
679
717
}
680
718
681
- #[ cfg( not( feature = "backtrace" ) ) ]
682
- #[ doc( hidden) ]
683
- pub fn make_backtrace ( ) -> Option < Arc < Backtrace > > {
684
- None
685
- }
686
-
687
719
/// This trait is an implementation detail which must be implemented on each
688
720
/// ErrorKind. We can't do it globally since each ErrorKind is different.
689
721
pub trait ChainedError : error:: Error + Send + ' static {
@@ -695,6 +727,7 @@ pub trait ChainedError: error::Error + Send + 'static {
695
727
/// to avoid generating a new one. It would be better to not
696
728
/// define this in the macro, but types need some additional
697
729
/// machinery to make it work.
730
+ #[ cfg( feature = "backtrace" ) ]
698
731
fn extract_backtrace ( e : & ( error:: Error + Send + ' static ) )
699
732
-> Option < Option < Arc < Backtrace > > > ;
700
733
}
@@ -715,26 +748,38 @@ impl<T, E> ResultExt<T, E> for Result<T, E> where E: ChainedError {
715
748
where F : FnOnce ( ) -> EK ,
716
749
EK : Into < E :: ErrorKind > {
717
750
self . map_err ( move |e| {
718
- let backtrace =
719
- E :: extract_backtrace ( & e) . unwrap_or_else ( make_backtrace) ;
720
-
721
- E :: new ( callback ( ) . into ( ) , State {
722
- next_error : Some ( Box :: new ( e) ) ,
723
- backtrace : backtrace,
724
- } )
751
+ #[ cfg( feature = "backtrace" ) ]
752
+ let ret = {
753
+ let backtrace = E :: extract_backtrace ( & e)
754
+ . unwrap_or_else ( make_backtrace) ;
755
+ E :: new ( callback ( ) . into ( ) , State {
756
+ next_error : Some ( Box :: new ( e) ) ,
757
+ backtrace : backtrace,
758
+ } )
759
+ } ;
760
+ #[ cfg( not( feature = "backtrace" ) ) ]
761
+ let ret = {
762
+ E :: new ( callback ( ) . into ( ) , State {
763
+ next_error : Some ( Box :: new ( e) ) ,
764
+ } )
765
+ } ;
766
+ ret
725
767
} )
726
768
}
727
769
}
728
770
771
+
729
772
/// Common state between errors.
730
773
#[ derive( Debug ) ]
731
774
pub struct State {
732
775
/// Next error in the error chain.
733
776
pub next_error : Option < Box < error:: Error + Send > > ,
734
777
/// Backtrace for the current error.
778
+ #[ cfg( feature = "backtrace" ) ]
735
779
pub backtrace : Option < Arc < Backtrace > > ,
736
780
}
737
781
782
+ #[ cfg( feature = "backtrace" ) ]
738
783
impl Default for State {
739
784
fn default ( ) -> State {
740
785
State {
@@ -743,3 +788,12 @@ impl Default for State {
743
788
}
744
789
}
745
790
}
791
+
792
+ #[ cfg( not( feature = "backtrace" ) ) ]
793
+ impl Default for State {
794
+ fn default ( ) -> State {
795
+ State {
796
+ next_error : None ,
797
+ }
798
+ }
799
+ }
0 commit comments