Skip to content

Commit fa9ed4e

Browse files
committed
internal: refactor unresolved macro call diagnostic
1 parent 6d104de commit fa9ed4e

File tree

5 files changed

+94
-95
lines changed

5 files changed

+94
-95
lines changed

crates/hir/src/diagnostics.rs

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use crate::diagnostics_sink::{
1717
};
1818

1919
macro_rules! diagnostics {
20-
($($diag:ident),*) => {
20+
($($diag:ident,)*) => {
2121
pub enum AnyDiagnostic {$(
2222
$diag(Box<$diag>),
2323
)*}
@@ -32,7 +32,13 @@ macro_rules! diagnostics {
3232
};
3333
}
3434

35-
diagnostics![UnresolvedModule, UnresolvedExternCrate, UnresolvedImport, MissingFields];
35+
diagnostics![
36+
UnresolvedModule,
37+
UnresolvedExternCrate,
38+
UnresolvedImport,
39+
UnresolvedMacroCall,
40+
MissingFields,
41+
];
3642

3743
#[derive(Debug)]
3844
pub struct UnresolvedModule {
@@ -50,35 +56,12 @@ pub struct UnresolvedImport {
5056
pub decl: InFile<AstPtr<ast::UseTree>>,
5157
}
5258

53-
// Diagnostic: unresolved-macro-call
54-
//
55-
// This diagnostic is triggered if rust-analyzer is unable to resolve the path to a
56-
// macro in a macro invocation.
5759
#[derive(Debug, Clone, Eq, PartialEq)]
5860
pub struct UnresolvedMacroCall {
59-
pub file: HirFileId,
60-
pub node: AstPtr<ast::MacroCall>,
61+
pub macro_call: InFile<AstPtr<ast::MacroCall>>,
6162
pub path: ModPath,
6263
}
6364

64-
impl Diagnostic for UnresolvedMacroCall {
65-
fn code(&self) -> DiagnosticCode {
66-
DiagnosticCode("unresolved-macro-call")
67-
}
68-
fn message(&self) -> String {
69-
format!("unresolved macro `{}!`", self.path)
70-
}
71-
fn display_source(&self) -> InFile<SyntaxNodePtr> {
72-
InFile::new(self.file, self.node.clone().into())
73-
}
74-
fn as_any(&self) -> &(dyn Any + Send + 'static) {
75-
self
76-
}
77-
fn is_experimental(&self) -> bool {
78-
true
79-
}
80-
}
81-
8265
// Diagnostic: inactive-code
8366
//
8467
// This diagnostic is shown for code with inactive `#[cfg]` attributes.

crates/hir/src/lib.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,13 @@ impl Module {
580580

581581
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
582582
let node = ast.to_node(db.upcast());
583-
sink.push(UnresolvedMacroCall {
584-
file: ast.file_id,
585-
node: AstPtr::new(&node),
586-
path: path.clone(),
587-
});
583+
acc.push(
584+
UnresolvedMacroCall {
585+
macro_call: InFile::new(ast.file_id, AstPtr::new(&node)),
586+
path: path.clone(),
587+
}
588+
.into(),
589+
);
588590
}
589591

590592
DefDiagnosticKind::MacroError { ast, message } => {
@@ -1060,13 +1062,9 @@ impl Function {
10601062
precise_location: None,
10611063
macro_name: None,
10621064
}),
1063-
BodyDiagnostic::UnresolvedMacroCall { node, path } => {
1064-
sink.push(UnresolvedMacroCall {
1065-
file: node.file_id,
1066-
node: node.value.clone(),
1067-
path: path.clone(),
1068-
})
1069-
}
1065+
BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
1066+
UnresolvedMacroCall { macro_call: node.clone(), path: path.clone() }.into(),
1067+
),
10701068
}
10711069
}
10721070

crates/hir_def/src/nameres/tests/diagnostics.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,37 +54,6 @@ fn inactive_via_cfg_attr() {
5454
);
5555
}
5656

57-
#[test]
58-
fn unresolved_legacy_scope_macro() {
59-
check_diagnostics(
60-
r#"
61-
//- /lib.rs
62-
macro_rules! m { () => {} }
63-
64-
m!();
65-
m2!();
66-
//^^^^^^ UnresolvedMacroCall
67-
"#,
68-
);
69-
}
70-
71-
#[test]
72-
fn unresolved_module_scope_macro() {
73-
check_diagnostics(
74-
r#"
75-
//- /lib.rs
76-
mod mac {
77-
#[macro_export]
78-
macro_rules! m { () => {} }
79-
}
80-
81-
self::m!();
82-
self::m2!();
83-
//^^^^^^^^^^^^ UnresolvedMacroCall
84-
"#,
85-
);
86-
}
87-
8857
#[test]
8958
fn builtin_macro_fails_expansion() {
9059
check_diagnostics(

crates/ide/src/diagnostics.rs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
mod unresolved_module;
88
mod unresolved_extern_crate;
99
mod unresolved_import;
10+
mod unresolved_macro_call;
1011
mod missing_fields;
1112

1213
mod fixes;
@@ -16,9 +17,8 @@ mod unlinked_file;
1617
use std::cell::RefCell;
1718

1819
use hir::{
19-
db::AstDatabase,
2020
diagnostics::{AnyDiagnostic, Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder},
21-
InFile, Semantics,
21+
Semantics,
2222
};
2323
use ide_assists::AssistResolveStrategy;
2424
use ide_db::{base_db::SourceDatabase, RootDatabase};
@@ -203,20 +203,6 @@ pub(crate) fn diagnostics(
203203
res.borrow_mut()
204204
.push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code())));
205205
})
206-
.on::<hir::diagnostics::UnresolvedMacroCall, _>(|d| {
207-
let last_path_segment = sema.db.parse_or_expand(d.file).and_then(|root| {
208-
d.node
209-
.to_node(&root)
210-
.path()
211-
.and_then(|it| it.segment())
212-
.and_then(|it| it.name_ref())
213-
.map(|it| InFile::new(d.file, SyntaxNodePtr::new(it.syntax())))
214-
});
215-
let diagnostics = last_path_segment.unwrap_or_else(|| d.display_source());
216-
let display_range = sema.diagnostics_display_range(diagnostics).range;
217-
res.borrow_mut()
218-
.push(Diagnostic::error(display_range, d.message()).with_code(Some(d.code())));
219-
})
220206
.on::<hir::diagnostics::UnimplementedBuiltinMacro, _>(|d| {
221207
let display_range = sema.diagnostics_display_range(d.display_source()).range;
222208
res.borrow_mut()
@@ -259,6 +245,7 @@ pub(crate) fn diagnostics(
259245
AnyDiagnostic::UnresolvedModule(d) => unresolved_module::unresolved_module(&ctx, &d),
260246
AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d),
261247
AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d),
248+
AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d),
262249
AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d),
263250
};
264251
if let Some(code) = d.code {
@@ -480,16 +467,6 @@ mod tests {
480467
assert_eq!(expected, actual);
481468
}
482469

483-
#[test]
484-
fn test_unresolved_macro_range() {
485-
check_diagnostics(
486-
r#"
487-
foo::bar!(92);
488-
//^^^ unresolved macro `foo::bar!`
489-
"#,
490-
);
491-
}
492-
493470
#[test]
494471
fn range_mapping_out_of_macros() {
495472
// FIXME: this is very wrong, but somewhat tricky to fix.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use hir::{db::AstDatabase, InFile};
2+
use syntax::{AstNode, SyntaxNodePtr};
3+
4+
use crate::diagnostics::{Diagnostic, DiagnosticsContext};
5+
6+
// Diagnostic: unresolved-macro-call
7+
//
8+
// This diagnostic is triggered if rust-analyzer is unable to resolve the path
9+
// to a macro in a macro invocation.
10+
pub(super) fn unresolved_macro_call(
11+
ctx: &DiagnosticsContext<'_>,
12+
d: &hir::UnresolvedMacroCall,
13+
) -> Diagnostic {
14+
let last_path_segment = ctx.sema.db.parse_or_expand(d.macro_call.file_id).and_then(|root| {
15+
d.macro_call
16+
.value
17+
.to_node(&root)
18+
.path()
19+
.and_then(|it| it.segment())
20+
.and_then(|it| it.name_ref())
21+
.map(|it| InFile::new(d.macro_call.file_id, SyntaxNodePtr::new(it.syntax())))
22+
});
23+
let diagnostics = last_path_segment.unwrap_or_else(|| d.macro_call.clone().map(|it| it.into()));
24+
25+
Diagnostic::new(
26+
"unresolved-macro-call",
27+
format!("unresolved macro `{}!`", d.path),
28+
ctx.sema.diagnostics_display_range(diagnostics).range,
29+
)
30+
.experimental()
31+
}
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use crate::diagnostics::tests::check_diagnostics;
36+
37+
#[test]
38+
fn test_unresolved_macro_range() {
39+
check_diagnostics(
40+
r#"
41+
foo::bar!(92);
42+
//^^^ unresolved macro `foo::bar!`
43+
"#,
44+
);
45+
}
46+
47+
#[test]
48+
fn unresolved_legacy_scope_macro() {
49+
check_diagnostics(
50+
r#"
51+
macro_rules! m { () => {} }
52+
53+
m!(); m2!();
54+
//^^ unresolved macro `self::m2!`
55+
"#,
56+
);
57+
}
58+
59+
#[test]
60+
fn unresolved_module_scope_macro() {
61+
check_diagnostics(
62+
r#"
63+
mod mac {
64+
#[macro_export]
65+
macro_rules! m { () => {} } }
66+
67+
self::m!(); self::m2!();
68+
//^^ unresolved macro `self::m2!`
69+
"#,
70+
);
71+
}
72+
}

0 commit comments

Comments
 (0)