@@ -64,11 +64,11 @@ impl Emitter for EmitterWriter {
6464 }
6565 }
6666
67- if !db. handler . flags . external_macro_backtrace {
68- self . fix_multispans_in_std_macros ( & mut primary_span, & mut children) ;
69- }
67+ self . fix_multispans_in_std_macros ( & mut primary_span,
68+ & mut children,
69+ db. handler . flags . external_macro_backtrace ) ;
70+
7071 self . emit_messages_default ( & db. level ,
71- db. handler . flags . external_macro_backtrace ,
7272 & db. styled_message ( ) ,
7373 & db. code ,
7474 & primary_span,
@@ -726,7 +726,9 @@ impl EmitterWriter {
726726 // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
727727 // <*macros>. Since these locations are often difficult to read, we move these Spans from
728728 // <*macros> to their corresponding use site.
729- fn fix_multispan_in_std_macros ( & mut self , span : & mut MultiSpan ) -> bool {
729+ fn fix_multispan_in_std_macros ( & mut self ,
730+ span : & mut MultiSpan ,
731+ always_backtrace : bool ) -> bool {
730732 let mut spans_updated = false ;
731733
732734 if let Some ( ref cm) = self . cm {
@@ -739,22 +741,45 @@ impl EmitterWriter {
739741 continue ;
740742 }
741743 let call_sp = cm. call_span_if_macro ( * sp) ;
742- if call_sp != * sp {
743- before_after. push ( ( sp . clone ( ) , call_sp) ) ;
744+ if call_sp != * sp && !always_backtrace {
745+ before_after. push ( ( * sp , call_sp) ) ;
744746 }
745- for trace in sp. macro_backtrace ( ) . iter ( ) . rev ( ) {
747+ let backtrace_len = sp. macro_backtrace ( ) . len ( ) ;
748+ for ( i, trace) in sp. macro_backtrace ( ) . iter ( ) . rev ( ) . enumerate ( ) {
746749 // Only show macro locations that are local
747750 // and display them like a span_note
748751 if let Some ( def_site) = trace. def_site_span {
749752 if def_site == DUMMY_SP {
750753 continue ;
751754 }
755+ if always_backtrace {
756+ new_labels. push ( ( def_site,
757+ format ! ( "in this expansion of `{}`{}" ,
758+ trace. macro_decl_name,
759+ if backtrace_len > 2 {
760+ // if backtrace_len == 1 it'll be pointed
761+ // at by "in this macro invocation"
762+ format!( " (#{})" , i + 1 )
763+ } else {
764+ "" . to_string( )
765+ } ) ) ) ;
766+ }
752767 // Check to make sure we're not in any <*macros>
753768 if !cm. span_to_filename ( def_site) . contains ( "macros>" ) &&
754- !trace. macro_decl_name . starts_with ( "#[" ) {
769+ !trace. macro_decl_name . starts_with ( "#[" ) ||
770+ always_backtrace {
755771 new_labels. push ( ( trace. call_site ,
756- "in this macro invocation" . to_string ( ) ) ) ;
757- break ;
772+ format ! ( "in this macro invocation{}" ,
773+ if backtrace_len > 2 && always_backtrace {
774+ // only specify order when the macro
775+ // backtrace is multiple levels deep
776+ format!( " (#{})" , i + 1 )
777+ } else {
778+ "" . to_string( )
779+ } ) ) ) ;
780+ if !always_backtrace {
781+ break ;
782+ }
758783 }
759784 }
760785 }
@@ -766,7 +791,9 @@ impl EmitterWriter {
766791 if sp_label. span == DUMMY_SP {
767792 continue ;
768793 }
769- if cm. span_to_filename ( sp_label. span . clone ( ) ) . contains ( "macros>" ) {
794+ if cm. span_to_filename ( sp_label. span . clone ( ) ) . contains ( "macros>" ) &&
795+ !always_backtrace
796+ {
770797 let v = sp_label. span . macro_backtrace ( ) ;
771798 if let Some ( use_site) = v. last ( ) {
772799 before_after. push ( ( sp_label. span . clone ( ) , use_site. call_site . clone ( ) ) ) ;
@@ -788,18 +815,19 @@ impl EmitterWriter {
788815 // will change the span to point at the use site.
789816 fn fix_multispans_in_std_macros ( & mut self ,
790817 span : & mut MultiSpan ,
791- children : & mut Vec < SubDiagnostic > ) {
792- let mut spans_updated = self . fix_multispan_in_std_macros ( span) ;
818+ children : & mut Vec < SubDiagnostic > ,
819+ backtrace : bool ) {
820+ let mut spans_updated = self . fix_multispan_in_std_macros ( span, backtrace) ;
793821 for child in children. iter_mut ( ) {
794- spans_updated |= self . fix_multispan_in_std_macros ( & mut child. span ) ;
822+ spans_updated |= self . fix_multispan_in_std_macros ( & mut child. span , backtrace ) ;
795823 }
796824 if spans_updated {
797825 children. push ( SubDiagnostic {
798826 level : Level :: Note ,
799827 message : vec ! [
800- ( [ "this error originates in a macro outside of the current crate" ,
801- " (in Nightly builds, run with -Z external-macro-backtrace for more info)" ]
802- . join ( " " ) ,
828+ ( "this error originates in a macro outside of the current crate \
829+ (in Nightly builds, run with -Z external-macro-backtrace \
830+ for more info)" . to_string ( ) ,
803831 Style :: NoStyle ) ,
804832 ] ,
805833 span : MultiSpan :: new ( ) ,
@@ -861,7 +889,7 @@ impl EmitterWriter {
861889 // ("see?", Style::Highlight),
862890 // ];
863891 //
864- // the expected output on a note is (* surround the highlighted text)
892+ // the expected output on a note is (* surround the highlighted text)
865893 //
866894 // = note: highlighted multiline
867895 // string to
@@ -889,7 +917,6 @@ impl EmitterWriter {
889917 msg : & Vec < ( String , Style ) > ,
890918 code : & Option < DiagnosticId > ,
891919 level : & Level ,
892- external_macro_backtrace : bool ,
893920 max_line_num_len : usize ,
894921 is_secondary : bool )
895922 -> io:: Result < ( ) > {
@@ -1087,18 +1114,13 @@ impl EmitterWriter {
10871114 }
10881115 }
10891116
1090- if external_macro_backtrace {
1091- if let Some ( ref primary_span) = msp. primary_span ( ) . as_ref ( ) {
1092- self . render_macro_backtrace_old_school ( primary_span, & mut buffer) ?;
1093- }
1094- }
1095-
10961117 // final step: take our styled buffer, render it, then output it
10971118 emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ) ?;
10981119
10991120 Ok ( ( ) )
11001121
11011122 }
1123+
11021124 fn emit_suggestion_default ( & mut self ,
11031125 suggestion : & CodeSuggestion ,
11041126 level : & Level ,
@@ -1182,9 +1204,9 @@ impl EmitterWriter {
11821204 }
11831205 Ok ( ( ) )
11841206 }
1207+
11851208 fn emit_messages_default ( & mut self ,
11861209 level : & Level ,
1187- external_macro_backtrace : bool ,
11881210 message : & Vec < ( String , Style ) > ,
11891211 code : & Option < DiagnosticId > ,
11901212 span : & MultiSpan ,
@@ -1197,7 +1219,6 @@ impl EmitterWriter {
11971219 message,
11981220 code,
11991221 level,
1200- external_macro_backtrace,
12011222 max_line_num_len,
12021223 false ) {
12031224 Ok ( ( ) ) => {
@@ -1219,7 +1240,6 @@ impl EmitterWriter {
12191240 & child. styled_message ( ) ,
12201241 & None ,
12211242 & child. level ,
1222- external_macro_backtrace,
12231243 max_line_num_len,
12241244 true ) {
12251245 Err ( e) => panic ! ( "failed to emit error: {}" , e) ,
@@ -1248,30 +1268,6 @@ impl EmitterWriter {
12481268 }
12491269 }
12501270 }
1251-
1252- fn render_macro_backtrace_old_school ( & self ,
1253- sp : & Span ,
1254- buffer : & mut StyledBuffer ) -> io:: Result < ( ) > {
1255- if let Some ( ref cm) = self . cm {
1256- for trace in sp. macro_backtrace ( ) . iter ( ) . rev ( ) {
1257- let line_offset = buffer. num_lines ( ) ;
1258-
1259- let mut diag_string =
1260- format ! ( "in this expansion of {}" , trace. macro_decl_name) ;
1261- if let Some ( def_site_span) = trace. def_site_span {
1262- diag_string. push_str (
1263- & format ! ( " (defined in {})" ,
1264- cm. span_to_filename( def_site_span) ) ) ;
1265- }
1266- let snippet = cm. span_to_string ( trace. call_site ) ;
1267- buffer. append ( line_offset, & format ! ( "{} " , snippet) , Style :: NoStyle ) ;
1268- buffer. append ( line_offset, "note" , Style :: Level ( Level :: Note ) ) ;
1269- buffer. append ( line_offset, ": " , Style :: NoStyle ) ;
1270- buffer. append ( line_offset, & diag_string, Style :: OldSchoolNoteText ) ;
1271- }
1272- }
1273- Ok ( ( ) )
1274- }
12751271}
12761272
12771273fn draw_col_separator ( buffer : & mut StyledBuffer , line : usize , col : usize ) {
0 commit comments