Skip to content

Commit 868f4b5

Browse files
bors[bot]popzxc
andauthored
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]>
2 parents 5c336e2 + 023e3a1 commit 868f4b5

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,49 @@
4444
},
4545
fixes: [],
4646
},
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+
},
4792
]

crates/rust-analyzer/src/diagnostics/to_proto.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)