@@ -26,6 +26,7 @@ use std::borrow::Cow;
26
26
use std:: cmp:: { max, min, Reverse } ;
27
27
use std:: io;
28
28
use std:: io:: prelude:: * ;
29
+ use std:: iter;
29
30
use std:: path:: Path ;
30
31
use termcolor:: { Ansi , BufferWriter , ColorChoice , ColorSpec , StandardStream } ;
31
32
use termcolor:: { Buffer , Color , WriteColor } ;
@@ -279,20 +280,41 @@ pub trait Emitter {
279
280
level : & Level ,
280
281
backtrace : bool ,
281
282
) {
282
- let mut external_spans_updated = false ;
283
+ // Check for spans in macros, before `fix_multispans_in_extern_macros`
284
+ // has a chance to replace them.
285
+ let has_macro_spans = iter:: once ( & * span)
286
+ . chain ( children. iter ( ) . map ( |child| & child. span ) )
287
+ . flat_map ( |span| span. primary_spans ( ) )
288
+ . copied ( )
289
+ . flat_map ( |sp| {
290
+ sp. macro_backtrace ( ) . filter_map ( |expn_data| {
291
+ match expn_data. kind {
292
+ ExpnKind :: Root => None ,
293
+
294
+ // Skip past non-macro entries, just in case there
295
+ // are some which do actually involve macros.
296
+ ExpnKind :: Desugaring ( ..) | ExpnKind :: AstPass ( ..) => None ,
297
+
298
+ ExpnKind :: Macro ( macro_kind, _) => Some ( macro_kind) ,
299
+ }
300
+ } )
301
+ } )
302
+ . next ( ) ;
303
+
283
304
if !backtrace {
284
- external_spans_updated =
285
- self . fix_multispans_in_extern_macros ( source_map, span, children) ;
305
+ self . fix_multispans_in_extern_macros ( source_map, span, children) ;
286
306
}
287
307
288
308
self . render_multispans_macro_backtrace ( span, children, backtrace) ;
289
309
290
310
if !backtrace {
291
- if external_spans_updated {
311
+ if let Some ( macro_kind ) = has_macro_spans {
292
312
let msg = format ! (
293
- "this {} originates in a macro outside of the current crate \
313
+ "this {} originates in {} {} \
294
314
(in Nightly builds, run with -Z macro-backtrace for more info)",
295
315
level,
316
+ macro_kind. article( ) ,
317
+ macro_kind. descr( ) ,
296
318
) ;
297
319
298
320
children. push ( SubDiagnostic {
@@ -311,9 +333,8 @@ pub trait Emitter {
311
333
children : & mut Vec < SubDiagnostic > ,
312
334
backtrace : bool ,
313
335
) {
314
- self . render_multispan_macro_backtrace ( span, backtrace) ;
315
- for child in children. iter_mut ( ) {
316
- self . render_multispan_macro_backtrace ( & mut child. span , backtrace) ;
336
+ for span in iter:: once ( span) . chain ( children. iter_mut ( ) . map ( |child| & mut child. span ) ) {
337
+ self . render_multispan_macro_backtrace ( span, backtrace) ;
317
338
}
318
339
}
319
340
@@ -386,6 +407,7 @@ pub trait Emitter {
386
407
}
387
408
}
388
409
}
410
+
389
411
for ( label_span, label_text) in new_labels {
390
412
span. push_span_label ( label_span, label_text) ;
391
413
}
@@ -399,12 +421,10 @@ pub trait Emitter {
399
421
source_map : & Option < Lrc < SourceMap > > ,
400
422
span : & mut MultiSpan ,
401
423
children : & mut Vec < SubDiagnostic > ,
402
- ) -> bool {
403
- let mut spans_updated = self . fix_multispan_in_extern_macros ( source_map, span) ;
404
- for child in children. iter_mut ( ) {
405
- spans_updated |= self . fix_multispan_in_extern_macros ( source_map, & mut child. span ) ;
424
+ ) {
425
+ for span in iter:: once ( span) . chain ( children. iter_mut ( ) . map ( |child| & mut child. span ) ) {
426
+ self . fix_multispan_in_extern_macros ( source_map, span) ;
406
427
}
407
- spans_updated
408
428
}
409
429
410
430
// This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
@@ -414,10 +434,10 @@ pub trait Emitter {
414
434
& self ,
415
435
source_map : & Option < Lrc < SourceMap > > ,
416
436
span : & mut MultiSpan ,
417
- ) -> bool {
437
+ ) {
418
438
let sm = match source_map {
419
439
Some ( ref sm) => sm,
420
- None => return false ,
440
+ None => return ,
421
441
} ;
422
442
423
443
// First, find all the spans in <*macros> and point instead at their use site
@@ -438,12 +458,9 @@ pub trait Emitter {
438
458
. collect ( ) ;
439
459
440
460
// After we have them, make sure we replace these 'bad' def sites with their use sites
441
- let spans_updated = !replacements. is_empty ( ) ;
442
461
for ( from, to) in replacements {
443
462
span. replace ( from, to) ;
444
463
}
445
-
446
- spans_updated
447
464
}
448
465
}
449
466
0 commit comments