@@ -25,7 +25,7 @@ use crate::backtrace::Backtrace;
25
25
use crate :: borrow:: Cow ;
26
26
use crate :: cell;
27
27
use crate :: char;
28
- use crate :: fmt:: { self , Debug , Display , Write } ;
28
+ use crate :: fmt:: { self , Debug , Display } ;
29
29
use crate :: mem:: transmute;
30
30
use crate :: num;
31
31
use crate :: str;
@@ -816,6 +816,7 @@ impl dyn Error + Send + Sync {
816
816
///
817
817
/// ```
818
818
/// #![feature(error_reporter)]
819
+ /// #![feature(negative_impls)]
819
820
///
820
821
/// use std::error::{Error, Report};
821
822
/// use std::fmt;
@@ -848,17 +849,48 @@ impl dyn Error + Send + Sync {
848
849
///
849
850
/// impl Error for SuperErrorSideKick {}
850
851
///
852
+ /// // Note that the error doesn't need to be `Send` or `Sync`.
853
+ /// impl !Send for SuperError {}
854
+ /// impl !Sync for SuperError {}
855
+ ///
851
856
/// fn main() {
852
857
/// let error = SuperError { side: SuperErrorSideKick };
853
858
/// let report = Report::new(&error).pretty(true);
854
859
///
855
860
/// println!("{}", report);
856
861
/// }
857
862
/// ```
863
+ ///
864
+ /// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the
865
+ /// wrapped error be `Send`, `Sync`, or `'static`.
866
+ ///
867
+ /// ```rust
868
+ /// # #![feature(error_reporter)]
869
+ /// # use std::fmt;
870
+ /// # use std::error::{Error, Report};
871
+ /// #[derive(Debug)]
872
+ /// struct SuperError<'a> {
873
+ /// side: &'a str,
874
+ /// }
875
+ /// impl<'a> fmt::Display for SuperError<'a> {
876
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
877
+ /// write!(f, "SuperError is here: {}", self.side)
878
+ /// }
879
+ /// }
880
+ /// impl<'a> Error for SuperError<'a> {}
881
+ /// fn main() {
882
+ /// let msg = String::from("Huzzah!");
883
+ /// let report = Report::new(SuperError { side: &msg });
884
+ /// println!("{}", report);
885
+ /// }
886
+ /// ```
858
887
#[ unstable( feature = "error_reporter" , issue = "90172" ) ]
859
888
pub struct Report < E > {
889
+ /// The error being reported.
860
890
error : E ,
891
+ /// Whether a backtrace should be included as part of the report.
861
892
show_backtrace : bool ,
893
+ /// Whether the report should be pretty-printed.
862
894
pretty : bool ,
863
895
}
864
896
@@ -911,33 +943,26 @@ where
911
943
write ! ( f, "\n \n Caused by:" ) ?;
912
944
913
945
let multiple = cause. source ( ) . is_some ( ) ;
914
- let format = if multiple {
915
- Format :: Numbered { ind : 0 }
916
- } else {
917
- Format :: Uniform { indentation : " " }
918
- } ;
919
946
920
- for error in cause. chain ( ) {
947
+ for ( ind , error) in cause. chain ( ) . enumerate ( ) {
921
948
writeln ! ( f) ?;
922
949
923
- let mut indented = Indented { inner : f, needs_indent : true , format } ;
924
-
925
- write ! ( indented, "{}" , error) ?;
950
+ if multiple {
951
+ write ! ( f, "{: >4}: {}" , ind, Indented { source: error } ) ?;
952
+ } else {
953
+ write ! ( f, " {}" , error) ?;
954
+ }
926
955
}
927
956
}
928
957
929
958
if self . show_backtrace {
930
959
let backtrace = error. backtrace ( ) ;
931
960
932
961
if let Some ( backtrace) = backtrace {
933
- let mut backtrace = backtrace. to_string ( ) ;
934
-
935
- write ! ( f, "\n \n " ) ?;
936
- writeln ! ( f, "Stack backtrace:" ) ?;
962
+ let backtrace = backtrace. to_string ( ) ;
937
963
938
- backtrace. truncate ( backtrace. trim_end ( ) . len ( ) ) ;
939
-
940
- write ! ( f, "{}" , backtrace) ?;
964
+ f. write_str ( "\n \n Stack backtrace:\n " ) ?;
965
+ f. write_str ( backtrace. trim_end ( ) ) ?;
941
966
}
942
967
}
943
968
@@ -977,76 +1002,26 @@ where
977
1002
}
978
1003
}
979
1004
980
- /// Encapsulates how error sources are indented and formatted.
981
- struct Indented < ' a , D : ?Sized > {
982
- inner : & ' a mut D ,
983
- needs_indent : bool ,
984
- format : Format ,
985
- }
986
-
987
- /// The possible variants that error sources can be formatted as.
988
- #[ derive( Clone , Copy ) ]
989
- enum Format {
990
- /// Insert uniform indentation before every line.
991
- ///
992
- /// This format takes a static string as input and inserts it after every newline.
993
- Uniform {
994
- /// The string to insert as indentation.
995
- indentation : & ' static str ,
996
- } ,
997
- /// Inserts a number before the first line.
998
- ///
999
- /// This format hard codes the indentation level to match the indentation from
1000
- /// `std::backtrace::Backtrace`.
1001
- Numbered {
1002
- /// The index to insert before the first line of output.
1003
- ind : usize ,
1004
- } ,
1005
+ /// Wrapper type for indenting the inner source.
1006
+ struct Indented < D > {
1007
+ source : D ,
1005
1008
}
1006
1009
1007
- impl < D > Write for Indented < ' _ , D >
1010
+ impl < D > fmt :: Display for Indented < D >
1008
1011
where
1009
- D : Write + ? Sized ,
1012
+ D : fmt :: Display ,
1010
1013
{
1011
- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
1012
- for ( ind, line) in s. split ( '\n' ) . enumerate ( ) {
1013
- if ind > 0 {
1014
- self . inner . write_char ( '\n' ) ?;
1015
- self . needs_indent = true ;
1016
- }
1017
-
1018
- if self . needs_indent {
1019
- if line. is_empty ( ) {
1020
- continue ;
1021
- }
1014
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1015
+ let source = self . source . to_string ( ) ;
1022
1016
1023
- self . format . insert_indentation ( ind, & mut self . inner ) ?;
1024
- self . needs_indent = false ;
1017
+ for ( ind, line) in source. trim ( ) . split ( '\n' ) . filter ( |l| !l. is_empty ( ) ) . enumerate ( ) {
1018
+ if ind > 0 {
1019
+ write ! ( f, "\n {}" , line) ?;
1020
+ } else {
1021
+ write ! ( f, "{}" , line) ?;
1025
1022
}
1026
-
1027
- self . inner . write_fmt ( format_args ! ( "{}" , line) ) ?;
1028
1023
}
1029
1024
1030
1025
Ok ( ( ) )
1031
1026
}
1032
1027
}
1033
-
1034
- impl Format {
1035
- /// Write the specified formatting to the write buffer.
1036
- fn insert_indentation ( & mut self , line : usize , f : & mut dyn Write ) -> fmt:: Result {
1037
- match self {
1038
- Format :: Uniform { indentation } => {
1039
- write ! ( f, "{}" , indentation)
1040
- }
1041
- Format :: Numbered { ind } => {
1042
- if line == 0 {
1043
- write ! ( f, "{: >4}: " , ind) ?;
1044
- * ind += 1 ;
1045
- Ok ( ( ) )
1046
- } else {
1047
- write ! ( f, " " )
1048
- }
1049
- }
1050
- }
1051
- }
1052
- }
0 commit comments