@@ -21,7 +21,7 @@ use rustc_error_messages::FluentArgs;
2121use rustc_lint_defs:: Applicability ;
2222use rustc_span:: Span ;
2323use rustc_span:: hygiene:: ExpnData ;
24- use rustc_span:: source_map:: SourceMap ;
24+ use rustc_span:: source_map:: { FilePathMapping , SourceMap } ;
2525use serde:: Serialize ;
2626use termcolor:: { ColorSpec , WriteColor } ;
2727
@@ -45,7 +45,7 @@ pub struct JsonEmitter {
4545 #[ setters( skip) ]
4646 dst : IntoDynSyncSend < Box < dyn Write + Send > > ,
4747 #[ setters( skip) ]
48- sm : Lrc < SourceMap > ,
48+ sm : Option < Lrc < SourceMap > > ,
4949 fluent_bundle : Option < Lrc < FluentBundle > > ,
5050 #[ setters( skip) ]
5151 fallback_bundle : LazyFallbackBundle ,
@@ -65,7 +65,7 @@ pub struct JsonEmitter {
6565impl JsonEmitter {
6666 pub fn new (
6767 dst : Box < dyn Write + Send > ,
68- sm : Lrc < SourceMap > ,
68+ sm : Option < Lrc < SourceMap > > ,
6969 fallback_bundle : LazyFallbackBundle ,
7070 pretty : bool ,
7171 json_rendered : HumanReadableErrorType ,
@@ -171,7 +171,7 @@ impl Emitter for JsonEmitter {
171171 }
172172
173173 fn source_map ( & self ) -> Option < & SourceMap > {
174- Some ( & self . sm )
174+ self . sm . as_deref ( )
175175 }
176176
177177 fn should_show_explain ( & self ) -> bool {
@@ -371,7 +371,7 @@ impl Diagnostic {
371371 }
372372 HumanEmitter :: new ( dst, Lrc :: clone ( & je. fallback_bundle ) )
373373 . short_message ( short)
374- . sm ( Some ( Lrc :: clone ( & je. sm ) ) )
374+ . sm ( je. sm . clone ( ) )
375375 . fluent_bundle ( je. fluent_bundle . clone ( ) )
376376 . diagnostic_width ( je. diagnostic_width )
377377 . macro_backtrace ( je. macro_backtrace )
@@ -458,23 +458,34 @@ impl DiagnosticSpan {
458458 mut backtrace : impl Iterator < Item = ExpnData > ,
459459 je : & JsonEmitter ,
460460 ) -> DiagnosticSpan {
461- let start = je. sm . lookup_char_pos ( span. lo ( ) ) ;
461+ let empty_source_map;
462+ let sm = match & je. sm {
463+ Some ( s) => s,
464+ None => {
465+ span = rustc_span:: DUMMY_SP ;
466+ empty_source_map = Arc :: new ( SourceMap :: new ( FilePathMapping :: empty ( ) ) ) ;
467+ empty_source_map
468+ . new_source_file ( std:: path:: PathBuf :: from ( "empty.rs" ) . into ( ) , String :: new ( ) ) ;
469+ & empty_source_map
470+ }
471+ } ;
472+ let start = sm. lookup_char_pos ( span. lo ( ) ) ;
462473 // If this goes from the start of a line to the end and the replacement
463474 // is an empty string, increase the length to include the newline so we don't
464475 // leave an empty line
465476 if start. col . 0 == 0
466477 && let Some ( ( suggestion, _) ) = suggestion
467478 && suggestion. is_empty ( )
468- && let Ok ( after) = je . sm . span_to_next_source ( span)
479+ && let Ok ( after) = sm. span_to_next_source ( span)
469480 && after. starts_with ( '\n' )
470481 {
471482 span = span. with_hi ( span. hi ( ) + rustc_span:: BytePos ( 1 ) ) ;
472483 }
473- let end = je . sm . lookup_char_pos ( span. hi ( ) ) ;
484+ let end = sm. lookup_char_pos ( span. hi ( ) ) ;
474485 let backtrace_step = backtrace. next ( ) . map ( |bt| {
475486 let call_site = Self :: from_span_full ( bt. call_site , false , None , None , backtrace, je) ;
476487 let def_site_span = Self :: from_span_full (
477- je . sm . guess_head_span ( bt. def_site ) ,
488+ sm. guess_head_span ( bt. def_site ) ,
478489 false ,
479490 None ,
480491 None ,
@@ -489,7 +500,7 @@ impl DiagnosticSpan {
489500 } ) ;
490501
491502 DiagnosticSpan {
492- file_name : je . sm . filename_for_diagnostics ( & start. file . name ) . to_string ( ) ,
503+ file_name : sm. filename_for_diagnostics ( & start. file . name ) . to_string ( ) ,
493504 byte_start : start. file . original_relative_byte_pos ( span. lo ( ) ) . 0 ,
494505 byte_end : start. file . original_relative_byte_pos ( span. hi ( ) ) . 0 ,
495506 line_start : start. line ,
@@ -559,19 +570,20 @@ impl DiagnosticSpanLine {
559570 /// `span` within the line.
560571 fn from_span ( span : Span , je : & JsonEmitter ) -> Vec < DiagnosticSpanLine > {
561572 je. sm
562- . span_to_lines ( span)
563- . map ( |lines| {
573+ . as_ref ( )
574+ . and_then ( |sm| {
575+ let lines = sm. span_to_lines ( span) . ok ( ) ?;
564576 // We can't get any lines if the source is unavailable.
565577 if !should_show_source_code (
566578 & je. ignored_directories_in_source_blocks ,
567- & je . sm ,
579+ & sm,
568580 & lines. file ,
569581 ) {
570- return vec ! [ ] ;
582+ return None ;
571583 }
572584
573585 let sf = & * lines. file ;
574- lines
586+ let span_lines = lines
575587 . lines
576588 . iter ( )
577589 . map ( |line| {
@@ -582,8 +594,9 @@ impl DiagnosticSpanLine {
582594 line. end_col . 0 + 1 ,
583595 )
584596 } )
585- . collect ( )
597+ . collect ( ) ;
598+ Some ( span_lines)
586599 } )
587- . unwrap_or_else ( |_| vec ! [ ] )
600+ . unwrap_or_default ( )
588601 }
589602}
0 commit comments