@@ -280,72 +280,72 @@ pub trait Emitter {
280280 }
281281 }
282282
283- // This does a small "fix" for multispans by looking to see if it can find any that
284- // point directly at <*macros>. Since these are often difficult to read, this
285- // will change the span to point at the use site.
286- fn fix_multispans_in_std_macros (
283+ fn render_multispans_macro_backtrace_and_fix_extern_macros (
287284 & self ,
288285 source_map : & Option < Lrc < SourceMap > > ,
289286 span : & mut MultiSpan ,
290287 children : & mut Vec < SubDiagnostic > ,
291288 level : & Level ,
292289 backtrace : bool ,
293290 ) {
294- let mut spans_updated = self . fix_multispan_in_std_macros ( source_map, span, backtrace) ;
295- for child in children. iter_mut ( ) {
296- spans_updated |=
297- self . fix_multispan_in_std_macros ( source_map, & mut child. span , backtrace) ;
291+ self . render_multispans_macro_backtrace ( source_map, span, children, backtrace) ;
292+
293+ if !backtrace {
294+ if self . fix_multispans_in_extern_macros ( source_map, span, children) {
295+ let msg = if level == & Error {
296+ "this error originates in a macro outside of the current crate \
297+ (in Nightly builds, run with -Z external-macro-backtrace \
298+ for more info)"
299+ . to_string ( )
300+ } else {
301+ "this warning originates in a macro outside of the current crate \
302+ (in Nightly builds, run with -Z external-macro-backtrace \
303+ for more info)"
304+ . to_string ( )
305+ } ;
306+
307+ children. push ( SubDiagnostic {
308+ level : Level :: Note ,
309+ message : vec ! [ ( msg, Style :: NoStyle ) ] ,
310+ span : MultiSpan :: new ( ) ,
311+ render_span : None ,
312+ } ) ;
313+ }
298314 }
299- let msg = if level == & Error {
300- "this error originates in a macro outside of the current crate \
301- (in Nightly builds, run with -Z external-macro-backtrace \
302- for more info)"
303- . to_string ( )
304- } else {
305- "this warning originates in a macro outside of the current crate \
306- (in Nightly builds, run with -Z external-macro-backtrace \
307- for more info)"
308- . to_string ( )
309- } ;
315+ }
310316
311- if spans_updated {
312- children. push ( SubDiagnostic {
313- level : Level :: Note ,
314- message : vec ! [ ( msg, Style :: NoStyle ) ] ,
315- span : MultiSpan :: new ( ) ,
316- render_span : None ,
317- } ) ;
317+ fn render_multispans_macro_backtrace (
318+ & self ,
319+ source_map : & Option < Lrc < SourceMap > > ,
320+ span : & mut MultiSpan ,
321+ children : & mut Vec < SubDiagnostic > ,
322+ backtrace : bool ,
323+ ) {
324+ self . render_multispan_macro_backtrace ( source_map, span, backtrace) ;
325+ for child in children. iter_mut ( ) {
326+ self . render_multispan_macro_backtrace ( source_map, & mut child. span , backtrace) ;
318327 }
319328 }
320329
321- // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
322- // <*macros>. Since these locations are often difficult to read, we move these Spans from
323- // <*macros> to their corresponding use site.
324- fn fix_multispan_in_std_macros (
330+ fn render_multispan_macro_backtrace (
325331 & self ,
326332 source_map : & Option < Lrc < SourceMap > > ,
327333 span : & mut MultiSpan ,
328334 always_backtrace : bool ,
329- ) -> bool {
335+ ) {
330336 let sm = match source_map {
331337 Some ( ref sm) => sm,
332- None => return false ,
338+ None => return ,
333339 } ;
334340
335- let mut before_after: Vec < ( Span , Span ) > = vec ! [ ] ;
336341 let mut new_labels: Vec < ( Span , String ) > = vec ! [ ] ;
337342
338343 // First, find all the spans in <*macros> and point instead at their use site
339- for sp in span. primary_spans ( ) {
344+ for & sp in span. primary_spans ( ) {
340345 if sp. is_dummy ( ) {
341346 continue ;
342347 }
343- let call_sp = sm. call_span_if_macro ( * sp) ;
344- if call_sp != * sp && !always_backtrace {
345- before_after. push ( ( * sp, call_sp) ) ;
346- }
347348 let macro_backtrace: Vec < _ > = sp. macro_backtrace ( ) . collect ( ) ;
348- let backtrace_len = macro_backtrace. len ( ) ;
349349 for ( i, trace) in macro_backtrace. iter ( ) . rev ( ) . enumerate ( ) {
350350 // Only show macro locations that are local
351351 // and display them like a span_note
@@ -358,13 +358,13 @@ pub trait Emitter {
358358 format ! (
359359 "in this expansion of `{}`{}" ,
360360 trace. kind. descr( ) ,
361- if backtrace_len > 2 {
362- // if backtrace_len == 1 it'll be pointed
363- // at by "in this macro invocation"
361+ if macro_backtrace . len ( ) > 2 {
362+ // if macro_backtrace.len() == 1 it'll be
363+ // pointed at by "in this macro invocation"
364364 format!( " (#{})" , i + 1 )
365365 } else {
366366 String :: new( )
367- }
367+ } ,
368368 ) ,
369369 ) ) ;
370370 }
@@ -377,13 +377,13 @@ pub trait Emitter {
377377 trace. call_site ,
378378 format ! (
379379 "in this macro invocation{}" ,
380- if backtrace_len > 2 && always_backtrace {
380+ if macro_backtrace . len ( ) > 2 && always_backtrace {
381381 // only specify order when the macro
382382 // backtrace is multiple levels deep
383383 format!( " (#{})" , i + 1 )
384384 } else {
385385 String :: new( )
386- }
386+ } ,
387387 ) ,
388388 ) ) ;
389389 if !always_backtrace {
@@ -395,20 +395,58 @@ pub trait Emitter {
395395 for ( label_span, label_text) in new_labels {
396396 span. push_span_label ( label_span, label_text) ;
397397 }
398- for sp_label in span. span_labels ( ) {
399- if sp_label. span . is_dummy ( ) {
400- continue ;
401- }
402- if sm. span_to_filename ( sp_label. span . clone ( ) ) . is_macros ( ) && !always_backtrace {
403- if let Some ( use_site) = sp_label. span . macro_backtrace ( ) . last ( ) {
404- before_after. push ( ( sp_label. span , use_site. call_site ) ) ;
405- }
406- }
398+ }
399+
400+ // This does a small "fix" for multispans by looking to see if it can find any that
401+ // point directly at <*macros>. Since these are often difficult to read, this
402+ // will change the span to point at the use site.
403+ fn fix_multispans_in_extern_macros (
404+ & self ,
405+ source_map : & Option < Lrc < SourceMap > > ,
406+ span : & mut MultiSpan ,
407+ children : & mut Vec < SubDiagnostic > ,
408+ ) -> bool {
409+ let mut spans_updated = self . fix_multispan_in_extern_macros ( source_map, span) ;
410+ for child in children. iter_mut ( ) {
411+ spans_updated |= self . fix_multispan_in_extern_macros ( source_map, & mut child. span ) ;
407412 }
413+ spans_updated
414+ }
415+
416+ // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
417+ // <*macros>. Since these locations are often difficult to read, we move these Spans from
418+ // <*macros> to their corresponding use site.
419+ fn fix_multispan_in_extern_macros (
420+ & self ,
421+ source_map : & Option < Lrc < SourceMap > > ,
422+ span : & mut MultiSpan ,
423+ ) -> bool {
424+ let sm = match source_map {
425+ Some ( ref sm) => sm,
426+ None => return false ,
427+ } ;
428+
429+ // First, find all the spans in <*macros> and point instead at their use site
430+ let replacements: Vec < ( Span , Span ) > = span
431+ . primary_spans ( )
432+ . iter ( )
433+ . copied ( )
434+ . chain ( span. span_labels ( ) . iter ( ) . map ( |sp_label| sp_label. span ) )
435+ . filter_map ( |sp| {
436+ if !sp. is_dummy ( ) && sm. span_to_filename ( sp) . is_macros ( ) {
437+ let maybe_callsite = sp. source_callsite ( ) ;
438+ if sp != maybe_callsite {
439+ return Some ( ( sp, maybe_callsite) ) ;
440+ }
441+ }
442+ None
443+ } )
444+ . collect ( ) ;
445+
408446 // After we have them, make sure we replace these 'bad' def sites with their use sites
409- let spans_updated = !before_after . is_empty ( ) ;
410- for ( before , after ) in before_after {
411- span. replace ( before , after ) ;
447+ let spans_updated = !replacements . is_empty ( ) ;
448+ for ( from , to ) in replacements {
449+ span. replace ( from , to ) ;
412450 }
413451
414452 spans_updated
@@ -424,7 +462,7 @@ impl Emitter for EmitterWriter {
424462 let mut children = diag. children . clone ( ) ;
425463 let ( mut primary_span, suggestions) = self . primary_span_formatted ( & diag) ;
426464
427- self . fix_multispans_in_std_macros (
465+ self . render_multispans_macro_backtrace_and_fix_extern_macros (
428466 & self . sm ,
429467 & mut primary_span,
430468 & mut children,
0 commit comments