fix: Fix nested macro diagnostics pointing at macro expansion files

This commit is contained in:
Lukas Wirth 2022-11-19 10:32:32 +01:00
parent 52bc15fc1f
commit dc8254c6ab
4 changed files with 25 additions and 19 deletions

View file

@ -5,10 +5,7 @@ use crate::{Diagnostic, DiagnosticsContext};
// This diagnostic is shown for macro expansion errors. // This diagnostic is shown for macro expansion errors.
pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic { pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic {
// Use more accurate position if available. // Use more accurate position if available.
let display_range = d let display_range = ctx.resolve_precise_location(&d.node, d.precise_location);
.precise_location
.unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()).range);
Diagnostic::new("macro-error", d.message.clone(), display_range).experimental() Diagnostic::new("macro-error", d.message.clone(), display_range).experimental()
} }

View file

@ -9,10 +9,7 @@ pub(crate) fn unresolved_macro_call(
d: &hir::UnresolvedMacroCall, d: &hir::UnresolvedMacroCall,
) -> Diagnostic { ) -> Diagnostic {
// Use more accurate position if available. // Use more accurate position if available.
let display_range = d let display_range = ctx.resolve_precise_location(&d.macro_call, d.precise_location);
.precise_location
.unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.macro_call.clone()).range);
let bang = if d.is_bang { "!" } else { "" }; let bang = if d.is_bang { "!" } else { "" };
Diagnostic::new( Diagnostic::new(
"unresolved-macro-call", "unresolved-macro-call",

View file

@ -1,5 +1,4 @@
use hir::db::DefDatabase; use hir::db::DefDatabase;
use syntax::NodeOrToken;
use crate::{Diagnostic, DiagnosticsContext, Severity}; use crate::{Diagnostic, DiagnosticsContext, Severity};
@ -19,16 +18,7 @@ pub(crate) fn unresolved_proc_macro(
proc_attr_macros_enabled: bool, proc_attr_macros_enabled: bool,
) -> Diagnostic { ) -> Diagnostic {
// Use more accurate position if available. // Use more accurate position if available.
let display_range = (|| { let display_range = ctx.resolve_precise_location(&d.node, d.precise_location);
let precise_location = d.precise_location?;
let root = ctx.sema.parse_or_expand(d.node.file_id)?;
match root.covering_element(precise_location) {
NodeOrToken::Node(it) => Some(ctx.sema.original_range(&it)),
NodeOrToken::Token(it) => d.node.with_value(it).original_file_range_opt(ctx.sema.db),
}
})()
.unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()))
.range;
let config_enabled = match d.kind { let config_enabled = match d.kind {
hir::MacroKind::Attr => proc_macros_enabled && proc_attr_macros_enabled, hir::MacroKind::Attr => proc_macros_enabled && proc_attr_macros_enabled,

View file

@ -182,6 +182,28 @@ struct DiagnosticsContext<'a> {
resolve: &'a AssistResolveStrategy, resolve: &'a AssistResolveStrategy,
} }
impl<'a> DiagnosticsContext<'a> {
fn resolve_precise_location(
&self,
node: &InFile<SyntaxNodePtr>,
precise_location: Option<TextRange>,
) -> TextRange {
let sema = &self.sema;
(|| {
let precise_location = precise_location?;
let root = sema.parse_or_expand(node.file_id)?;
match root.covering_element(precise_location) {
syntax::NodeOrToken::Node(it) => Some(sema.original_range(&it)),
syntax::NodeOrToken::Token(it) => {
node.with_value(it).original_file_range_opt(sema.db)
}
}
})()
.unwrap_or_else(|| sema.diagnostics_display_range(node.clone()))
.range
}
}
pub fn diagnostics( pub fn diagnostics(
db: &RootDatabase, db: &RootDatabase,
config: &DiagnosticsConfig, config: &DiagnosticsConfig,