about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir-def/src/data.rs13
-rw-r--r--crates/hir-ty/src/tests/macros.rs62
-rw-r--r--crates/ide-diagnostics/src/handlers/inactive_code.rs19
3 files changed, 93 insertions, 1 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 12bfbbe3084..8e8b5c322f9 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -2,7 +2,7 @@
 
 use std::{mem, sync::Arc};
 
-use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId};
+use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroDefKind};
 use syntax::ast;
 
 use crate::{
@@ -498,6 +498,17 @@ impl<'a> AssocItemCollector<'a> {
                     if !self.db.enable_proc_attr_macros() {
                         continue 'attrs;
                     }
+                    let loc = self.db.lookup_intern_macro_call(call_id);
+                    if let MacroDefKind::ProcMacro(exp, ..) = loc.def.kind {
+                        // If there's no expander for the proc macro (e.g. the
+                        // proc macro is ignored, or building the proc macro
+                        // crate failed), skip expansion like we would if it was
+                        // disabled. This is analogous to the handling in
+                        // `DefCollector::collect_macros`.
+                        if exp.is_dummy() {
+                            continue 'attrs;
+                        }
+                    }
                     match self.expander.enter_expand_id(self.db, call_id) {
                         ExpandResult { value: Some((mark, mac)), .. } => {
                             self.collect_macro_items(mark, mac);
diff --git a/crates/hir-ty/src/tests/macros.rs b/crates/hir-ty/src/tests/macros.rs
index a4299d9f050..a1ab6060e79 100644
--- a/crates/hir-ty/src/tests/macros.rs
+++ b/crates/hir-ty/src/tests/macros.rs
@@ -1274,3 +1274,65 @@ impl S {
         "#]],
     );
 }
+
+#[test]
+fn infer_in_unexpandable_attr_proc_macro_1() {
+    check_types(
+        r#"
+//- /main.rs crate:main deps:mac
+#[mac::attr_macro]
+fn foo() {
+    let xxx = 1;
+      //^^^ i32
+}
+
+//- /mac.rs crate:mac
+#![crate_type="proc-macro"]
+#[proc_macro_attribute]
+pub fn attr_macro() {}
+"#,
+    );
+}
+
+#[test]
+fn infer_in_unexpandable_attr_proc_macro_in_impl() {
+    check_types(
+        r#"
+//- /main.rs crate:main deps:mac
+struct Foo;
+impl Foo {
+    #[mac::attr_macro]
+    fn foo() {
+        let xxx = 1;
+          //^^^ i32
+    }
+}
+
+//- /mac.rs crate:mac
+#![crate_type="proc-macro"]
+#[proc_macro_attribute]
+pub fn attr_macro() {}
+"#,
+    );
+}
+
+#[test]
+fn infer_in_unexpandable_attr_proc_macro_in_trait() {
+    check_types(
+        r#"
+//- /main.rs crate:main deps:mac
+trait Foo {
+    #[mac::attr_macro]
+    fn foo() {
+        let xxx = 1;
+          //^^^ i32
+    }
+}
+
+//- /mac.rs crate:mac
+#![crate_type="proc-macro"]
+#[proc_macro_attribute]
+pub fn attr_macro() {}
+"#,
+    );
+}
diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs
index 17243d612a4..97ea5c456a6 100644
--- a/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -104,6 +104,25 @@ fn f() {
         );
     }
 
+    #[test]
+    fn inactive_assoc_item() {
+        // FIXME these currently don't work, hence the *
+        check(
+            r#"
+struct Foo;
+impl Foo {
+    #[cfg(any())] pub fn f() {}
+  //*************************** weak: code is inactive due to #[cfg] directives
+}
+
+trait Bar {
+    #[cfg(any())] pub fn f() {}
+  //*************************** weak: code is inactive due to #[cfg] directives
+}
+"#,
+        );
+    }
+
     /// Tests that `cfg` attributes behind `cfg_attr` is handled properly.
     #[test]
     fn inactive_via_cfg_attr() {