Repository: rust-analyzer/rust-analyzer
Pull request #6641 (2020-11-26 16:29:50)

Fix def map volatility with `#[cfg]` diagnostics
bors r+ :robot:


Patch:
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index eb41d324e3..202a7dcb6d 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -287,7 +287,7 @@ mod diagnostics {
     use hir_expand::diagnostics::DiagnosticSink;
     use hir_expand::hygiene::Hygiene;
     use hir_expand::InFile;
-    use syntax::{ast, AstPtr, SyntaxNodePtr};
+    use syntax::{ast, AstPtr};
 
     use crate::path::ModPath;
     use crate::{db::DefDatabase, diagnostics::*, nameres::LocalModuleId, AstId};
@@ -300,7 +300,7 @@ mod diagnostics {
 
         UnresolvedImport { ast: AstId<ast::Use>, index: usize },
 
-        UnconfiguredCode { ast: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
+        UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
     }
 
     #[derive(Debug, PartialEq, Eq)]
@@ -341,7 +341,7 @@ mod diagnostics {
 
         pub(super) fn unconfigured_code(
             container: LocalModuleId,
-            ast: InFile<SyntaxNodePtr>,
+            ast: AstId<ast::Item>,
             cfg: CfgExpr,
             opts: CfgOptions,
         ) -> Self {
@@ -399,9 +399,10 @@ mod diagnostics {
                 }
 
                 DiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
+                    let item = ast.to_node(db.upcast());
                     sink.push(InactiveCode {
                         file: ast.file_id,
-                        node: ast.value.clone(),
+                        node: AstPtr::new(&item).into(),
                         cfg: cfg.clone(),
                         opts: opts.clone(),
                     });
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 386287518a..5ed9073e08 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1336,13 +1336,11 @@ impl ModCollector<'_, '_> {
 
     fn emit_unconfigured_diagnostic(&mut self, item: ModItem, cfg: &CfgExpr) {
         let ast_id = item.ast_id(self.item_tree);
-        let id_map = self.def_collector.db.ast_id_map(self.file_id);
-        let syntax_ptr = id_map.get(ast_id).syntax_node_ptr();
 
-        let ast_node = InFile::new(self.file_id, syntax_ptr);
+        let ast_id = InFile::new(self.file_id, ast_id);
         self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
             self.module_id,
-            ast_node,
+            ast_id,
             cfg.clone(),
             self.def_collector.cfg_options.clone(),
         ));


Test patch:
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs
index cfbc62cc43..8981fa7c94 100644
--- a/crates/hir_def/src/nameres/tests/incremental.rs
+++ b/crates/hir_def/src/nameres/tests/incremental.rs
@@ -38,6 +38,9 @@ fn typing_inside_a_function_should_not_invalidate_def_map() {
         fn foo() -> i32 {
             1 + 1
         }
+
+        #[cfg(never)]
+        fn no() {}
         //- /foo/mod.rs
         pub mod bar;
 
@@ -53,6 +56,9 @@ fn typing_inside_a_function_should_not_invalidate_def_map() {
         use E::*;
 
         fn foo() -> i32 { 92 }
+
+        #[cfg(never)]
+        fn no() {}
         ",
     );
 }