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