about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs64
2 files changed, 71 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 4b35c1ae719..58aca964290 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -16,6 +16,7 @@ use hir_expand::{
     name::{AsName, Name},
     proc_macro::CustomProcMacroExpander,
     ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
+    MacroFileIdExt,
 };
 use intern::{sym, Interned};
 use itertools::{izip, Itertools};
@@ -1397,7 +1398,12 @@ impl DefCollector<'_> {
         // Then, fetch and process the item tree. This will reuse the expansion result from above.
         let item_tree = self.db.file_item_tree(file_id);
 
-        let mod_dir = self.mod_dirs[&module_id].clone();
+        let mod_dir = if macro_call_id.as_macro_file().is_include_macro(self.db.upcast()) {
+            ModDir::root()
+        } else {
+            self.mod_dirs[&module_id].clone()
+        };
+
         ModCollector {
             def_collector: &mut *self,
             macro_depth: depth,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
index 9f67d6fa8bd..390c934f6da 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
@@ -1356,6 +1356,70 @@ pub mod ip_address {
 }
 
 #[test]
+fn include_many_mods() {
+    check(
+        r#"
+//- /lib.rs
+#[rustc_builtin_macro]
+macro_rules! include { () => {} }
+
+mod nested {
+    include!("out_dir/includes.rs");
+
+    mod different_company {
+        include!("out_dir/different_company/mod.rs");
+    }
+
+    mod util;
+}
+
+//- /nested/util.rs
+pub struct Helper {}
+//- /out_dir/includes.rs
+pub mod company_name {
+    pub mod network {
+        pub mod v1;
+    }
+}
+//- /out_dir/company_name/network/v1.rs
+pub struct IpAddress {}
+//- /out_dir/different_company/mod.rs
+pub mod network;
+//- /out_dir/different_company/network.rs
+pub struct Url {}
+
+"#,
+        expect![[r#"
+            crate
+            nested: t
+
+            crate::nested
+            company_name: t
+            different_company: t
+            util: t
+
+            crate::nested::company_name
+            network: t
+
+            crate::nested::company_name::network
+            v1: t
+
+            crate::nested::company_name::network::v1
+            IpAddress: t
+
+            crate::nested::different_company
+            network: t
+
+            crate::nested::different_company::network
+            Url: t
+
+            crate::nested::util
+            Helper: t
+        "#]],
+    );
+}
+
+#[test]
 fn macro_use_imports_all_macro_types() {
     let db = TestDB::with_files(
         r#"