aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs')
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs b/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs
new file mode 100644
index 000000000..f0f7725db
--- /dev/null
+++ b/crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs
@@ -0,0 +1,84 @@
1use hir::{db::AstDatabase, InFile};
2use syntax::{AstNode, SyntaxNodePtr};
3
4use crate::{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.
10pub(crate) 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)]
34mod tests {
35 use crate::tests::check_diagnostics;
36
37 #[test]
38 fn unresolved_macro_diag() {
39 check_diagnostics(
40 r#"
41fn f() {
42 m!();
43} //^ error: unresolved macro `m!`
44
45"#,
46 );
47 }
48
49 #[test]
50 fn test_unresolved_macro_range() {
51 check_diagnostics(
52 r#"
53foo::bar!(92);
54 //^^^ error: unresolved macro `foo::bar!`
55"#,
56 );
57 }
58
59 #[test]
60 fn unresolved_legacy_scope_macro() {
61 check_diagnostics(
62 r#"
63macro_rules! m { () => {} }
64
65m!(); m2!();
66 //^^ error: unresolved macro `self::m2!`
67"#,
68 );
69 }
70
71 #[test]
72 fn unresolved_module_scope_macro() {
73 check_diagnostics(
74 r#"
75mod mac {
76#[macro_export]
77macro_rules! m { () => {} } }
78
79self::m!(); self::m2!();
80 //^^ error: unresolved macro `self::m2!`
81"#,
82 );
83 }
84}