about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-22 07:20:56 +0000
committerbors <bors@rust-lang.org>2022-08-22 07:20:56 +0000
commitdea163970a94f05d56e482c423df1cd379c8735c (patch)
treeb8d2db03565072077af4dfc9fcc3ccb7e2f5cd7b
parentf27f4a9b558b3a37b41b44a607fcc531b639e304 (diff)
parent23c00ed50d327918b0f9fb59345ed87cfe7584a9 (diff)
downloadrust-dea163970a94f05d56e482c423df1cd379c8735c.tar.gz
rust-dea163970a94f05d56e482c423df1cd379c8735c.zip
Auto merge of #12965 - DesmondWillowbrook:assoc-method-dimming, r=Veykril
feat: make trait assoc items become inactive due to cfg

fixes #12394
-rw-r--r--crates/hir-def/src/data.rs70
-rw-r--r--crates/hir-def/src/db.rs9
-rw-r--r--crates/hir-def/src/nameres/diagnostics.rs2
-rw-r--r--crates/hir/src/lib.rs11
-rw-r--r--crates/ide-diagnostics/src/handlers/inactive_code.rs5
5 files changed, 75 insertions, 22 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 35c8708955a..631ae3cf11f 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -2,7 +2,7 @@
 
 use std::sync::Arc;
 
-use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, MacroCallId, MacroDefKind};
+use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroDefKind};
 use smallvec::SmallVec;
 use syntax::ast;
 
@@ -12,7 +12,10 @@ use crate::{
     db::DefDatabase,
     intern::Interned,
     item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, ModItem, Param, TreeId},
-    nameres::{attr_resolution::ResolvedAttr, proc_macro::ProcMacroKind, DefMap},
+    nameres::{
+        attr_resolution::ResolvedAttr, diagnostics::DefDiagnostic, proc_macro::ProcMacroKind,
+        DefMap,
+    },
     type_ref::{TraitRef, TypeBound, TypeRef},
     visibility::RawVisibility,
     AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -210,6 +213,13 @@ pub struct TraitData {
 
 impl TraitData {
     pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> {
+        db.trait_data_with_diagnostics(tr).0
+    }
+
+    pub(crate) fn trait_data_with_diagnostics_query(
+        db: &dyn DefDatabase,
+        tr: TraitId,
+    ) -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>) {
         let tr_loc @ ItemLoc { container: module_id, id: tree_id } = tr.lookup(db);
         let item_tree = tree_id.item_tree(db);
         let tr_def = &item_tree[tree_id.value];
@@ -229,17 +239,20 @@ impl TraitData {
         let mut collector =
             AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
         collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
-        let (items, attribute_calls) = collector.finish();
-
-        Arc::new(TraitData {
-            name,
-            attribute_calls,
-            items,
-            is_auto,
-            is_unsafe,
-            visibility,
-            skip_array_during_method_dispatch,
-        })
+        let (items, attribute_calls, diagnostics) = collector.finish();
+
+        (
+            Arc::new(TraitData {
+                name,
+                attribute_calls,
+                items,
+                is_auto,
+                is_unsafe,
+                visibility,
+                skip_array_during_method_dispatch,
+            }),
+            Arc::new(diagnostics),
+        )
     }
 
     pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
@@ -280,7 +293,14 @@ pub struct ImplData {
 
 impl ImplData {
     pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc<ImplData> {
-        let _p = profile::span("impl_data_query");
+        db.impl_data_with_diagnostics(id).0
+    }
+
+    pub(crate) fn impl_data_with_diagnostics_query(
+        db: &dyn DefDatabase,
+        id: ImplId,
+    ) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>) {
+        let _p = profile::span("impl_data_with_diagnostics_query");
         let ItemLoc { container: module_id, id: tree_id } = id.lookup(db);
 
         let item_tree = tree_id.item_tree(db);
@@ -293,10 +313,13 @@ impl ImplData {
             AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::ImplId(id));
         collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items);
 
-        let (items, attribute_calls) = collector.finish();
+        let (items, attribute_calls, diagnostics) = collector.finish();
         let items = items.into_iter().map(|(_, item)| item).collect();
 
-        Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls })
+        (
+            Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls }),
+            Arc::new(diagnostics),
+        )
     }
 
     pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
@@ -437,6 +460,7 @@ struct AssocItemCollector<'a> {
     db: &'a dyn DefDatabase,
     module_id: ModuleId,
     def_map: Arc<DefMap>,
+    inactive_diagnostics: Vec<DefDiagnostic>,
     container: ItemContainerId,
     expander: Expander,
 
@@ -459,15 +483,21 @@ impl<'a> AssocItemCollector<'a> {
             expander: Expander::new(db, file_id, module_id),
             items: Vec::new(),
             attr_calls: Vec::new(),
+            inactive_diagnostics: Vec::new(),
         }
     }
 
     fn finish(
         self,
-    ) -> (Vec<(Name, AssocItemId)>, Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>) {
+    ) -> (
+        Vec<(Name, AssocItemId)>,
+        Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
+        Vec<DefDiagnostic>,
+    ) {
         (
             self.items,
             if self.attr_calls.is_empty() { None } else { Some(Box::new(self.attr_calls)) },
+            self.inactive_diagnostics,
         )
     }
 
@@ -479,6 +509,12 @@ impl<'a> AssocItemCollector<'a> {
         'items: for &item in assoc_items {
             let attrs = item_tree.attrs(self.db, self.module_id.krate, ModItem::from(item).into());
             if !attrs.is_cfg_enabled(self.expander.cfg_options()) {
+                self.inactive_diagnostics.push(DefDiagnostic::unconfigured_code(
+                    self.module_id.local_id,
+                    InFile::new(self.expander.current_file_id(), item.ast_id(&item_tree).upcast()),
+                    attrs.cfg().unwrap(),
+                    self.expander.cfg_options().clone(),
+                ));
                 continue;
             }
 
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index df6dcb024b5..40b2f734b71 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -20,7 +20,7 @@ use crate::{
     intern::Interned,
     item_tree::{AttrOwner, ItemTree},
     lang_item::{LangItemTarget, LangItems},
-    nameres::DefMap,
+    nameres::{diagnostics::DefDiagnostic, DefMap},
     visibility::{self, Visibility},
     AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
     ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
@@ -106,9 +106,16 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
     #[salsa::invoke(ImplData::impl_data_query)]
     fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
 
+    #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)]
+    fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>);
+
     #[salsa::invoke(TraitData::trait_data_query)]
     fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
 
+    #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)]
+    fn trait_data_with_diagnostics(&self, tr: TraitId)
+        -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>);
+
     #[salsa::invoke(TypeAliasData::type_alias_data_query)]
     fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
 
diff --git a/crates/hir-def/src/nameres/diagnostics.rs b/crates/hir-def/src/nameres/diagnostics.rs
index 0d01f6d0aba..ed7e920fd2b 100644
--- a/crates/hir-def/src/nameres/diagnostics.rs
+++ b/crates/hir-def/src/nameres/diagnostics.rs
@@ -73,7 +73,7 @@ impl DefDiagnostic {
         Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } }
     }
 
-    pub(super) fn unconfigured_code(
+    pub fn unconfigured_code(
         container: LocalModuleId,
         ast: AstId<ast::Item>,
         cfg: CfgExpr,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index aa019ca4838..6dccf2ed20b 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -511,6 +511,7 @@ impl Module {
             .collect()
     }
 
+    /// Fills `acc` with the module's diagnostics.
     pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
         let _p = profile::span("Module::diagnostics").detail(|| {
             format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
@@ -531,11 +532,21 @@ impl Module {
                         m.diagnostics(db, acc)
                     }
                 }
+                ModuleDef::Trait(t) => {
+                    for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
+                        emit_def_diagnostic(db, acc, diag);
+                    }
+                    acc.extend(decl.diagnostics(db))
+                }
                 _ => acc.extend(decl.diagnostics(db)),
             }
         }
 
         for impl_def in self.impl_defs(db) {
+            for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
+                emit_def_diagnostic(db, acc, diag);
+            }
+
             for item in impl_def.items(db) {
                 let def: DefWithBody = match item {
                     AssocItem::Function(it) => it.into(),
diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs
index 5694f33525e..04918891b25 100644
--- a/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -106,18 +106,17 @@ 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
+  //^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives
 }
 
 trait Bar {
     #[cfg(any())] pub fn f() {}
-  //*************************** weak: code is inactive due to #[cfg] directives
+  //^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives
 }
 "#,
         );