@@ -225,12 +225,43 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
225
225
226
226
// If error occurs from macro expansion, add related info pointing to
227
227
// 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
+ } ;
234
265
235
266
let diagnostic = lsp_types:: Diagnostic {
236
267
range : location. range ,
@@ -246,8 +277,14 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
246
277
tags : if tags. is_empty ( ) { None } else { Some ( tags. clone ( ) ) } ,
247
278
} ;
248
279
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
+ }
250
286
} )
287
+ . flatten ( )
251
288
. collect ( )
252
289
}
253
290
0 commit comments