Repository: rust-analyzer/rust-analyzer
Pull request #8108 (2021-03-19 17:24:54)

Fix handling of `#![cfg]` in outline module file
bors r+


Patch:
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 4bcdc0fc84..46a3c60cdd 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1294,29 +1294,37 @@ impl ModCollector<'_, '_> {
                 let db = self.def_collector.db;
                 match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) {
                     Ok((file_id, is_mod_rs, mod_dir)) => {
-                        let module_id = self.push_child_module(
-                            module.name.clone(),
-                            ast_id,
-                            Some((file_id, is_mod_rs)),
-                            &self.item_tree[module.visibility],
-                        );
                         let item_tree = db.file_item_tree(file_id.into());
-                        ModCollector {
-                            def_collector: &mut *self.def_collector,
-                            macro_depth: self.macro_depth,
-                            module_id,
-                            file_id: file_id.into(),
-                            item_tree: &item_tree,
-                            mod_dir,
-                        }
-                        .collect(item_tree.top_level_items());
-                        if is_macro_use
-                            || item_tree
-                                .top_level_attrs(db, self.def_collector.def_map.krate)
-                                .by_key("macro_use")
-                                .exists()
+                        if item_tree
+                            .top_level_attrs(db, self.def_collector.def_map.krate)
+                            .cfg()
+                            .map_or(true, |cfg| {
+                                self.def_collector.cfg_options.check(&cfg) != Some(false)
+                            })
                         {
-                            self.import_all_legacy_macros(module_id);
+                            let module_id = self.push_child_module(
+                                module.name.clone(),
+                                ast_id,
+                                Some((file_id, is_mod_rs)),
+                                &self.item_tree[module.visibility],
+                            );
+                            ModCollector {
+                                def_collector: &mut *self.def_collector,
+                                macro_depth: self.macro_depth,
+                                module_id,
+                                file_id: file_id.into(),
+                                item_tree: &item_tree,
+                                mod_dir,
+                            }
+                            .collect(item_tree.top_level_items());
+                            if is_macro_use
+                                || item_tree
+                                    .top_level_attrs(db, self.def_collector.def_map.krate)
+                                    .by_key("macro_use")
+                                    .exists()
+                            {
+                                self.import_all_legacy_macros(module_id);
+                            }
                         }
                     }
                     Err(candidate) => {


Test patch:
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs
index dfbbad1f90..16a2cd27af 100644
--- a/crates/hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs
@@ -819,3 +819,22 @@ pub mod hash { pub trait Hash {} }
         "#]],
     );
 }
+
+#[test]
+fn cfg_in_module_file() {
+    // Inner `#![cfg]` in a module file makes the whole module disappear.
+    check(
+        r#"
+//- /main.rs
+mod module;
+
+//- /module.rs
+#![cfg(NEVER)]
+
+struct AlsoShoulntAppear;
+        "#,
+        expect![[r#"
+            crate
+        "#]],
+    )
+}