1
1
#[ cfg( test) ]
2
2
mod tests;
3
3
4
+ mod repr_unpacked;
5
+ use repr_unpacked:: Repr ;
6
+
4
7
use crate :: convert:: From ;
5
8
use crate :: error;
6
9
use crate :: fmt;
@@ -66,15 +69,38 @@ impl fmt::Debug for Error {
66
69
}
67
70
}
68
71
69
- enum Repr {
72
+ enum ErrorData < C > {
70
73
Os ( i32 ) ,
71
74
Simple ( ErrorKind ) ,
72
- // &str is a fat pointer, but &&str is a thin pointer.
73
- SimpleMessage ( ErrorKind , & ' static & ' static str ) ,
74
- Custom ( Box < Custom > ) ,
75
+ SimpleMessage ( & ' static SimpleMessage ) ,
76
+ Custom ( C ) ,
77
+ }
78
+
79
+ #[ repr( align( 4 ) ) ]
80
+ #[ doc( hidden) ]
81
+ pub ( crate ) struct SimpleMessage {
82
+ kind : ErrorKind ,
83
+ message : & ' static str ,
84
+ }
85
+
86
+ impl SimpleMessage {
87
+ pub ( crate ) const fn new ( kind : ErrorKind , message : & ' static str ) -> Self {
88
+ Self { kind, message }
89
+ }
90
+ }
91
+
92
+ /// Create and return an `io::Error` for a given `ErrorKind` and constant
93
+ /// message. This doesn't allocate.
94
+ pub ( crate ) macro const_io_error ( $kind: expr, $message: expr $( , ) ?) {
95
+ $crate:: io:: error:: Error :: from_static_message ( {
96
+ const MESSAGE_DATA : $crate:: io:: error:: SimpleMessage =
97
+ $crate:: io:: error:: SimpleMessage :: new ( $kind, $message) ;
98
+ & MESSAGE_DATA
99
+ } )
75
100
}
76
101
77
102
#[ derive( Debug ) ]
103
+ #[ repr( align( 4 ) ) ]
78
104
struct Custom {
79
105
kind : ErrorKind ,
80
106
error : Box < dyn error:: Error + Send + Sync > ,
@@ -396,7 +422,7 @@ impl From<ErrorKind> for Error {
396
422
/// ```
397
423
#[ inline]
398
424
fn from ( kind : ErrorKind ) -> Error {
399
- Error { repr : Repr :: Simple ( kind) }
425
+ Error { repr : Repr :: new_simple ( kind) }
400
426
}
401
427
}
402
428
@@ -461,20 +487,22 @@ impl Error {
461
487
}
462
488
463
489
fn _new ( kind : ErrorKind , error : Box < dyn error:: Error + Send + Sync > ) -> Error {
464
- Error { repr : Repr :: Custom ( Box :: new ( Custom { kind, error } ) ) }
490
+ Error { repr : Repr :: new_custom ( Box :: new ( Custom { kind, error } ) ) }
465
491
}
466
492
467
- /// Creates a new I/O error from a known kind of error as well as a
468
- /// constant message.
493
+ /// Creates a new I/O error from a known kind of error as well as a constant
494
+ /// message.
469
495
///
470
496
/// This function does not allocate.
471
497
///
472
- /// This function should maybe change to
473
- /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
474
- /// in the future, when const generics allow that.
498
+ /// You should not use this directly, and instead use the `const_io_error!`
499
+ /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
500
+ ///
501
+ /// This function should maybe change to `from_static_message<const MSG: &'static
502
+ /// str>(kind: ErrorKind)` in the future, when const generics allow that.
475
503
#[ inline]
476
- pub ( crate ) const fn new_const ( kind : ErrorKind , message : & ' static & ' static str ) -> Error {
477
- Self { repr : Repr :: SimpleMessage ( kind , message ) }
504
+ pub ( crate ) const fn from_static_message ( msg : & ' static SimpleMessage ) -> Error {
505
+ Self { repr : Repr :: new_simple_message ( msg ) }
478
506
}
479
507
480
508
/// Returns an error representing the last OS error which occurred.
@@ -532,7 +560,7 @@ impl Error {
532
560
#[ must_use]
533
561
#[ inline]
534
562
pub fn from_raw_os_error ( code : i32 ) -> Error {
535
- Error { repr : Repr :: Os ( code) }
563
+ Error { repr : Repr :: new_os ( code) }
536
564
}
537
565
538
566
/// Returns the OS error that this error represents (if any).
@@ -568,11 +596,11 @@ impl Error {
568
596
#[ must_use]
569
597
#[ inline]
570
598
pub fn raw_os_error ( & self ) -> Option < i32 > {
571
- match self . repr {
572
- Repr :: Os ( i) => Some ( i) ,
573
- Repr :: Custom ( ..) => None ,
574
- Repr :: Simple ( ..) => None ,
575
- Repr :: SimpleMessage ( ..) => None ,
599
+ match self . repr . data ( ) {
600
+ ErrorData :: Os ( i) => Some ( i) ,
601
+ ErrorData :: Custom ( ..) => None ,
602
+ ErrorData :: Simple ( ..) => None ,
603
+ ErrorData :: SimpleMessage ( ..) => None ,
576
604
}
577
605
}
578
606
@@ -607,11 +635,11 @@ impl Error {
607
635
#[ must_use]
608
636
#[ inline]
609
637
pub fn get_ref ( & self ) -> Option < & ( dyn error:: Error + Send + Sync + ' static ) > {
610
- match self . repr {
611
- Repr :: Os ( ..) => None ,
612
- Repr :: Simple ( ..) => None ,
613
- Repr :: SimpleMessage ( ..) => None ,
614
- Repr :: Custom ( ref c) => Some ( & * c. error ) ,
638
+ match self . repr . data ( ) {
639
+ ErrorData :: Os ( ..) => None ,
640
+ ErrorData :: Simple ( ..) => None ,
641
+ ErrorData :: SimpleMessage ( ..) => None ,
642
+ ErrorData :: Custom ( c) => Some ( & * c. error ) ,
615
643
}
616
644
}
617
645
@@ -681,11 +709,11 @@ impl Error {
681
709
#[ must_use]
682
710
#[ inline]
683
711
pub fn get_mut ( & mut self ) -> Option < & mut ( dyn error:: Error + Send + Sync + ' static ) > {
684
- match self . repr {
685
- Repr :: Os ( ..) => None ,
686
- Repr :: Simple ( ..) => None ,
687
- Repr :: SimpleMessage ( ..) => None ,
688
- Repr :: Custom ( ref mut c) => Some ( & mut * c. error ) ,
712
+ match self . repr . data_mut ( ) {
713
+ ErrorData :: Os ( ..) => None ,
714
+ ErrorData :: Simple ( ..) => None ,
715
+ ErrorData :: SimpleMessage ( ..) => None ,
716
+ ErrorData :: Custom ( c) => Some ( & mut * c. error ) ,
689
717
}
690
718
}
691
719
@@ -720,11 +748,11 @@ impl Error {
720
748
#[ must_use = "`self` will be dropped if the result is not used" ]
721
749
#[ inline]
722
750
pub fn into_inner ( self ) -> Option < Box < dyn error:: Error + Send + Sync > > {
723
- match self . repr {
724
- Repr :: Os ( ..) => None ,
725
- Repr :: Simple ( ..) => None ,
726
- Repr :: SimpleMessage ( ..) => None ,
727
- Repr :: Custom ( c) => Some ( c. error ) ,
751
+ match self . repr . into_data ( ) {
752
+ ErrorData :: Os ( ..) => None ,
753
+ ErrorData :: Simple ( ..) => None ,
754
+ ErrorData :: SimpleMessage ( ..) => None ,
755
+ ErrorData :: Custom ( c) => Some ( c. error ) ,
728
756
}
729
757
}
730
758
@@ -750,44 +778,46 @@ impl Error {
750
778
#[ must_use]
751
779
#[ inline]
752
780
pub fn kind ( & self ) -> ErrorKind {
753
- match self . repr {
754
- Repr :: Os ( code) => sys:: decode_error_kind ( code) ,
755
- Repr :: Custom ( ref c) => c. kind ,
756
- Repr :: Simple ( kind) => kind,
757
- Repr :: SimpleMessage ( kind , _ ) => kind,
781
+ match self . repr . data ( ) {
782
+ ErrorData :: Os ( code) => sys:: decode_error_kind ( code) ,
783
+ ErrorData :: Custom ( ref c) => c. kind ,
784
+ ErrorData :: Simple ( kind) => kind,
785
+ ErrorData :: SimpleMessage ( m ) => m . kind ,
758
786
}
759
787
}
760
788
}
761
789
762
790
impl fmt:: Debug for Repr {
763
791
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
764
- match * self {
765
- Repr :: Os ( code) => fmt
792
+ match self . data ( ) {
793
+ ErrorData :: Os ( code) => fmt
766
794
. debug_struct ( "Os" )
767
795
. field ( "code" , & code)
768
796
. field ( "kind" , & sys:: decode_error_kind ( code) )
769
797
. field ( "message" , & sys:: os:: error_string ( code) )
770
798
. finish ( ) ,
771
- Repr :: Custom ( ref c) => fmt:: Debug :: fmt ( & c, fmt) ,
772
- Repr :: Simple ( kind) => fmt. debug_tuple ( "Kind" ) . field ( & kind) . finish ( ) ,
773
- Repr :: SimpleMessage ( kind, & message) => {
774
- fmt. debug_struct ( "Error" ) . field ( "kind" , & kind) . field ( "message" , & message) . finish ( )
775
- }
799
+ ErrorData :: Custom ( c) => fmt:: Debug :: fmt ( & c, fmt) ,
800
+ ErrorData :: Simple ( kind) => fmt. debug_tuple ( "Kind" ) . field ( & kind) . finish ( ) ,
801
+ ErrorData :: SimpleMessage ( msg) => fmt
802
+ . debug_struct ( "Error" )
803
+ . field ( "kind" , & msg. kind )
804
+ . field ( "message" , & msg. message )
805
+ . finish ( ) ,
776
806
}
777
807
}
778
808
}
779
809
780
810
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
781
811
impl fmt:: Display for Error {
782
812
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
783
- match self . repr {
784
- Repr :: Os ( code) => {
813
+ match self . repr . data ( ) {
814
+ ErrorData :: Os ( code) => {
785
815
let detail = sys:: os:: error_string ( code) ;
786
816
write ! ( fmt, "{} (os error {})" , detail, code)
787
817
}
788
- Repr :: Custom ( ref c) => c. error . fmt ( fmt) ,
789
- Repr :: Simple ( kind) => write ! ( fmt, "{}" , kind. as_str( ) ) ,
790
- Repr :: SimpleMessage ( _ , & msg) => msg. fmt ( fmt) ,
818
+ ErrorData :: Custom ( ref c) => c. error . fmt ( fmt) ,
819
+ ErrorData :: Simple ( kind) => write ! ( fmt, "{}" , kind. as_str( ) ) ,
820
+ ErrorData :: SimpleMessage ( msg) => msg. message . fmt ( fmt) ,
791
821
}
792
822
}
793
823
}
@@ -796,29 +826,29 @@ impl fmt::Display for Error {
796
826
impl error:: Error for Error {
797
827
#[ allow( deprecated, deprecated_in_future) ]
798
828
fn description ( & self ) -> & str {
799
- match self . repr {
800
- Repr :: Os ( ..) | Repr :: Simple ( ..) => self . kind ( ) . as_str ( ) ,
801
- Repr :: SimpleMessage ( _ , & msg) => msg,
802
- Repr :: Custom ( ref c) => c. error . description ( ) ,
829
+ match self . repr . data ( ) {
830
+ ErrorData :: Os ( ..) | ErrorData :: Simple ( ..) => self . kind ( ) . as_str ( ) ,
831
+ ErrorData :: SimpleMessage ( msg) => msg. message ,
832
+ ErrorData :: Custom ( ref c) => c. error . description ( ) ,
803
833
}
804
834
}
805
835
806
836
#[ allow( deprecated) ]
807
837
fn cause ( & self ) -> Option < & dyn error:: Error > {
808
- match self . repr {
809
- Repr :: Os ( ..) => None ,
810
- Repr :: Simple ( ..) => None ,
811
- Repr :: SimpleMessage ( ..) => None ,
812
- Repr :: Custom ( ref c) => c. error . cause ( ) ,
838
+ match self . repr . data ( ) {
839
+ ErrorData :: Os ( ..) => None ,
840
+ ErrorData :: Simple ( ..) => None ,
841
+ ErrorData :: SimpleMessage ( ..) => None ,
842
+ ErrorData :: Custom ( ref c) => c. error . cause ( ) ,
813
843
}
814
844
}
815
845
816
846
fn source ( & self ) -> Option < & ( dyn error:: Error + ' static ) > {
817
- match self . repr {
818
- Repr :: Os ( ..) => None ,
819
- Repr :: Simple ( ..) => None ,
820
- Repr :: SimpleMessage ( ..) => None ,
821
- Repr :: Custom ( ref c) => c. error . source ( ) ,
847
+ match self . repr . data ( ) {
848
+ ErrorData :: Os ( ..) => None ,
849
+ ErrorData :: Simple ( ..) => None ,
850
+ ErrorData :: SimpleMessage ( ..) => None ,
851
+ ErrorData :: Custom ( ref c) => c. error . source ( ) ,
822
852
}
823
853
}
824
854
}
0 commit comments