From 12f54eec2745d7e7dca766fd50913d68ebba778d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 26 Feb 2025 07:40:42 +0100 Subject: [PATCH] Split assoc items out of `trait_data`/`impl_data` queries --- crates/hir-def/src/data.rs | 321 +------------------ crates/hir-def/src/db.rs | 25 +- crates/hir-def/src/expr_store/pretty.rs | 2 +- crates/hir-def/src/import_map.rs | 6 +- crates/hir-def/src/lang_item.rs | 4 +- crates/hir-def/src/nameres.rs | 1 + crates/hir-def/src/nameres/assoc.rs | 325 ++++++++++++++++++++ crates/hir-ty/src/autoderef.rs | 2 +- crates/hir-ty/src/chalk_db.rs | 12 +- crates/hir-ty/src/diagnostics/expr.rs | 2 +- crates/hir-ty/src/display.rs | 2 +- crates/hir-ty/src/dyn_compatibility.rs | 4 +- crates/hir-ty/src/infer.rs | 2 +- crates/hir-ty/src/infer/closure.rs | 2 +- crates/hir-ty/src/infer/expr.rs | 8 +- crates/hir-ty/src/infer/mutability.rs | 4 +- crates/hir-ty/src/infer/path.rs | 2 +- crates/hir-ty/src/infer/unify.rs | 2 +- crates/hir-ty/src/lib.rs | 2 +- crates/hir-ty/src/lower.rs | 4 +- crates/hir-ty/src/lower/path.rs | 2 +- crates/hir-ty/src/method_resolution.rs | 24 +- crates/hir-ty/src/mir/eval.rs | 12 +- crates/hir-ty/src/mir/eval/shim.rs | 2 +- crates/hir-ty/src/mir/lower/as_place.rs | 4 +- crates/hir-ty/src/tests.rs | 4 +- crates/hir-ty/src/utils.rs | 2 +- crates/hir/src/attrs.rs | 2 +- crates/hir/src/db.rs | 4 +- crates/hir/src/lib.rs | 37 ++- crates/hir/src/semantics/child_by_source.rs | 4 +- crates/hir/src/source_analyzer.rs | 6 +- crates/hir/src/symbols.rs | 4 +- crates/ide-db/src/apply_change.rs | 4 +- 34 files changed, 446 insertions(+), 397 deletions(-) create mode 100644 crates/hir-def/src/nameres/assoc.rs diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 9c87dc31db..8a1f07c92e 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -3,33 +3,21 @@ pub mod adt; use base_db::Crate; -use hir_expand::{ - name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, -}; +use hir_expand::name::Name; use intern::{sym, Symbol}; use la_arena::{Idx, RawIdx}; -use smallvec::SmallVec; -use syntax::{ast, Parse}; use triomphe::Arc; use tt::iter::TtElement; use crate::{ db::DefDatabase, - expander::{Expander, Mark}, - item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, - macro_call_as_call_id, - nameres::{ - attr_resolution::ResolvedAttr, - diagnostics::{DefDiagnostic, DefDiagnostics}, - proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, - DefMap, LocalDefMap, MacroSubNs, - }, + item_tree::{self, FnFlags, ModItem}, + nameres::proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, path::ImportAlias, type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap}, visibility::RawVisibility, - AssocItemId, AstIdWithPath, ConstId, ConstLoc, ExternCrateId, FunctionId, FunctionLoc, - HasModule, ImplId, Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId, - ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc, + ConstId, ExternCrateId, FunctionId, HasModule, ImplId, ItemContainerId, ItemLoc, Lookup, + Macro2Id, MacroRulesId, ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -256,23 +244,13 @@ bitflags::bitflags! { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraitData { pub name: Name, - pub items: Box<[(Name, AssocItemId)]>, pub flags: TraitFlags, pub visibility: RawVisibility, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, } impl TraitData { #[inline] 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, DefDiagnostics) { let 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]; @@ -317,40 +295,7 @@ impl TraitData { flags |= TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH; } - 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, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(TraitData { name, macro_calls, items, visibility, flags }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn associated_types(&self) -> impl Iterator + '_ { - self.items.iter().filter_map(|(_name, item)| match item { - AssocItemId::TypeAliasId(t) => Some(*t), - _ => None, - }) - } - - pub fn associated_type_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn method_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::FunctionId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() + Arc::new(TraitData { name, visibility, flags }) } } @@ -375,26 +320,16 @@ impl TraitAliasData { pub struct ImplData { pub target_trait: Option, pub self_ty: TypeRefId, - pub items: Box<[(Name, AssocItemId)]>, pub is_negative: bool, pub is_unsafe: bool, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, pub types_map: Arc, } impl ImplData { #[inline] pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc { - db.impl_data_with_diagnostics(id).0 - } - - pub(crate) fn impl_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: ImplId, - ) -> (Arc, DefDiagnostics) { - let _p = tracing::info_span!("impl_data_with_diagnostics_query").entered(); - let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); + let _p = tracing::info_span!("impl_data_query").entered(); + let ItemLoc { id: tree_id, .. } = id.lookup(db); let item_tree = tree_id.item_tree(db); let impl_def = &item_tree[tree_id.value]; @@ -403,28 +338,13 @@ impl ImplData { let is_negative = impl_def.is_negative; let is_unsafe = impl_def.is_unsafe; - let mut collector = - 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, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(ImplData { - target_trait, - self_ty, - items, - is_negative, - is_unsafe, - macro_calls, - types_map: impl_def.types_map.clone(), - }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() + Arc::new(ImplData { + target_trait, + self_ty, + is_negative, + is_unsafe, + types_map: impl_def.types_map.clone(), + }) } } @@ -628,217 +548,6 @@ impl StaticData { } } -struct AssocItemCollector<'a> { - db: &'a dyn DefDatabase, - module_id: ModuleId, - def_map: Arc, - local_def_map: Arc, - diagnostics: Vec, - container: ItemContainerId, - expander: Expander, - - items: Vec<(Name, AssocItemId)>, - macro_calls: Vec<(AstId, MacroCallId)>, -} - -impl<'a> AssocItemCollector<'a> { - fn new( - db: &'a dyn DefDatabase, - module_id: ModuleId, - file_id: HirFileId, - container: ItemContainerId, - ) -> Self { - let (def_map, local_def_map) = module_id.local_def_map(db); - Self { - db, - module_id, - def_map, - local_def_map, - container, - expander: Expander::new(db, file_id, module_id), - items: Vec::new(), - macro_calls: Vec::new(), - diagnostics: Vec::new(), - } - } - - fn finish( - self, - ) -> ( - Box<[(Name, AssocItemId)]>, - Option, MacroCallId)>>>, - Vec, - ) { - ( - self.items.into_boxed_slice(), - if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) }, - self.diagnostics, - ) - } - - fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[AssocItem]) { - let container = self.container; - self.items.reserve(assoc_items.len()); - - '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.diagnostics.push(DefDiagnostic::unconfigured_code( - self.module_id.local_id, - tree_id, - ModItem::from(item).into(), - attrs.cfg().unwrap(), - self.expander.cfg_options().clone(), - )); - continue; - } - - 'attrs: for attr in &*attrs { - let ast_id = - AstId::new(self.expander.current_file_id(), item.ast_id(item_tree).upcast()); - let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; - - match self.def_map.resolve_attr_macro( - &self.local_def_map, - self.db, - self.module_id.local_id, - ast_id_with_path, - attr, - ) { - Ok(ResolvedAttr::Macro(call_id)) => { - let loc = self.db.lookup_intern_macro_call(call_id); - if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind { - // If there's no expander for the proc macro (e.g. the - // proc macro is ignored, or building the proc macro - // crate failed), skip expansion like we would if it was - // disabled. This is analogous to the handling in - // `DefCollector::collect_macros`. - if let Some(err) = exp.as_expand_error(self.module_id.krate) { - self.diagnostics.push(DefDiagnostic::macro_error( - self.module_id.local_id, - ast_id, - (*attr.path).clone(), - err, - )); - continue 'attrs; - } - } - - self.macro_calls.push((ast_id, call_id)); - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.collect_macro_items(res); - continue 'items; - } - Ok(_) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::Attr { - ast_id, - attr_args: None, - invoc_attr_index: attr.id, - }, - attr.path().clone(), - )); - } - } - } - - self.collect_item(item_tree, tree_id, container, item); - } - } - - fn collect_item( - &mut self, - item_tree: &ItemTree, - tree_id: TreeId, - container: ItemContainerId, - item: AssocItem, - ) { - match item { - AssocItem::Function(id) => { - let item = &item_tree[id]; - let def = - FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::TypeAlias(id) => { - let item = &item_tree[id]; - let def = - TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::Const(id) => { - let item = &item_tree[id]; - let Some(name) = item.name.clone() else { return }; - let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((name, def.into())); - } - AssocItem::MacroCall(call) => { - let file_id = self.expander.current_file_id(); - let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call]; - let module = self.expander.module.local_id; - - let resolver = |path: &_| { - self.def_map - .resolve_path( - &self.local_def_map, - self.db, - module, - path, - crate::item_scope::BuiltinShadowMode::Other, - Some(MacroSubNs::Bang), - ) - .0 - .take_macros() - .map(|it| self.db.macro_def(it)) - }; - match macro_call_as_call_id( - self.db.upcast(), - &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), - ctxt, - expand_to, - self.expander.krate(), - resolver, - ) { - Ok(Some(call_id)) => { - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.macro_calls.push((InFile::new(file_id, ast_id.upcast()), call_id)); - self.collect_macro_items(res); - } - Ok(None) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::FnLike { - ast_id: InFile::new(file_id, ast_id), - expand_to, - eager: None, - }, - Clone::clone(path), - )); - } - } - } - } - } - - fn collect_macro_items(&mut self, res: ExpandResult)>>) { - let Some((mark, _parse)) = res.value else { return }; - - let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None); - let item_tree = tree_id.item_tree(self.db); - let iter: SmallVec<[_; 2]> = - item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item).collect(); - - self.collect(&item_tree, tree_id, &iter); - - self.expander.exit(mark); - } -} - fn trait_vis(db: &dyn DefDatabase, trait_id: TraitId) -> RawVisibility { let ItemLoc { id: tree_id, .. } = trait_id.lookup(db); let item_tree = tree_id.item_tree(db); diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index b6707af618..ff33056538 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -20,7 +20,11 @@ use crate::{ import_map::ImportMap, item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, lang_item::{self, LangItem, LangItemTarget, LangItems}, - nameres::{diagnostics::DefDiagnostics, DefMap, LocalDefMap}, + nameres::{ + assoc::{ImplItems, TraitItems}, + diagnostics::DefDiagnostics, + DefMap, LocalDefMap, + }, tt, type_ref::TypesSourceMap, visibility::{self, Visibility}, @@ -176,19 +180,26 @@ pub trait DefDatabase: #[salsa::transparent] #[salsa::invoke_actual(VariantData::variant_data)] fn variant_data(&self, id: VariantId) -> Arc; - #[salsa::transparent] + #[salsa::invoke_actual(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; - #[salsa::invoke_actual(ImplData::impl_data_with_diagnostics_query)] - fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); - #[salsa::transparent] + #[salsa::invoke_actual(ImplItems::impl_items_query)] + fn impl_items(&self, e: ImplId) -> Arc; + + #[salsa::invoke_actual(ImplItems::impl_items_with_diagnostics_query)] + fn impl_items_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); + #[salsa::invoke_actual(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; - #[salsa::invoke_actual(TraitData::trait_data_with_diagnostics_query)] - fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); + #[salsa::transparent] + #[salsa::invoke_actual(TraitItems::trait_items_query)] + fn trait_items(&self, e: TraitId) -> Arc; + + #[salsa::invoke_actual(TraitItems::trait_items_with_diagnostics_query)] + fn trait_items_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); #[salsa::invoke_actual(TraitAliasData::trait_alias_query)] fn trait_alias_data(&self, e: TraitAliasId) -> Arc; diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 82ad756dc2..cc6d200051 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -82,7 +82,7 @@ pub(super) fn print_body_hir( p.buf.push_str(", "); }); // remove the last ", " in param list - if body.params.len() > 0 { + if !body.params.is_empty() { p.buf.truncate(p.buf.len() - 2); } p.buf.push(')'); diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index 1cdc4c0259..9e4479f05b 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -222,7 +222,7 @@ impl ImportMap { trait_import_info: &ImportInfo, ) { let _p = tracing::info_span!("collect_trait_assoc_items").entered(); - for &(ref assoc_item_name, item) in &db.trait_data(tr).items { + for &(ref assoc_item_name, item) in &db.trait_items(tr).items { let module_def_id = match item { AssocItemId::FunctionId(f) => ModuleDefId::from(f), AssocItemId::ConstId(c) => ModuleDefId::from(c), @@ -575,8 +575,8 @@ mod tests { let trait_info = dependency_imports.import_info_for(ItemInNs::Types(trait_id.into()))?; - let trait_data = db.trait_data(trait_id); - let (assoc_item_name, _) = trait_data + let trait_items = db.trait_items(trait_id); + let (assoc_item_name, _) = trait_items .items .iter() .find(|(_, assoc_item_id)| &dependency_assoc_item_id == assoc_item_id)?; diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index 70c28009f4..67788576c1 100644 --- a/crates/hir-def/src/lang_item.rs +++ b/crates/hir-def/src/lang_item.rs @@ -107,7 +107,7 @@ impl LangItems { for (_, module_data) in crate_def_map.modules() { for impl_def in module_data.scope.impls() { lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef); - for &(_, assoc) in db.impl_data(impl_def).items.iter() { + for &(_, assoc) in db.impl_items(impl_def).items.iter() { match assoc { AssocItemId::FunctionId(f) => { lang_items.collect_lang_item(db, f, LangItemTarget::Function) @@ -124,7 +124,7 @@ impl LangItems { match def { ModuleDefId::TraitId(trait_) => { lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait); - db.trait_data(trait_).items.iter().for_each( + db.trait_items(trait_).items.iter().for_each( |&(_, assoc_id)| match assoc_id { AssocItemId::FunctionId(f) => { lang_items.collect_lang_item(db, f, LangItemTarget::Function); diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 054c285fa2..a34766ebc1 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -47,6 +47,7 @@ //! path and, upon success, we run macro expansion and "collect module" phase on //! the result +pub mod assoc; pub mod attr_resolution; mod collector; pub mod diagnostics; diff --git a/crates/hir-def/src/nameres/assoc.rs b/crates/hir-def/src/nameres/assoc.rs new file mode 100644 index 0000000000..dea6d334f8 --- /dev/null +++ b/crates/hir-def/src/nameres/assoc.rs @@ -0,0 +1,325 @@ +//! Expansion of associated items + +use hir_expand::{ + name::Name, AstId, ExpandResult, InFile, Intern, Lookup, MacroCallKind, MacroDefKind, +}; +use smallvec::SmallVec; +use span::{HirFileId, MacroCallId}; +use syntax::{ast, Parse}; +use triomphe::Arc; + +use crate::{ + db::DefDatabase, + expander::{Expander, Mark}, + item_tree::{self, AssocItem, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, + macro_call_as_call_id, + nameres::{ + attr_resolution::ResolvedAttr, + diagnostics::{DefDiagnostic, DefDiagnostics}, + DefMap, LocalDefMap, MacroSubNs, + }, + AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId, + ItemLoc, ModuleId, TraitId, TypeAliasId, TypeAliasLoc, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitItems { + pub items: Box<[(Name, AssocItemId)]>, + // box it as the vec is usually empty anyways + pub macro_calls: Option, MacroCallId)>>>, +} + +impl TraitItems { + #[inline] + pub(crate) fn trait_items_query(db: &dyn DefDatabase, tr: TraitId) -> Arc { + db.trait_items_with_diagnostics(tr).0 + } + + pub(crate) fn trait_items_with_diagnostics_query( + db: &dyn DefDatabase, + tr: TraitId, + ) -> (Arc, DefDiagnostics) { + let 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]; + + 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, macro_calls, diagnostics) = collector.finish(); + + (Arc::new(TraitItems { macro_calls, items }), DefDiagnostics::new(diagnostics)) + } + + pub fn associated_types(&self) -> impl Iterator + '_ { + self.items.iter().filter_map(|(_name, item)| match item { + AssocItemId::TypeAliasId(t) => Some(*t), + _ => None, + }) + } + + pub fn associated_type_by_name(&self, name: &Name) -> Option { + self.items.iter().find_map(|(item_name, item)| match item { + AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), + _ => None, + }) + } + + pub fn method_by_name(&self, name: &Name) -> Option { + self.items.iter().find_map(|(item_name, item)| match item { + AssocItemId::FunctionId(t) if item_name == name => Some(*t), + _ => None, + }) + } + + pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + self.macro_calls.iter().flat_map(|it| it.iter()).copied() + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ImplItems { + pub items: Box<[(Name, AssocItemId)]>, + // box it as the vec is usually empty anyways + pub macro_calls: Option, MacroCallId)>>>, +} + +impl ImplItems { + #[inline] + pub(crate) fn impl_items_query(db: &dyn DefDatabase, id: ImplId) -> Arc { + db.impl_items_with_diagnostics(id).0 + } + + pub(crate) fn impl_items_with_diagnostics_query( + db: &dyn DefDatabase, + id: ImplId, + ) -> (Arc, DefDiagnostics) { + let _p = tracing::info_span!("impl_items_with_diagnostics_query").entered(); + let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); + + let item_tree = tree_id.item_tree(db); + let impl_def = &item_tree[tree_id.value]; + let mut collector = + 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, macro_calls, diagnostics) = collector.finish(); + + (Arc::new(ImplItems { items, macro_calls }), DefDiagnostics::new(diagnostics)) + } + + pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + self.macro_calls.iter().flat_map(|it| it.iter()).copied() + } +} + +struct AssocItemCollector<'a> { + db: &'a dyn DefDatabase, + module_id: ModuleId, + def_map: Arc, + local_def_map: Arc, + diagnostics: Vec, + container: ItemContainerId, + expander: Expander, + + items: Vec<(Name, AssocItemId)>, + macro_calls: Vec<(AstId, MacroCallId)>, +} + +impl<'a> AssocItemCollector<'a> { + fn new( + db: &'a dyn DefDatabase, + module_id: ModuleId, + file_id: HirFileId, + container: ItemContainerId, + ) -> Self { + let (def_map, local_def_map) = module_id.local_def_map(db); + Self { + db, + module_id, + def_map, + local_def_map, + container, + expander: Expander::new(db, file_id, module_id), + items: Vec::new(), + macro_calls: Vec::new(), + diagnostics: Vec::new(), + } + } + + fn finish( + self, + ) -> ( + Box<[(Name, AssocItemId)]>, + Option, MacroCallId)>>>, + Vec, + ) { + ( + self.items.into_boxed_slice(), + if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) }, + self.diagnostics, + ) + } + + fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[AssocItem]) { + let container = self.container; + self.items.reserve(assoc_items.len()); + + '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.diagnostics.push(DefDiagnostic::unconfigured_code( + self.module_id.local_id, + tree_id, + ModItem::from(item).into(), + attrs.cfg().unwrap(), + self.expander.cfg_options().clone(), + )); + continue; + } + + 'attrs: for attr in &*attrs { + let ast_id = + AstId::new(self.expander.current_file_id(), item.ast_id(item_tree).upcast()); + let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; + + match self.def_map.resolve_attr_macro( + &self.local_def_map, + self.db, + self.module_id.local_id, + ast_id_with_path, + attr, + ) { + Ok(ResolvedAttr::Macro(call_id)) => { + let loc = self.db.lookup_intern_macro_call(call_id); + if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind { + // If there's no expander for the proc macro (e.g. the + // proc macro is ignored, or building the proc macro + // crate failed), skip expansion like we would if it was + // disabled. This is analogous to the handling in + // `DefCollector::collect_macros`. + if let Some(err) = exp.as_expand_error(self.module_id.krate) { + self.diagnostics.push(DefDiagnostic::macro_error( + self.module_id.local_id, + ast_id, + (*attr.path).clone(), + err, + )); + continue 'attrs; + } + } + + self.macro_calls.push((ast_id, call_id)); + let res = + self.expander.enter_expand_id::(self.db, call_id); + self.collect_macro_items(res); + continue 'items; + } + Ok(_) => (), + Err(_) => { + self.diagnostics.push(DefDiagnostic::unresolved_macro_call( + self.module_id.local_id, + MacroCallKind::Attr { + ast_id, + attr_args: None, + invoc_attr_index: attr.id, + }, + attr.path().clone(), + )); + } + } + } + + self.collect_item(item_tree, tree_id, container, item); + } + } + + fn collect_item( + &mut self, + item_tree: &ItemTree, + tree_id: TreeId, + container: ItemContainerId, + item: AssocItem, + ) { + match item { + AssocItem::Function(id) => { + let item = &item_tree[id]; + let def = + FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((item.name.clone(), def.into())); + } + AssocItem::TypeAlias(id) => { + let item = &item_tree[id]; + let def = + TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((item.name.clone(), def.into())); + } + AssocItem::Const(id) => { + let item = &item_tree[id]; + let Some(name) = item.name.clone() else { return }; + let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); + self.items.push((name, def.into())); + } + AssocItem::MacroCall(call) => { + let file_id = self.expander.current_file_id(); + let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call]; + let module = self.expander.module.local_id; + + let resolver = |path: &_| { + self.def_map + .resolve_path( + &self.local_def_map, + self.db, + module, + path, + crate::item_scope::BuiltinShadowMode::Other, + Some(MacroSubNs::Bang), + ) + .0 + .take_macros() + .map(|it| self.db.macro_def(it)) + }; + match macro_call_as_call_id( + self.db.upcast(), + &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), + ctxt, + expand_to, + self.expander.krate(), + resolver, + ) { + Ok(Some(call_id)) => { + let res = + self.expander.enter_expand_id::(self.db, call_id); + self.macro_calls.push((InFile::new(file_id, ast_id.upcast()), call_id)); + self.collect_macro_items(res); + } + Ok(None) => (), + Err(_) => { + self.diagnostics.push(DefDiagnostic::unresolved_macro_call( + self.module_id.local_id, + MacroCallKind::FnLike { + ast_id: InFile::new(file_id, ast_id), + expand_to, + eager: None, + }, + Clone::clone(path), + )); + } + } + } + } + } + + fn collect_macro_items(&mut self, res: ExpandResult)>>) { + let Some((mark, _parse)) = res.value else { return }; + + let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None); + let item_tree = tree_id.item_tree(self.db); + let iter: SmallVec<[_; 2]> = + item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item).collect(); + + self.collect(&item_tree, tree_id, &iter); + + self.expander.exit(mark); + } +} diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs index 171ba001c4..2c27f5e3bb 100644 --- a/crates/hir-ty/src/autoderef.rs +++ b/crates/hir-ty/src/autoderef.rs @@ -210,7 +210,7 @@ pub(crate) fn deref_by_trait( }; let trait_id = trait_id()?; let target = db - .trait_data(trait_id) + .trait_items(trait_id) .associated_type_by_name(&Name::new_symbol_root(sym::Target.clone()))?; let projection = { diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index 84eb964d56..e5751a394d 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -294,7 +294,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { .lang_item(self.krate, LangItem::Future) .and_then(|item| item.as_trait()) .and_then(|trait_| { - let alias = self.db.trait_data(trait_).associated_type_by_name( + let alias = self.db.trait_items(trait_).associated_type_by_name( &Name::new_symbol_root(sym::Output.clone()), )?; Some((trait_, alias)) @@ -684,7 +684,8 @@ pub(crate) fn trait_datum_query( fundamental: trait_data.flags.contains(TraitFlags::IS_FUNDAMENTAL), }; let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); - let associated_ty_ids = trait_data.associated_types().map(to_assoc_type_id).collect(); + let associated_ty_ids = + db.trait_items(trait_).associated_types().map(to_assoc_type_id).collect(); let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; let well_known = db.lang_attr(trait_.into()).and_then(well_known_trait_from_lang_item); let trait_datum = TraitDatum { @@ -856,8 +857,9 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId) let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; let impl_datum_bound = rust_ir::ImplDatumBound { trait_ref, where_clauses }; - let trait_data = db.trait_data(trait_); - let associated_ty_value_ids = impl_data + let trait_data = db.trait_items(trait_); + let associated_ty_value_ids = db + .impl_items(impl_id) .items .iter() .filter_map(|(_, item)| match item { @@ -908,7 +910,7 @@ fn type_alias_associated_ty_value( .0; // we don't return any assoc ty values if the impl'd trait can't be resolved let assoc_ty = db - .trait_data(trait_ref.hir_trait_id()) + .trait_items(trait_ref.hir_trait_id()) .associated_type_by_name(&type_alias_data.name) .expect("assoc ty value should not exist"); // validated when building the impl data as well let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders(); diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index 053d1cd41e..1035651692 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -492,7 +492,7 @@ impl FilterMapNextChecker { Some(next_function_id), match next_function_id.lookup(db.upcast()).container { ItemContainerId::TraitId(iterator_trait_id) => { - let iterator_trait_items = &db.trait_data(iterator_trait_id).items; + let iterator_trait_items = &db.trait_items(iterator_trait_id).items; iterator_trait_items.iter().find_map(|(name, it)| match it { &AssocItemId::FunctionId(id) if *name == sym::filter_map.clone() => { Some(id) diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 2ae7e746ba..be590b6101 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -1342,7 +1342,7 @@ impl HirDisplay for Ty { .lang_item(body.module(db.upcast()).krate(), LangItem::Future) .and_then(LangItemTarget::as_trait); let output = future_trait.and_then(|t| { - db.trait_data(t).associated_type_by_name(&Name::new_symbol_root( + db.trait_items(t).associated_type_by_name(&Name::new_symbol_root( sym::Output.clone(), )) }); diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 6a01579bcc..af16a2499b 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -103,7 +103,7 @@ where // rustc checks for non-lifetime binders here, but we don't support HRTB yet - let trait_data = db.trait_data(trait_); + let trait_data = db.trait_items(trait_); for (_, assoc_item) in &trait_data.items { dyn_compatibility_violation_for_assoc_item(db, trait_, *assoc_item, cb)?; } @@ -166,7 +166,7 @@ fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool { // Same as the above, `predicates_reference_self` fn bounds_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool { - let trait_data = db.trait_data(trait_); + let trait_data = db.trait_items(trait_); trait_data .items .iter() diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 556091c404..9a4b7af85d 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -1723,7 +1723,7 @@ impl<'a> InferenceContext<'a> { fn resolve_output_on(&self, trait_: TraitId) -> Option { self.db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone())) } diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 50cac034e4..ef02762c80 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -815,7 +815,7 @@ impl InferenceContext<'_> { { if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { break 'b deref_fn == f; diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 131e98d729..d093618595 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -772,7 +772,7 @@ impl InferenceContext<'_> { if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref) { if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref.clone())) { // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that @@ -930,7 +930,7 @@ impl InferenceContext<'_> { self.write_expr_adj(*base, adj); if let Some(func) = self .db - .trait_data(index_trait) + .trait_items(index_trait) .method_by_name(&Name::new_symbol_root(sym::index.clone())) { let subst = TyBuilder::subst_for_def(self.db, index_trait, None); @@ -1258,7 +1258,7 @@ impl InferenceContext<'_> { let Some(trait_) = fn_x.get_id(self.db, self.table.trait_env.krate) else { return; }; - let trait_data = self.db.trait_data(trait_); + let trait_data = self.db.trait_items(trait_); if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) { let subst = TyBuilder::subst_for_def(self.db, trait_, None) .push(callee_ty.clone()) @@ -1426,7 +1426,7 @@ impl InferenceContext<'_> { let trait_func = lang_items_for_bin_op(op).and_then(|(name, lang_item)| { let trait_id = self.resolve_lang_item(lang_item)?.as_trait()?; - let func = self.db.trait_data(trait_id).method_by_name(&name)?; + let func = self.db.trait_items(trait_id).method_by_name(&name)?; Some((trait_id, func)) }); let (trait_, func) = match trait_func { diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs index d74a383f44..96d84cad93 100644 --- a/crates/hir-ty/src/infer/mutability.rs +++ b/crates/hir-ty/src/infer/mutability.rs @@ -134,7 +134,7 @@ impl InferenceContext<'_> { { if let Some(index_fn) = self .db - .trait_data(index_trait) + .trait_items(index_trait) .method_by_name(&Name::new_symbol_root(sym::index_mut.clone())) { *f = index_fn; @@ -201,7 +201,7 @@ impl InferenceContext<'_> { mutability = Mutability::Not; } else if let Some(deref_fn) = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { *f = deref_fn; diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index 6254bc1239..29f455a61b 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -277,7 +277,7 @@ impl InferenceContext<'_> { ) -> Option<(ValueNs, Substitution)> { let trait_ = trait_ref.hir_trait_id(); let item = - self.db.trait_data(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| { + self.db.trait_items(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| { match item { AssocItemId::FunctionId(func) => { if segment.name == &self.db.function_data(func).name { diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index 8a8992cf37..a9332a5a96 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -801,7 +801,7 @@ impl<'a> InferenceTable<'a> { ] { let krate = self.trait_env.krate; let fn_trait = fn_trait_name.get_id(self.db, krate)?; - let trait_data = self.db.trait_data(fn_trait); + let trait_data = self.db.trait_items(fn_trait); let output_assoc_type = trait_data.associated_type_by_name(&Name::new_symbol_root(output_assoc_name))?; diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index f35298846a..836319431d 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -906,7 +906,7 @@ pub fn callable_sig_from_fn_trait( let krate = trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; let output_assoc_type = db - .trait_data(fn_once_trait) + .trait_items(fn_once_trait) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; let mut table = InferenceTable::new(db, trait_env.clone()); diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 29ab0251f8..33e852aaee 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -898,7 +898,7 @@ fn named_associated_type_shorthand_candidates( ) -> Option { let mut search = |t| { all_super_trait_refs(db, t, |t| { - let data = db.trait_data(t.hir_trait_id()); + let data = db.trait_items(t.hir_trait_id()); for (name, assoc_id) in &data.items { if let AssocItemId::TypeAliasId(alias) = assoc_id { @@ -1068,7 +1068,7 @@ pub(crate) fn generic_predicates_for_param_query( }; all_super_traits(db.upcast(), tr).iter().any(|tr| { - db.trait_data(*tr).items.iter().any(|(name, item)| { + db.trait_items(*tr).items.iter().any(|(name, item)| { matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name }) }) diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs index a165932ddc..a9e9e83e87 100644 --- a/crates/hir-ty/src/lower/path.rs +++ b/crates/hir-ty/src/lower/path.rs @@ -169,7 +169,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { self.skip_resolved_segment(); let segment = self.current_or_prev_segment; let found = - self.ctx.db.trait_data(trait_).associated_type_by_name(segment.name); + self.ctx.db.trait_items(trait_).associated_type_by_name(segment.name); match found { Some(associated_ty) => { diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 50b0fce62f..bb3aaef20b 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -8,8 +8,8 @@ use arrayvec::ArrayVec; use base_db::Crate; use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; use hir_def::{ - data::{adt::StructFlags, ImplData, TraitFlags}, - nameres::DefMap, + data::{adt::StructFlags, TraitFlags}, + nameres::{assoc::ImplItems, DefMap}, AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId, }; @@ -325,7 +325,7 @@ impl InherentImpls { let self_ty = db.impl_self_ty(impl_id); let self_ty = self_ty.skip_binders(); - match is_inherent_impl_coherent(db, def_map, &data, self_ty) { + match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) { true => { // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution) if let Some(fp) = TyFingerprint::for_inherent_impl(self_ty) { @@ -765,11 +765,10 @@ fn find_matching_impl( mut impls: impl Iterator, mut table: InferenceTable<'_>, actual_trait_ref: TraitRef, -) -> Option<(Arc, Substitution)> { +) -> Option<(Arc, Substitution)> { let db = table.db; impls.find_map(|impl_| { table.run_in_snapshot(|table| { - let impl_data = db.impl_data(impl_); let impl_substs = TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build(); let trait_ref = db @@ -787,7 +786,7 @@ fn find_matching_impl( let goal = crate::Goal::all(Interner, wcs); table.try_obligation(goal.clone())?; table.register_obligation(goal); - Some((impl_data, table.resolve_completely(impl_substs))) + Some((db.impl_items(impl_), table.resolve_completely(impl_substs))) }) }) } @@ -795,7 +794,7 @@ fn find_matching_impl( fn is_inherent_impl_coherent( db: &dyn HirDatabase, def_map: &DefMap, - impl_data: &ImplData, + impl_id: ImplId, self_ty: &Ty, ) -> bool { let self_ty = self_ty.kind(Interner); @@ -848,9 +847,10 @@ fn is_inherent_impl_coherent( _ => false, }; + let items = db.impl_items(impl_id); rustc_has_incoherent_inherent_impls - && !impl_data.items.is_empty() - && impl_data.items.iter().all(|&(_, assoc)| match assoc { + && !items.items.is_empty() + && items.items.iter().all(|&(_, assoc)| match assoc { AssocItemId::FunctionId(it) => db.function_data(it).rustc_allow_incoherent_impl, AssocItemId::ConstId(it) => db.const_data(it).rustc_allow_incoherent_impl, AssocItemId::TypeAliasId(it) => db.type_alias_data(it).rustc_allow_incoherent_impl, @@ -1241,7 +1241,7 @@ fn iterate_trait_method_candidates( // trait, but if we find out it doesn't, we'll skip the rest of the // iteration let mut known_implemented = false; - for &(_, item) in data.items.iter() { + for &(_, item) in db.trait_items(t).items.iter() { // Don't pass a `visible_from_module` down to `is_valid_candidate`, // since only inherent methods should be included into visibility checking. let visible = @@ -1368,7 +1368,7 @@ fn iterate_inherent_methods( ) -> ControlFlow<()> { let db = table.db; for t in traits { - let data = db.trait_data(t); + let data = db.trait_items(t); for &(_, item) in data.items.iter() { // We don't pass `visible_from_module` as all trait items should be visible. let visible = match is_valid_trait_method_candidate( @@ -1401,7 +1401,7 @@ fn iterate_inherent_methods( callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()> { for &impl_id in impls.for_self_ty(self_ty) { - for &(ref item_name, item) in table.db.impl_data(impl_id).items.iter() { + for &(ref item_name, item) in table.db.impl_items(impl_id).items.iter() { let visible = match is_valid_impl_method_candidate( table, self_ty, diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 597e6a3ef0..97710aab06 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -661,19 +661,19 @@ impl Evaluator<'_> { .lang_item(crate_id, LangItem::Fn) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call.clone())) }), cached_fn_mut_trait_func: db .lang_item(crate_id, LangItem::FnMut) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone())) }), cached_fn_once_trait_func: db .lang_item(crate_id, LangItem::FnOnce) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone())) + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }), }) } @@ -2818,7 +2818,9 @@ impl Evaluator<'_> { ) -> Result<()> { let Some(drop_fn) = (|| { let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?; - self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop.clone())) + self.db + .trait_items(drop_trait) + .method_by_name(&Name::new_symbol_root(sym::drop.clone())) })() else { // in some tests we don't have drop trait in minicore, and // we can ignore drop in them. @@ -2928,7 +2930,7 @@ pub fn render_const_using_debug_impl( not_supported!("core::fmt::Debug not found"); }; let Some(debug_fmt_fn) = - db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone())) + db.trait_items(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone())) else { not_supported!("core::fmt::Debug::fmt not found"); }; diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 346dea8252..edd028cdeb 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -1261,7 +1261,7 @@ impl Evaluator<'_> { if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) { if let Some(def) = target.as_trait().and_then(|it| { self.db - .trait_data(it) + .trait_items(it) .method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }) { self.exec_fn_trait( diff --git a/crates/hir-ty/src/mir/lower/as_place.rs b/crates/hir-ty/src/mir/lower/as_place.rs index 420f2aaff4..7b0ee22d51 100644 --- a/crates/hir-ty/src/mir/lower/as_place.rs +++ b/crates/hir-ty/src/mir/lower/as_place.rs @@ -195,7 +195,7 @@ impl MirLowerCtx<'_> { self.resolve_lang_item(LangItem::DerefMut)?.as_trait() { if let Some(deref_fn) = - self.db.trait_data(deref_trait).method_by_name( + self.db.trait_items(deref_trait).method_by_name( &Name::new_symbol_root(sym::deref_mut.clone()), ) { @@ -353,7 +353,7 @@ impl MirLowerCtx<'_> { .ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?; let deref_fn = self .db - .trait_data(deref_trait) + .trait_items(deref_trait) .method_by_name(&trait_method_name) .ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?; let deref_fn_op = Operand::const_zst( diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs index cdb9e9edf8..9ad07922fa 100644 --- a/crates/hir-ty/src/tests.rs +++ b/crates/hir-ty/src/tests.rs @@ -439,7 +439,7 @@ pub(crate) fn visit_module( ) { visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb); for impl_id in crate_def_map[module_id].scope.impls() { - let impl_data = db.impl_data(impl_id); + let impl_data = db.impl_items(impl_id); for &(_, item) in impl_data.items.iter() { match item { AssocItemId::FunctionId(it) => { @@ -488,7 +488,7 @@ pub(crate) fn visit_module( }); } ModuleDefId::TraitId(it) => { - let trait_data = db.trait_data(it); + let trait_data = db.trait_items(it); for &(_, item) in trait_data.items.iter() { match item { AssocItemId::FunctionId(it) => cb(it.into()), diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index b90f4e4d7f..cbb78ef40d 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -226,7 +226,7 @@ pub(super) fn associated_type_by_name_including_super_traits( name: &Name, ) -> Option<(TraitRef, TypeAliasId)> { all_super_trait_refs(db, trait_ref, |t| { - let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?; + let assoc_type = db.trait_items(t.hir_trait_id()).associated_type_by_name(name)?; Some((t, assoc_type)) }) } diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 4351a34e82..1c88e79933 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -194,7 +194,7 @@ fn resolve_assoc_or_field( // Doc paths in this context may only resolve to an item of this trait // (i.e. no items of its supertraits), so we need to handle them here // independently of others. - return db.trait_data(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| { + return db.trait_items(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| { let def = match *assoc_id { AssocItemId::FunctionId(it) => ModuleDef::Function(it.into()), AssocItemId::ConstId(it) => ModuleDef::Const(it.into()), diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs index 9e8e87ecff..64d97b3f2a 100644 --- a/crates/hir/src/db.rs +++ b/crates/hir/src/db.rs @@ -11,7 +11,7 @@ pub use hir_def::db::DefDatabase; // ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery, // FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery, // FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery, -// GenericParamsWithSourceMapQuery, ImplDataWithDiagnosticsQuery, ImportMapQuery, +// GenericParamsWithSourceMapQuery, ImplItemsWithDiagnosticsQuery, ImportMapQuery, // IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery, // InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery, // InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery, @@ -19,7 +19,7 @@ pub use hir_def::db::DefDatabase; // InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery, // InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery, // MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery, -// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitDataWithDiagnosticsQuery, +// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitItemsWithDiagnosticsQuery, // TypeAliasDataQuery, UnionDataWithDiagnosticsQuery, // }; pub use hir_expand::db::ExpandDatabase; diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5da2b5ed09..5cc330fb38 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -636,7 +636,7 @@ impl Module { acc.extend(def.diagnostics(db, style_lints)) } ModuleDef::Trait(t) => { - for diag in db.trait_data_with_diagnostics(t.id).1.iter() { + for diag in db.trait_items_with_diagnostics(t.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -743,7 +743,7 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); - for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() { + for diag in db.impl_items_with_diagnostics(impl_def.id).1.iter() { emit_def_diagnostic(db, acc, diag, edition); } @@ -801,13 +801,13 @@ impl Module { // Negative impls can't have items, don't emit missing items diagnostic for them if let (false, Some(trait_)) = (impl_is_negative, trait_) { - let items = &db.trait_data(trait_.into()).items; + let items = &db.trait_items(trait_.into()).items; let required_items = items.iter().filter(|&(_, assoc)| match *assoc { AssocItemId::FunctionId(it) => !db.function_data(it).has_body(), AssocItemId::ConstId(id) => !db.const_data(id).has_body, AssocItemId::TypeAliasId(it) => db.type_alias_data(it).type_ref.is_none(), }); - impl_assoc_items_scratch.extend(db.impl_data(impl_def.id).items.iter().cloned()); + impl_assoc_items_scratch.extend(db.impl_items(impl_def.id).items.iter().cloned()); let redundant = impl_assoc_items_scratch .iter() @@ -863,7 +863,7 @@ impl Module { source_map, ); - for &(_, item) in db.impl_data(impl_def.id).items.iter() { + for &(_, item) in db.impl_items(impl_def.id).items.iter() { AssocItem::from(item).diagnostics(db, acc, style_lints); } } @@ -2868,16 +2868,15 @@ impl Trait { } pub fn function(self, db: &dyn HirDatabase, name: impl PartialEq) -> Option { - db.trait_data(self.id).items.iter().find(|(n, _)| name == *n).and_then( - |&(_, it)| match it { - AssocItemId::FunctionId(id) => Some(Function { id }), - _ => None, - }, - ) + db.trait_items(self.id).items.iter().find(|(n, _)| name == *n).and_then(|&(_, it)| match it + { + AssocItemId::FunctionId(id) => Some(Function { id }), + _ => None, + }) } pub fn items(self, db: &dyn HirDatabase) -> Vec { - db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() + db.trait_items(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec { @@ -2921,7 +2920,7 @@ impl Trait { } fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId, MacroCallId)]> { - db.trait_data(self.id) + db.trait_items(self.id) .macro_calls .as_ref() .map(|it| it.as_ref().clone().into_boxed_slice()) @@ -4428,7 +4427,7 @@ impl Impl { } pub fn items(self, db: &dyn HirDatabase) -> Vec { - db.impl_data(self.id).items.iter().map(|&(_, it)| it.into()).collect() + db.impl_items(self.id).items.iter().map(|&(_, it)| it.into()).collect() } pub fn is_negative(self, db: &dyn HirDatabase) -> bool { @@ -4478,7 +4477,7 @@ impl Impl { } fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId, MacroCallId)]> { - db.impl_data(self.id) + db.impl_items(self.id) .macro_calls .as_ref() .map(|it| it.as_ref().clone().into_boxed_slice()) @@ -4959,7 +4958,7 @@ impl Type { } let output_assoc_type = db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; self.normalize_trait_assoc_type(db, &[], output_assoc_type.into()) } @@ -4975,7 +4974,7 @@ impl Type { pub fn iterator_item(self, db: &dyn HirDatabase) -> Option { let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?; let iterator_item = db - .trait_data(iterator_trait) + .trait_items(iterator_trait) .associated_type_by_name(&Name::new_symbol_root(sym::Item.clone()))?; self.normalize_trait_assoc_type(db, &[], iterator_item.into()) } @@ -5007,7 +5006,7 @@ impl Type { } let into_iter_assoc_type = db - .trait_data(trait_) + .trait_items(trait_) .associated_type_by_name(&Name::new_symbol_root(sym::IntoIter.clone()))?; self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.into()) } @@ -5301,7 +5300,7 @@ impl Type { let impls = db.inherent_impls_in_crate(krate); for impl_def in impls.for_self_ty(&self.ty) { - for &(_, item) in db.impl_data(*impl_def).items.iter() { + for &(_, item) in db.impl_items(*impl_def).items.iter() { if callback(item) { return; } diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index da9bb8b15c..556b21124d 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -34,7 +34,7 @@ pub(crate) trait ChildBySource { impl ChildBySource for TraitId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let data = db.trait_data(*self); + let data = db.trait_items(*self); data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { @@ -49,7 +49,7 @@ impl ChildBySource for TraitId { impl ChildBySource for ImplId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let data = db.impl_data(*self); + let data = db.impl_items(*self); // FIXME: Macro calls data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index aa0eac9478..e390fb0b93 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -1291,7 +1291,7 @@ impl SourceAnalyzer { method_name: &Name, ) -> Option<(TraitId, FunctionId)> { let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?; - let fn_id = db.trait_data(trait_id).method_by_name(method_name)?; + let fn_id = db.trait_items(trait_id).method_by_name(method_name)?; Some((trait_id, fn_id)) } @@ -1453,7 +1453,7 @@ fn resolve_hir_path_( // within the trait's associated types. if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) { if let Some(type_alias_id) = - db.trait_data(trait_id).associated_type_by_name(unresolved.name) + db.trait_items(trait_id).associated_type_by_name(unresolved.name) { return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into())); } @@ -1586,7 +1586,7 @@ fn resolve_hir_path_qualifier( // within the trait's associated types. if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) { if let Some(type_alias_id) = - db.trait_data(trait_id).associated_type_by_name(unresolved.name) + db.trait_items(trait_id).associated_type_by_name(unresolved.name) { return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into())); } diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index 2a6c15207a..853df7ee2d 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -313,7 +313,7 @@ impl<'a> SymbolCollector<'a> { .to_smolstr(), ); self.with_container_name(impl_name, |s| { - for &(ref name, assoc_item_id) in &impl_data.items { + for &(ref name, assoc_item_id) in &self.db.impl_items(impl_id).items { s.push_assoc_item(assoc_item_id, name) } }) @@ -322,7 +322,7 @@ impl<'a> SymbolCollector<'a> { fn collect_from_trait(&mut self, trait_id: TraitId) { let trait_data = self.db.trait_data(trait_id); self.with_container_name(Some(trait_data.name.as_str().into()), |s| { - for &(ref name, assoc_item_id) in &trait_data.items { + for &(ref name, assoc_item_id) in &self.db.trait_items(trait_id).items { s.push_assoc_item(assoc_item_id, name); } }); diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs index 4c8940db95..6b08ada34b 100644 --- a/crates/ide-db/src/apply_change.rs +++ b/crates/ide-db/src/apply_change.rs @@ -162,7 +162,7 @@ impl RootDatabase { // hir::db::FunctionVisibilityQuery // hir::db::GenericParamsQuery // hir::db::GenericParamsWithSourceMapQuery - // hir::db::ImplDataWithDiagnosticsQuery + // hir::db::ImplItemsWithDiagnosticsQuery // hir::db::ImportMapQuery // hir::db::IncludeMacroInvocQuery // hir::db::InternAnonymousConstQuery @@ -193,7 +193,7 @@ impl RootDatabase { // hir::db::StaticDataQuery // hir::db::StructDataWithDiagnosticsQuery // hir::db::TraitAliasDataQuery - // hir::db::TraitDataWithDiagnosticsQuery + // hir::db::TraitItemsWithDiagnosticsQuery // hir::db::TypeAliasDataQuery // hir::db::UnionDataWithDiagnosticsQuery