From 1883d1f14146959cfa9cdf1ed43e5d1ad013e07e Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Sun, 7 Aug 2022 20:39:11 +0530 Subject: [PATCH 1/6] activate assoc item test --- crates/ide-diagnostics/src/handlers/inactive_code.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs index 97ea5c456a6..6715823f1ff 100644 --- a/crates/ide-diagnostics/src/handlers/inactive_code.rs +++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs @@ -112,12 +112,12 @@ fn f() { 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 } "#, ); From 196f389a708d5e0002a1d3b4e1059d43dc4542fb Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Mon, 8 Aug 2022 16:40:29 +0530 Subject: [PATCH 2/6] try adding diagnostrics for AssocItems --- crates/hir-def/src/data.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 35c8708955a..1b4f4ed04ac 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, MacroCallId, MacroDefKind, InFile}; use smallvec::SmallVec; use syntax::ast; @@ -12,7 +12,7 @@ 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, proc_macro::ProcMacroKind, DefMap, diagnostics::DefDiagnostic}, type_ref::{TraitRef, TypeBound, TypeRef}, visibility::RawVisibility, AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, @@ -479,6 +479,13 @@ 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.module_id.local_id, + InFile::new(tree_id.file_id(), item.ast_id(&item_tree).upcast()), + attrs.cfg().unwrap(), + self.expander.cfg_options().clone() + )); + dbg!("Ignoring assoc item!"); continue; } From c1eae3d0281e1e34f64332b02a7dc4bdd0ae6e5b Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Mon, 8 Aug 2022 16:45:27 +0530 Subject: [PATCH 3/6] make diagnostic function public --- crates/hir-def/src/nameres.rs | 8 ++++++++ crates/hir-def/src/nameres/diagnostics.rs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 45f631936d2..a2181a6bf41 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -511,6 +511,14 @@ impl DefMap { self.diagnostics.as_slice() } + pub fn push_diagnostic(&mut self, d: DefDiagnostic) { + self.diagnostics.push(d) + } + + pub fn push_diagnostics(&mut self, i: impl Iterator) { + self.diagnostics.extend(i) + } + pub fn recursion_limit(&self) -> Option { self.recursion_limit } 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, cfg: CfgExpr, From 87b779756cb52ed27d4e5b1cdec28544b07f43d7 Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Sat, 20 Aug 2022 13:28:43 +0530 Subject: [PATCH 4/6] 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 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 { + 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 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 { #[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 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) { 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 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; From 8f87fcb179421369eee4fdbaae8f25de8a6e9ed7 Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Sat, 20 Aug 2022 13:30:25 +0530 Subject: [PATCH 5/6] remove push_diagnostic methods weren't used in the end --- crates/hir-def/src/nameres.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index a2181a6bf41..45f631936d2 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -511,14 +511,6 @@ impl DefMap { self.diagnostics.as_slice() } - pub fn push_diagnostic(&mut self, d: DefDiagnostic) { - self.diagnostics.push(d) - } - - pub fn push_diagnostics(&mut self, i: impl Iterator) { - self.diagnostics.extend(i) - } - pub fn recursion_limit(&self) -> Option { self.recursion_limit } From 23c00ed50d327918b0f9fb59345ed87cfe7584a9 Mon Sep 17 00:00:00 2001 From: Kartavya Vashishtha Date: Sat, 20 Aug 2022 13:44:01 +0530 Subject: [PATCH 6/6] fix: formatting --- crates/hir-def/src/data.rs | 34 +++++++++++++++++++++++++--------- crates/hir-def/src/db.rs | 5 +++-- crates/hir/src/lib.rs | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 891104cbb37..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, InFile}; +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, diagnostics::DefDiagnostic}, + 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, @@ -213,7 +216,10 @@ impl TraitData { db.trait_data_with_diagnostics(tr).0 } - pub(crate) fn trait_data_with_diagnostics_query(db: &dyn DefDatabase, tr: TraitId) -> (Arc, Arc>) { + 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]; @@ -245,7 +251,7 @@ impl TraitData { visibility, skip_array_during_method_dispatch, }), - Arc::new(diagnostics) + Arc::new(diagnostics), ) } @@ -290,7 +296,10 @@ impl ImplData { db.impl_data_with_diagnostics(id).0 } - pub(crate) fn impl_data_with_diagnostics_query(db: &dyn DefDatabase, id: ImplId) -> (Arc, Arc>) { + 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); @@ -307,7 +316,10 @@ impl ImplData { 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(diagnostics)) + ( + Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls }), + Arc::new(diagnostics), + ) } pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { @@ -477,11 +489,15 @@ impl<'a> AssocItemCollector<'a> { fn finish( self, - ) -> (Vec<(Name, AssocItemId)>, Option, MacroCallId)>>>, Vec) { + ) -> ( + 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 + self.inactive_diagnostics, ) } @@ -497,7 +513,7 @@ impl<'a> AssocItemCollector<'a> { 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() + self.expander.cfg_options().clone(), )); continue; } diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index 2f5ee80cd85..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, diagnostics::DefDiagnostic}, + nameres::{diagnostics::DefDiagnostic, DefMap}, visibility::{self, Visibility}, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, @@ -113,7 +113,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast { 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>); + 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 45bb057d31a..cc9f3180a98 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -531,7 +531,7 @@ 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);