11#[ cfg( test) ]
22mod tests;
33
4+ mod repr_unpacked;
5+ use repr_unpacked:: Repr ;
6+
47use crate :: convert:: From ;
58use crate :: error;
69use crate :: fmt;
@@ -66,15 +69,38 @@ impl fmt::Debug for Error {
6669 }
6770}
6871
69- enum Repr {
72+ enum ErrorData < C > {
7073 Os ( i32 ) ,
7174 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+ } )
75100}
76101
77102#[ derive( Debug ) ]
103+ #[ repr( align( 4 ) ) ]
78104struct Custom {
79105 kind : ErrorKind ,
80106 error : Box < dyn error:: Error + Send + Sync > ,
@@ -396,7 +422,7 @@ impl From<ErrorKind> for Error {
396422 /// ```
397423 #[ inline]
398424 fn from ( kind : ErrorKind ) -> Error {
399- Error { repr : Repr :: Simple ( kind) }
425+ Error { repr : Repr :: new_simple ( kind) }
400426 }
401427}
402428
@@ -461,20 +487,22 @@ impl Error {
461487 }
462488
463489 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 } ) ) }
465491 }
466492
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.
469495 ///
470496 /// This function does not allocate.
471497 ///
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.
475503 #[ 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 ) }
478506 }
479507
480508 /// Returns an error representing the last OS error which occurred.
@@ -532,7 +560,7 @@ impl Error {
532560 #[ must_use]
533561 #[ inline]
534562 pub fn from_raw_os_error ( code : i32 ) -> Error {
535- Error { repr : Repr :: Os ( code) }
563+ Error { repr : Repr :: new_os ( code) }
536564 }
537565
538566 /// Returns the OS error that this error represents (if any).
@@ -568,11 +596,11 @@ impl Error {
568596 #[ must_use]
569597 #[ inline]
570598 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 ,
576604 }
577605 }
578606
@@ -607,11 +635,11 @@ impl Error {
607635 #[ must_use]
608636 #[ inline]
609637 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 ) ,
615643 }
616644 }
617645
@@ -681,11 +709,11 @@ impl Error {
681709 #[ must_use]
682710 #[ inline]
683711 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 ) ,
689717 }
690718 }
691719
@@ -720,11 +748,11 @@ impl Error {
720748 #[ must_use = "`self` will be dropped if the result is not used" ]
721749 #[ inline]
722750 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 ) ,
728756 }
729757 }
730758
@@ -750,44 +778,46 @@ impl Error {
750778 #[ must_use]
751779 #[ inline]
752780 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 ,
758786 }
759787 }
760788}
761789
762790impl fmt:: Debug for Repr {
763791 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
766794 . debug_struct ( "Os" )
767795 . field ( "code" , & code)
768796 . field ( "kind" , & sys:: decode_error_kind ( code) )
769797 . field ( "message" , & sys:: os:: error_string ( code) )
770798 . 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 ( ) ,
776806 }
777807 }
778808}
779809
780810#[ stable( feature = "rust1" , since = "1.0.0" ) ]
781811impl fmt:: Display for Error {
782812 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) => {
785815 let detail = sys:: os:: error_string ( code) ;
786816 write ! ( fmt, "{} (os error {})" , detail, code)
787817 }
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) ,
791821 }
792822 }
793823}
@@ -796,29 +826,29 @@ impl fmt::Display for Error {
796826impl error:: Error for Error {
797827 #[ allow( deprecated, deprecated_in_future) ]
798828 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 ( ) ,
803833 }
804834 }
805835
806836 #[ allow( deprecated) ]
807837 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 ( ) ,
813843 }
814844 }
815845
816846 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 ( ) ,
822852 }
823853 }
824854}
0 commit comments