@@ -247,14 +247,142 @@ pub trait Emitter {
247
247
( primary_span, & db. suggestions )
248
248
}
249
249
}
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
+ }
250
377
}
251
378
252
379
impl Emitter for EmitterWriter {
253
380
fn emit_diagnostic ( & mut self , db : & DiagnosticBuilder < ' _ > ) {
254
381
let mut children = db. children . clone ( ) ;
255
382
let ( mut primary_span, suggestions) = self . primary_span_formatted ( & db) ;
256
383
257
- self . fix_multispans_in_std_macros ( & mut primary_span,
384
+ self . fix_multispans_in_std_macros ( & self . sm ,
385
+ & mut primary_span,
258
386
& mut children,
259
387
& db. level ,
260
388
db. handler . flags . external_macro_backtrace ) ;
@@ -919,127 +1047,6 @@ impl EmitterWriter {
919
1047
max
920
1048
}
921
1049
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
-
1043
1050
/// Adds a left margin to every line but the first, given a padding length and the label being
1044
1051
/// displayed, keeping the provided highlighting.
1045
1052
fn msg_to_buffer ( & self ,
0 commit comments