@@ -47,6 +47,7 @@ pub struct AnnotateSnippetEmitter {
4747 track_diagnostics : bool ,
4848 terminal_url : TerminalUrl ,
4949 theme : OutputTheme ,
50+ show_suggestions_with_unavailable_source : bool ,
5051}
5152
5253impl Debug for AnnotateSnippetEmitter {
@@ -63,6 +64,10 @@ impl Debug for AnnotateSnippetEmitter {
6364 . field ( "track_diagnostics" , & self . track_diagnostics )
6465 . field ( "terminal_url" , & self . terminal_url )
6566 . field ( "theme" , & self . theme )
67+ . field (
68+ "show_suggestions_with_unavailable_source" ,
69+ & self . show_suggestions_with_unavailable_source ,
70+ )
6671 . finish ( )
6772 }
6873}
@@ -136,6 +141,7 @@ impl AnnotateSnippetEmitter {
136141 track_diagnostics : false ,
137142 terminal_url : TerminalUrl :: No ,
138143 theme : OutputTheme :: Ascii ,
144+ show_suggestions_with_unavailable_source : false ,
139145 }
140146 }
141147
@@ -307,6 +313,12 @@ impl AnnotateSnippetEmitter {
307313 SuggestionStyle :: HideCodeInline
308314 | SuggestionStyle :: ShowCode
309315 | SuggestionStyle :: ShowAlways => {
316+ // Get the original unavailable spans before `suggestion` is consumed.
317+ let unavailable_source_span = if self . show_suggestions_with_unavailable_source {
318+ self . suggestion_span_with_unavailable_source ( sm, & suggestion)
319+ } else {
320+ None
321+ } ;
310322 let substitutions = suggestion
311323 . substitutions
312324 . into_iter ( )
@@ -356,6 +368,30 @@ impl AnnotateSnippetEmitter {
356368 . collect :: < Vec < _ > > ( ) ;
357369
358370 if substitutions. is_empty ( ) {
371+ if let Some ( span) = unavailable_source_span {
372+ let msg = format_diag_message ( & suggestion. msg , args) . to_string ( ) ;
373+ report. push ( std:: mem:: replace (
374+ & mut group,
375+ Group :: with_title (
376+ annotate_snippets:: Level :: HELP . secondary_title ( msg) ,
377+ ) ,
378+ ) ) ;
379+
380+ let file_ann = collect_annotations ( args, & span, sm) ;
381+ let level = annotate_snippets:: Level :: HELP ;
382+ for ( file_idx, ( file, annotations) ) in file_ann. into_iter ( ) . enumerate ( )
383+ {
384+ group = self . unannotated_messages (
385+ annotations,
386+ & file. name ,
387+ sm,
388+ file_idx,
389+ & mut report,
390+ group,
391+ & level,
392+ ) ;
393+ }
394+ }
359395 continue ;
360396 }
361397 let mut msg = format_diag_message ( & suggestion. msg , args) . to_string ( ) ;
@@ -645,6 +681,34 @@ impl AnnotateSnippetEmitter {
645681 }
646682 group
647683 }
684+
685+ fn suggestion_span_with_unavailable_source (
686+ & self ,
687+ sm : & Arc < SourceMap > ,
688+ suggestion : & CodeSuggestion ,
689+ ) -> Option < MultiSpan > {
690+ // These spans cannot be rendered as source patches because their source
691+ // files are unavailable, but can still be shown as locations.
692+ let spans = suggestion
693+ . substitutions
694+ . iter ( )
695+ . flat_map ( |subst| & subst. parts )
696+ . filter_map ( |part| {
697+ if sm. is_valid_span ( part. span ) . is_err ( ) {
698+ debug ! ( "suggestion contains an invalid span: {:?}" , part) ;
699+ return None ;
700+ }
701+ let lines = sm. span_to_lines ( part. span ) . ok ( ) ?;
702+ if sm. ensure_source_file_source_present ( & lines. file ) {
703+ None
704+ } else {
705+ Some ( part. span )
706+ }
707+ } )
708+ . collect :: < Vec < _ > > ( ) ;
709+
710+ if spans. is_empty ( ) { None } else { Some ( MultiSpan :: from_spans ( spans) ) }
711+ }
648712}
649713
650714fn emit_to_destination (
0 commit comments