@@ -247,14 +247,142 @@ pub trait Emitter {
247247 ( primary_span, & db. suggestions )
248248 }
249249 }
250+
251+ // This does a small "fix" for multispans by looking to see if it can find any that
252+ // point directly at <*macros>. Since these are often difficult to read, this
253+ // will change the span to point at the use site.
254+ fn fix_multispans_in_std_macros ( & self ,
255+ source_map : & Option < Lrc < SourceMapperDyn > > ,
256+ span : & mut MultiSpan ,
257+ children : & mut Vec < SubDiagnostic > ,
258+ level : & Level ,
259+ backtrace : bool ) {
260+ let mut spans_updated = self . fix_multispan_in_std_macros ( source_map, span, backtrace) ;
261+ for child in children. iter_mut ( ) {
262+ spans_updated |= self . fix_multispan_in_std_macros (
263+ source_map,
264+ & mut child. span ,
265+ backtrace
266+ ) ;
267+ }
268+ let msg = if level == & Error {
269+ "this error originates in a macro outside of the current crate \
270+ (in Nightly builds, run with -Z external-macro-backtrace \
271+ for more info)". to_string ( )
272+ } else {
273+ "this warning originates in a macro outside of the current crate \
274+ (in Nightly builds, run with -Z external-macro-backtrace \
275+ for more info)". to_string ( )
276+ } ;
277+
278+ if spans_updated {
279+ children. push ( SubDiagnostic {
280+ level : Level :: Note ,
281+ message : vec ! [
282+ ( msg,
283+ Style :: NoStyle ) ,
284+ ] ,
285+ span : MultiSpan :: new ( ) ,
286+ render_span : None ,
287+ } ) ;
288+ }
289+ }
290+
291+ // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
292+ // <*macros>. Since these locations are often difficult to read, we move these Spans from
293+ // <*macros> to their corresponding use site.
294+ fn fix_multispan_in_std_macros ( & self ,
295+ source_map : & Option < Lrc < SourceMapperDyn > > ,
296+ span : & mut MultiSpan ,
297+ always_backtrace : bool ) -> bool {
298+ let mut spans_updated = false ;
299+
300+ if let Some ( ref sm) = source_map {
301+ let mut before_after: Vec < ( Span , Span ) > = vec ! [ ] ;
302+ let mut new_labels: Vec < ( Span , String ) > = vec ! [ ] ;
303+
304+ // First, find all the spans in <*macros> and point instead at their use site
305+ for sp in span. primary_spans ( ) {
306+ if sp. is_dummy ( ) {
307+ continue ;
308+ }
309+ let call_sp = sm. call_span_if_macro ( * sp) ;
310+ if call_sp != * sp && !always_backtrace {
311+ before_after. push ( ( * sp, call_sp) ) ;
312+ }
313+ let backtrace_len = sp. macro_backtrace ( ) . len ( ) ;
314+ for ( i, trace) in sp. macro_backtrace ( ) . iter ( ) . rev ( ) . enumerate ( ) {
315+ // Only show macro locations that are local
316+ // and display them like a span_note
317+ if trace. def_site_span . is_dummy ( ) {
318+ continue ;
319+ }
320+ if always_backtrace {
321+ new_labels. push ( ( trace. def_site_span ,
322+ format ! ( "in this expansion of `{}`{}" ,
323+ trace. macro_decl_name,
324+ if backtrace_len > 2 {
325+ // if backtrace_len == 1 it'll be pointed
326+ // at by "in this macro invocation"
327+ format!( " (#{})" , i + 1 )
328+ } else {
329+ String :: new( )
330+ } ) ) ) ;
331+ }
332+ // Check to make sure we're not in any <*macros>
333+ if !sm. span_to_filename ( trace. def_site_span ) . is_macros ( ) &&
334+ !trace. macro_decl_name . starts_with ( "desugaring of " ) &&
335+ !trace. macro_decl_name . starts_with ( "#[" ) ||
336+ always_backtrace {
337+ new_labels. push ( ( trace. call_site ,
338+ format ! ( "in this macro invocation{}" ,
339+ if backtrace_len > 2 && always_backtrace {
340+ // only specify order when the macro
341+ // backtrace is multiple levels deep
342+ format!( " (#{})" , i + 1 )
343+ } else {
344+ String :: new( )
345+ } ) ) ) ;
346+ if !always_backtrace {
347+ break ;
348+ }
349+ }
350+ }
351+ }
352+ for ( label_span, label_text) in new_labels {
353+ span. push_span_label ( label_span, label_text) ;
354+ }
355+ for sp_label in span. span_labels ( ) {
356+ if sp_label. span . is_dummy ( ) {
357+ continue ;
358+ }
359+ if sm. span_to_filename ( sp_label. span . clone ( ) ) . is_macros ( ) &&
360+ !always_backtrace
361+ {
362+ let v = sp_label. span . macro_backtrace ( ) ;
363+ if let Some ( use_site) = v. last ( ) {
364+ before_after. push ( ( sp_label. span . clone ( ) , use_site. call_site . clone ( ) ) ) ;
365+ }
366+ }
367+ }
368+ // After we have them, make sure we replace these 'bad' def sites with their use sites
369+ for ( before, after) in before_after {
370+ span. replace ( before, after) ;
371+ spans_updated = true ;
372+ }
373+ }
374+
375+ spans_updated
376+ }
250377}
251378
252379impl Emitter for EmitterWriter {
253380 fn emit_diagnostic ( & mut self , db : & DiagnosticBuilder < ' _ > ) {
254381 let mut children = db. children . clone ( ) ;
255382 let ( mut primary_span, suggestions) = self . primary_span_formatted ( & db) ;
256383
257- self . fix_multispans_in_std_macros ( & mut primary_span,
384+ self . fix_multispans_in_std_macros ( & self . sm ,
385+ & mut primary_span,
258386 & mut children,
259387 & db. level ,
260388 db. handler . flags . external_macro_backtrace ) ;
@@ -919,127 +1047,6 @@ impl EmitterWriter {
9191047 max
9201048 }
9211049
922- // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
923- // <*macros>. Since these locations are often difficult to read, we move these Spans from
924- // <*macros> to their corresponding use site.
925- fn fix_multispan_in_std_macros ( & mut self ,
926- span : & mut MultiSpan ,
927- always_backtrace : bool ) -> bool {
928- let mut spans_updated = false ;
929-
930- if let Some ( ref sm) = self . sm {
931- let mut before_after: Vec < ( Span , Span ) > = vec ! [ ] ;
932- let mut new_labels: Vec < ( Span , String ) > = vec ! [ ] ;
933-
934- // First, find all the spans in <*macros> and point instead at their use site
935- for sp in span. primary_spans ( ) {
936- if sp. is_dummy ( ) {
937- continue ;
938- }
939- let call_sp = sm. call_span_if_macro ( * sp) ;
940- if call_sp != * sp && !always_backtrace {
941- before_after. push ( ( * sp, call_sp) ) ;
942- }
943- let backtrace_len = sp. macro_backtrace ( ) . len ( ) ;
944- for ( i, trace) in sp. macro_backtrace ( ) . iter ( ) . rev ( ) . enumerate ( ) {
945- // Only show macro locations that are local
946- // and display them like a span_note
947- if trace. def_site_span . is_dummy ( ) {
948- continue ;
949- }
950- if always_backtrace {
951- new_labels. push ( ( trace. def_site_span ,
952- format ! ( "in this expansion of `{}`{}" ,
953- trace. macro_decl_name,
954- if backtrace_len > 2 {
955- // if backtrace_len == 1 it'll be pointed
956- // at by "in this macro invocation"
957- format!( " (#{})" , i + 1 )
958- } else {
959- String :: new( )
960- } ) ) ) ;
961- }
962- // Check to make sure we're not in any <*macros>
963- if !sm. span_to_filename ( trace. def_site_span ) . is_macros ( ) &&
964- !trace. macro_decl_name . starts_with ( "desugaring of " ) &&
965- !trace. macro_decl_name . starts_with ( "#[" ) ||
966- always_backtrace {
967- new_labels. push ( ( trace. call_site ,
968- format ! ( "in this macro invocation{}" ,
969- if backtrace_len > 2 && always_backtrace {
970- // only specify order when the macro
971- // backtrace is multiple levels deep
972- format!( " (#{})" , i + 1 )
973- } else {
974- String :: new( )
975- } ) ) ) ;
976- if !always_backtrace {
977- break ;
978- }
979- }
980- }
981- }
982- for ( label_span, label_text) in new_labels {
983- span. push_span_label ( label_span, label_text) ;
984- }
985- for sp_label in span. span_labels ( ) {
986- if sp_label. span . is_dummy ( ) {
987- continue ;
988- }
989- if sm. span_to_filename ( sp_label. span . clone ( ) ) . is_macros ( ) &&
990- !always_backtrace
991- {
992- let v = sp_label. span . macro_backtrace ( ) ;
993- if let Some ( use_site) = v. last ( ) {
994- before_after. push ( ( sp_label. span . clone ( ) , use_site. call_site . clone ( ) ) ) ;
995- }
996- }
997- }
998- // After we have them, make sure we replace these 'bad' def sites with their use sites
999- for ( before, after) in before_after {
1000- span. replace ( before, after) ;
1001- spans_updated = true ;
1002- }
1003- }
1004-
1005- spans_updated
1006- }
1007-
1008- // This does a small "fix" for multispans by looking to see if it can find any that
1009- // point directly at <*macros>. Since these are often difficult to read, this
1010- // will change the span to point at the use site.
1011- fn fix_multispans_in_std_macros ( & mut self ,
1012- span : & mut MultiSpan ,
1013- children : & mut Vec < SubDiagnostic > ,
1014- level : & Level ,
1015- backtrace : bool ) {
1016- let mut spans_updated = self . fix_multispan_in_std_macros ( span, backtrace) ;
1017- for child in children. iter_mut ( ) {
1018- spans_updated |= self . fix_multispan_in_std_macros ( & mut child. span , backtrace) ;
1019- }
1020- let msg = if level == & Error {
1021- "this error originates in a macro outside of the current crate \
1022- (in Nightly builds, run with -Z external-macro-backtrace \
1023- for more info)". to_string ( )
1024- } else {
1025- "this warning originates in a macro outside of the current crate \
1026- (in Nightly builds, run with -Z external-macro-backtrace \
1027- for more info)". to_string ( )
1028- } ;
1029-
1030- if spans_updated {
1031- children. push ( SubDiagnostic {
1032- level : Level :: Note ,
1033- message : vec ! [
1034- ( msg,
1035- Style :: NoStyle ) ,
1036- ] ,
1037- span : MultiSpan :: new ( ) ,
1038- render_span : None ,
1039- } ) ;
1040- }
1041- }
1042-
10431050 /// Adds a left margin to every line but the first, given a padding length and the label being
10441051 /// displayed, keeping the provided highlighting.
10451052 fn msg_to_buffer ( & self ,
0 commit comments