@@ -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,22 +458,33 @@ 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 && suggestion. map_or ( false , |( s, _) | s. is_empty ( ) )
467- && let Ok ( after) = je . sm . span_to_next_source ( span)
478+ && let Ok ( after) = sm. span_to_next_source ( span)
468479 && after. starts_with ( '\n' )
469480 {
470481 span = span. with_hi ( span. hi ( ) + rustc_span:: BytePos ( 1 ) ) ;
471482 }
472- let end = je . sm . lookup_char_pos ( span. hi ( ) ) ;
483+ let end = sm. lookup_char_pos ( span. hi ( ) ) ;
473484 let backtrace_step = backtrace. next ( ) . map ( |bt| {
474485 let call_site = Self :: from_span_full ( bt. call_site , false , None , None , backtrace, je) ;
475486 let def_site_span = Self :: from_span_full (
476- je . sm . guess_head_span ( bt. def_site ) ,
487+ sm. guess_head_span ( bt. def_site ) ,
477488 false ,
478489 None ,
479490 None ,
@@ -488,7 +499,7 @@ impl DiagnosticSpan {
488499 } ) ;
489500
490501 DiagnosticSpan {
491- file_name : je . sm . filename_for_diagnostics ( & start. file . name ) . to_string ( ) ,
502+ file_name : sm. filename_for_diagnostics ( & start. file . name ) . to_string ( ) ,
492503 byte_start : start. file . original_relative_byte_pos ( span. lo ( ) ) . 0 ,
493504 byte_end : start. file . original_relative_byte_pos ( span. hi ( ) ) . 0 ,
494505 line_start : start. line ,
@@ -558,19 +569,20 @@ impl DiagnosticSpanLine {
558569 /// `span` within the line.
559570 fn from_span ( span : Span , je : & JsonEmitter ) -> Vec < DiagnosticSpanLine > {
560571 je. sm
561- . span_to_lines ( span)
562- . map ( |lines| {
572+ . as_ref ( )
573+ . and_then ( |sm| {
574+ let lines = sm. span_to_lines ( span) . ok ( ) ?;
563575 // We can't get any lines if the source is unavailable.
564576 if !should_show_source_code (
565577 & je. ignored_directories_in_source_blocks ,
566- & je . sm ,
578+ & sm,
567579 & lines. file ,
568580 ) {
569- return vec ! [ ] ;
581+ return None ;
570582 }
571583
572584 let sf = & * lines. file ;
573- lines
585+ let span_lines = lines
574586 . lines
575587 . iter ( )
576588 . map ( |line| {
@@ -581,8 +593,9 @@ impl DiagnosticSpanLine {
581593 line. end_col . 0 + 1 ,
582594 )
583595 } )
584- . collect ( )
596+ . collect ( ) ;
597+ Some ( span_lines)
585598 } )
586- . unwrap_or_else ( |_| vec ! [ ] )
599+ . unwrap_or_default ( )
587600 }
588601}
0 commit comments