ide_diagnostics/handlers/
unresolved_macro_call.rs

1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3// Diagnostic: unresolved-macro-call
4//
5// This diagnostic is triggered if rust-analyzer is unable to resolve the path
6// to a macro in a macro invocation.
7pub(crate) fn unresolved_macro_call(
8    ctx: &DiagnosticsContext<'_>,
9    d: &hir::UnresolvedMacroCall,
10) -> Diagnostic {
11    let display_range = ctx.sema.diagnostics_display_range_for_range(d.range);
12    let bang = if d.is_bang { "!" } else { "" };
13    Diagnostic::new(
14        DiagnosticCode::RustcHardError("unresolved-macro-call"),
15        format!("unresolved macro `{}{bang}`", d.path.display(ctx.sema.db, ctx.edition)),
16        display_range,
17    )
18}
19
20#[cfg(test)]
21mod tests {
22    use crate::tests::check_diagnostics;
23
24    #[test]
25    fn unresolved_macro_diag() {
26        check_diagnostics(
27            r#"
28fn f() {
29    m!();
30} //^ error: unresolved macro `m!`
31
32"#,
33        );
34    }
35
36    #[test]
37    fn test_unresolved_macro_range() {
38        check_diagnostics(
39            r#"
40foo::bar!(92);
41   //^^^ error: unresolved macro `foo::bar!`
42"#,
43        );
44    }
45
46    #[test]
47    fn unresolved_legacy_scope_macro() {
48        check_diagnostics(
49            r#"
50macro_rules! m { () => {} }
51
52m!(); m2!();
53    //^^ error: unresolved macro `m2!`
54"#,
55        );
56    }
57
58    #[test]
59    fn unresolved_module_scope_macro() {
60        check_diagnostics(
61            r#"
62mod mac {
63#[macro_export]
64macro_rules! m { () => {} } }
65
66self::m!(); self::m2!();
67                //^^ error: unresolved macro `self::m2!`
68"#,
69        );
70    }
71
72    #[test]
73    fn regression_panic_with_inner_attribute_in_presence_of_unresolved_crate() {
74        check_diagnostics(
75            r#"
76    mod _test_inner {
77        #![empty_attr]
78        // ^^^^^^^^^^ error: unresolved macro `empty_attr`
79    }
80"#,
81        );
82    }
83
84    #[test]
85    fn no_unresolved_panic_inside_mod_inside_fn() {
86        check_diagnostics(
87            r#"
88//- /core.rs library crate:core
89#[macro_export]
90macro_rules! panic {
91    () => {};
92}
93
94//- /lib.rs crate:foo deps:core
95#[macro_use]
96extern crate core;
97
98fn foo() {
99    mod init {
100        pub fn init() {
101            panic!();
102        }
103    }
104}
105    "#,
106        );
107    }
108}