diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-09-10 21:55:06 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-09-10 21:55:06 +0100 |
commit | 868f4b57561cab3f537c9c5d0c9ad78fc4703891 (patch) | |
tree | 217405b14f2b57de8739166045b625cbb3e9cacb /crates | |
parent | 5c336e266fe09ae9ae6e634513d441cbcde63696 (diff) | |
parent | 023e3a1deaff4e8780eb5eb5f660bf193cbe384d (diff) |
Merge #5956
5956: Highlight errors in macros r=jonas-schievink a=popzxc
Resolves #4924
This PR makes rust-analyzer highlight not only the source place when error originates in macro, but also the exact places in macro which caused an error.
This is done by creating an inverse diagnostic, which points to the macro and cross-references the source place.
![изображение](https://user-images.githubusercontent.com/12111581/92319594-b71e6c00-f022-11ea-94c1-f412905269dd.png)
Co-authored-by: Igor Aleksanov <[email protected]>
Diffstat (limited to 'crates')
-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 | ||