Highlight errors in macros

This commit is contained in:
Igor Aleksanov 2020-09-06 09:22:01 +03:00
parent 0275b08d15
commit 023e3a1dea
2 changed files with 89 additions and 7 deletions

View file

@ -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: [],
},
]

View file

@ -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()
}