From 87b779756cb52ed27d4e5b1cdec28544b07f43d7 Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Sat, 20 Aug 2022 13:28:43 +0530 Subject: [PATCH] make impl and trait inactive diagnostics work --- crates/hir-def/src/data.rs | 47 ++++++++++++------- crates/hir-def/src/db.rs | 8 +++- crates/hir/src/lib.rs | 11 +++++ .../src/handlers/inactive_code.rs | 1 - 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 1b4f4ed04a..891104cbb3 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 { + db.trait_data_with_diagnostics(tr).0 + } + + pub(crate) fn trait_data_with_diagnostics_query(db: &dyn DefDatabase, tr: TraitId) -> (Arc, Arc>) { 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(); + 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(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 + '_ { @@ -280,7 +287,11 @@ pub struct ImplData { impl ImplData { pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc { - 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, Arc>) { + 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, MacroCallId)> + '_ { @@ -437,6 +448,7 @@ struct AssocItemCollector<'a> { db: &'a dyn DefDatabase, module_id: ModuleId, def_map: Arc, + inactive_diagnostics: Vec, 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, MacroCallId)>>>) { + ) -> (Vec<(Name, AssocItemId)>, Option, MacroCallId)>>>, Vec) { ( 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 df6dcb024b..2f5ee80cd8 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 { #[salsa::invoke(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; + #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)] + fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, Arc>); + #[salsa::invoke(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; + #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)] + fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, Arc>); + #[salsa::invoke(TypeAliasData::type_alias_data_query)] fn type_alias_data(&self, e: TypeAliasId) -> Arc; diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8f984210e1..45bb057d31 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) { let _p = profile::span("Module::diagnostics").detail(|| { format!("{:?}", self.name(db).map_or("".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 6715823f1f..18fd1c644a 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;