From 023e3a1deaff4e8780eb5eb5f660bf193cbe384d Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Sun, 6 Sep 2020 09:22:01 +0300 Subject: Highlight errors in macros --- .../diagnostics/test_data/macro_compiler_error.txt | 45 +++++++++++++++++++ crates/rust-analyzer/src/diagnostics/to_proto.rs | 51 +++++++++++++++++++--- 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt index 89dae7d5a..00e8da8a7 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt @@ -44,4 +44,49 @@ }, fixes: [], }, + MappedRustDiagnostic { + url: "file:///test/crates/hir_def/src/path.rs", + diagnostic: Diagnostic { + range: Range { + start: Position { + line: 264, + character: 8, + }, + end: Position { + line: 264, + character: 76, + }, + }, + severity: Some( + Error, + ), + code: None, + source: Some( + "rustc", + ), + message: "Please register your known path in the path module", + related_information: Some( + [ + DiagnosticRelatedInformation { + location: Location { + uri: "file:///test/crates/hir_def/src/data.rs", + range: Range { + start: Position { + line: 79, + character: 15, + }, + end: Position { + line: 79, + character: 41, + }, + }, + }, + message: "Exact error occured here", + }, + ], + ), + tags: None, + }, + fixes: [], + }, ] diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index f69a949f2..33606edda 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -225,12 +225,43 @@ pub(crate) fn map_rust_diagnostic_to_lsp( // If error occurs from macro expansion, add related info pointing to // where the error originated - if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { - related_information.push(lsp_types::DiagnosticRelatedInformation { - location: location_naive(workspace_root, &primary_span), - message: "Error originated from macro here".to_string(), - }); - } + // Also, we would generate an additional diagnostic, so that exact place of macro + // will be highlighted in the error origin place. + let additional_diagnostic = + if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { + let in_macro_location = location_naive(workspace_root, &primary_span); + + // Add related information for the main disagnostic. + related_information.push(lsp_types::DiagnosticRelatedInformation { + location: in_macro_location.clone(), + message: "Error originated from macro here".to_string(), + }); + + // For the additional in-macro diagnostic we add the inverse message pointing to the error location in code. + let information_for_additional_diagnostic = + vec![lsp_types::DiagnosticRelatedInformation { + location: location.clone(), + message: "Exact error occured here".to_string(), + }]; + + let diagnostic = lsp_types::Diagnostic { + range: in_macro_location.range, + severity, + code: code.clone().map(lsp_types::NumberOrString::String), + source: Some(source.clone()), + message: message.clone(), + related_information: Some(information_for_additional_diagnostic), + tags: if tags.is_empty() { None } else { Some(tags.clone()) }, + }; + + Some(MappedRustDiagnostic { + url: in_macro_location.uri, + diagnostic, + fixes: fixes.clone(), + }) + } else { + None + }; let diagnostic = lsp_types::Diagnostic { range: location.range, @@ -246,8 +277,14 @@ pub(crate) fn map_rust_diagnostic_to_lsp( tags: if tags.is_empty() { None } else { Some(tags.clone()) }, }; - MappedRustDiagnostic { url: location.uri, diagnostic, fixes: fixes.clone() } + let main_diagnostic = + MappedRustDiagnostic { url: location.uri, diagnostic, fixes: fixes.clone() }; + match additional_diagnostic { + None => vec![main_diagnostic], + Some(additional_diagnostic) => vec![main_diagnostic, additional_diagnostic], + } }) + .flatten() .collect() } -- cgit v1.2.3