diff options
author | Igor Aleksanov <[email protected]> | 2020-09-06 07:22:01 +0100 |
---|---|---|
committer | Igor Aleksanov <[email protected]> | 2020-09-06 07:22:01 +0100 |
commit | 023e3a1deaff4e8780eb5eb5f660bf193cbe384d (patch) | |
tree | 7c03a8b4c50ed6ab0d76da2bd5d08353343fa74e | |
parent | 0275b08d1521606fa733f76fe5d5707717456fb4 (diff) |
Highlight errors in macros
-rw-r--r-- | crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt | 45 | ||||
-rw-r--r-- | 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 @@ | |||
44 | }, | 44 | }, |
45 | fixes: [], | 45 | fixes: [], |
46 | }, | 46 | }, |
47 | MappedRustDiagnostic { | ||
48 | url: "file:///test/crates/hir_def/src/path.rs", | ||
49 | diagnostic: Diagnostic { | ||
50 | range: Range { | ||
51 | start: Position { | ||
52 | line: 264, | ||
53 | character: 8, | ||
54 | }, | ||
55 | end: Position { | ||
56 | line: 264, | ||
57 | character: 76, | ||
58 | }, | ||
59 | }, | ||
60 | severity: Some( | ||
61 | Error, | ||
62 | ), | ||
63 | code: None, | ||
64 | source: Some( | ||
65 | "rustc", | ||
66 | ), | ||
67 | message: "Please register your known path in the path module", | ||
68 | related_information: Some( | ||
69 | [ | ||
70 | DiagnosticRelatedInformation { | ||
71 | location: Location { | ||
72 | uri: "file:///test/crates/hir_def/src/data.rs", | ||
73 | range: Range { | ||
74 | start: Position { | ||
75 | line: 79, | ||
76 | character: 15, | ||
77 | }, | ||
78 | end: Position { | ||
79 | line: 79, | ||
80 | character: 41, | ||
81 | }, | ||
82 | }, | ||
83 | }, | ||
84 | message: "Exact error occured here", | ||
85 | }, | ||
86 | ], | ||
87 | ), | ||
88 | tags: None, | ||
89 | }, | ||
90 | fixes: [], | ||
91 | }, | ||
47 | ] | 92 | ] |
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( | |||
225 | 225 | ||
226 | // If error occurs from macro expansion, add related info pointing to | 226 | // If error occurs from macro expansion, add related info pointing to |
227 | // where the error originated | 227 | // where the error originated |
228 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { | 228 | // Also, we would generate an additional diagnostic, so that exact place of macro |
229 | related_information.push(lsp_types::DiagnosticRelatedInformation { | 229 | // will be highlighted in the error origin place. |
230 | location: location_naive(workspace_root, &primary_span), | 230 | let additional_diagnostic = |
231 | message: "Error originated from macro here".to_string(), | 231 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { |
232 | }); | 232 | let in_macro_location = location_naive(workspace_root, &primary_span); |
233 | } | 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 | let diagnostic = lsp_types::Diagnostic { | 266 | let diagnostic = lsp_types::Diagnostic { |
236 | range: location.range, | 267 | range: location.range, |
@@ -246,8 +277,14 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
246 | tags: if tags.is_empty() { None } else { Some(tags.clone()) }, | 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 | .collect() | 288 | .collect() |
252 | } | 289 | } |
253 | 290 | ||