@@ -225,12 +225,43 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
225225
226226 // If error occurs from macro expansion, add related info pointing to
227227 // where the error originated
228- if !is_from_macro ( & primary_span. file_name ) && primary_span. expansion . is_some ( ) {
229- related_information. push ( lsp_types:: DiagnosticRelatedInformation {
230- location : location_naive ( workspace_root, & primary_span) ,
231- message : "Error originated from macro here" . to_string ( ) ,
232- } ) ;
233- }
228+ // Also, we would generate an additional diagnostic, so that exact place of macro
229+ // will be highlighted in the error origin place.
230+ let additional_diagnostic =
231+ if !is_from_macro ( & primary_span. file_name ) && primary_span. expansion . is_some ( ) {
232+ let in_macro_location = location_naive ( workspace_root, & primary_span) ;
233+
234+ // Add related information for the main disagnostic.
235+ related_information. push ( lsp_types:: DiagnosticRelatedInformation {
236+ location : in_macro_location. clone ( ) ,
237+ message : "Error originated from macro here" . to_string ( ) ,
238+ } ) ;
239+
240+ // For the additional in-macro diagnostic we add the inverse message pointing to the error location in code.
241+ let information_for_additional_diagnostic =
242+ vec ! [ lsp_types:: DiagnosticRelatedInformation {
243+ location: location. clone( ) ,
244+ message: "Exact error occured here" . to_string( ) ,
245+ } ] ;
246+
247+ let diagnostic = lsp_types:: Diagnostic {
248+ range : in_macro_location. range ,
249+ severity,
250+ code : code. clone ( ) . map ( lsp_types:: NumberOrString :: String ) ,
251+ source : Some ( source. clone ( ) ) ,
252+ message : message. clone ( ) ,
253+ related_information : Some ( information_for_additional_diagnostic) ,
254+ tags : if tags. is_empty ( ) { None } else { Some ( tags. clone ( ) ) } ,
255+ } ;
256+
257+ Some ( MappedRustDiagnostic {
258+ url : in_macro_location. uri ,
259+ diagnostic,
260+ fixes : fixes. clone ( ) ,
261+ } )
262+ } else {
263+ None
264+ } ;
234265
235266 let diagnostic = lsp_types:: Diagnostic {
236267 range : location. range ,
@@ -246,8 +277,14 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
246277 tags : if tags. is_empty ( ) { None } else { Some ( tags. clone ( ) ) } ,
247278 } ;
248279
249- MappedRustDiagnostic { url : location. uri , diagnostic, fixes : fixes. clone ( ) }
280+ let main_diagnostic =
281+ MappedRustDiagnostic { url : location. uri , diagnostic, fixes : fixes. clone ( ) } ;
282+ match additional_diagnostic {
283+ None => vec ! [ main_diagnostic] ,
284+ Some ( additional_diagnostic) => vec ! [ main_diagnostic, additional_diagnostic] ,
285+ }
250286 } )
287+ . flatten ( )
251288 . collect ( )
252289}
253290
0 commit comments