about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-22 07:00:54 +0000
committerbors <bors@rust-lang.org>2024-07-22 07:00:54 +0000
commit5236347f7c30f3c611f37db395568dd37d12fa0e (patch)
tree92aa152efc2e82dfa8f35fb0654a72b786b9232b
parentf84d14e1c085de69261f4ef6ac483e0c58016f49 (diff)
parent8e7e37f4a9b214999260e18324c79b4db8beb126 (diff)
downloadrust-5236347f7c30f3c611f37db395568dd37d12fa0e.tar.gz
rust-5236347f7c30f3c611f37db395568dd37d12fa0e.zip
Auto merge of #17660 - ObsidianMinor:fix/17645, r=Veykril
Fix more path resolution for included submodules

Now with more comprehensive testing! This adds tests for includes within modules. Previous testing was not comprehensive enough since submodules that use `include!` didn't actually work either! The `ModDir` used for resolving mods relative to included files has to be `ModDir::root()`. The original test just so happened to put the submodules in the root which made this work, but if you put the `include!` inside a `mod` block it didn't work.

With this change, when collecting a macro expansion, if the macro call is an `include!`, we use the `ModDir::root()` instead of the current module we're in.
-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#"