about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir-def/src/data.rs49
-rw-r--r--crates/hir-def/src/db.rs8
-rw-r--r--crates/hir/src/lib.rs11
-rw-r--r--crates/ide-diagnostics/src/handlers/inactive_code.rs1
4 files changed, 49 insertions, 20 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 1b4f4ed04ac..891104cbb37 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -210,6 +210,10 @@ 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 +233,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 +287,11 @@ 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 +304,10 @@ 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 +448,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 +471,17 @@ 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,13 +493,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.def_map.push_diagnostic(DefDiagnostic::unconfigured_code(
+                self.inactive_diagnostics.push(DefDiagnostic::unconfigured_code(
                     self.module_id.local_id,
-                    InFile::new(tree_id.file_id(), item.ast_id(&item_tree).upcast()),
+                    InFile::new(self.expander.current_file_id(), item.ast_id(&item_tree).upcast()),
                     attrs.cfg().unwrap(),
                     self.expander.cfg_options().clone()
                 ));
-                dbg!("Ignoring assoc item!");
                 continue;
             }
 
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index df6dcb024b5..2f5ee80cd85 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::{DefMap, diagnostics::DefDiagnostic},
     visibility::{self, Visibility},
     AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
     ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
@@ -106,9 +106,15 @@ 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/src/lib.rs b/crates/hir/src/lib.rs
index 8f984210e11..45bb057d31a 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()))
@@ -530,12 +531,22 @@ impl Module {
                     if def_map[m.id.local_id].origin.is_inline() {
                         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 6715823f1ff..18fd1c644a1 100644
--- a/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -106,7 +106,6 @@ fn f() {
 
     #[test]
     fn inactive_assoc_item() {
-        // FIXME these currently don't work, hence the *
         check(
             r#"
 struct Foo;