@@ -280,72 +280,72 @@ pub trait Emitter {
280
280
}
281
281
}
282
282
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 (
287
284
& self ,
288
285
source_map : & Option < Lrc < SourceMap > > ,
289
286
span : & mut MultiSpan ,
290
287
children : & mut Vec < SubDiagnostic > ,
291
288
level : & Level ,
292
289
backtrace : bool ,
293
290
) {
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
+ }
298
314
}
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
+ }
310
316
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) ;
318
327
}
319
328
}
320
329
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 (
325
331
& self ,
326
332
source_map : & Option < Lrc < SourceMap > > ,
327
333
span : & mut MultiSpan ,
328
334
always_backtrace : bool ,
329
- ) -> bool {
335
+ ) {
330
336
let sm = match source_map {
331
337
Some ( ref sm) => sm,
332
- None => return false ,
338
+ None => return ,
333
339
} ;
334
340
335
- let mut before_after: Vec < ( Span , Span ) > = vec ! [ ] ;
336
341
let mut new_labels: Vec < ( Span , String ) > = vec ! [ ] ;
337
342
338
343
// 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 ( ) {
340
345
if sp. is_dummy ( ) {
341
346
continue ;
342
347
}
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
- }
347
348
let macro_backtrace: Vec < _ > = sp. macro_backtrace ( ) . collect ( ) ;
348
- let backtrace_len = macro_backtrace. len ( ) ;
349
349
for ( i, trace) in macro_backtrace. iter ( ) . rev ( ) . enumerate ( ) {
350
350
// Only show macro locations that are local
351
351
// and display them like a span_note
@@ -358,13 +358,13 @@ pub trait Emitter {
358
358
format ! (
359
359
"in this expansion of `{}`{}" ,
360
360
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"
364
364
format!( " (#{})" , i + 1 )
365
365
} else {
366
366
String :: new( )
367
- }
367
+ } ,
368
368
) ,
369
369
) ) ;
370
370
}
@@ -377,13 +377,13 @@ pub trait Emitter {
377
377
trace. call_site ,
378
378
format ! (
379
379
"in this macro invocation{}" ,
380
- if backtrace_len > 2 && always_backtrace {
380
+ if macro_backtrace . len ( ) > 2 && always_backtrace {
381
381
// only specify order when the macro
382
382
// backtrace is multiple levels deep
383
383
format!( " (#{})" , i + 1 )
384
384
} else {
385
385
String :: new( )
386
- }
386
+ } ,
387
387
) ,
388
388
) ) ;
389
389
if !always_backtrace {
@@ -395,20 +395,58 @@ pub trait Emitter {
395
395
for ( label_span, label_text) in new_labels {
396
396
span. push_span_label ( label_span, label_text) ;
397
397
}
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 ) ;
407
412
}
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
+
408
446
// 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 ) ;
412
450
}
413
451
414
452
spans_updated
@@ -424,7 +462,7 @@ impl Emitter for EmitterWriter {
424
462
let mut children = diag. children . clone ( ) ;
425
463
let ( mut primary_span, suggestions) = self . primary_span_formatted ( & diag) ;
426
464
427
- self . fix_multispans_in_std_macros (
465
+ self . render_multispans_macro_backtrace_and_fix_extern_macros (
428
466
& self . sm ,
429
467
& mut primary_span,
430
468
& mut children,
0 commit comments