From 45d05ed78384b28fbd341068f36912a2e0308292 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 15:27:33 +0300 Subject: id-ify impls_in_crate_query --- crates/ra_hir/src/code_model.rs | 9 +++ crates/ra_hir/src/db.rs | 4 +- crates/ra_hir/src/ty/method_resolution.rs | 101 ++++++++++++++++-------------- crates/ra_hir/src/ty/primitive.rs | 2 +- crates/ra_hir/src/ty/traits.rs | 4 +- crates/ra_ide_api/src/impls.rs | 10 +-- 6 files changed, 74 insertions(+), 56 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index bb1596bed..821f919d4 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -997,6 +997,15 @@ pub struct ImplBlock { } impl ImplBlock { + pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec { + let impls = db.impls_in_crate(krate.crate_id); + impls.all_impls().map(Self::from).collect() + } + pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec { + let impls = db.impls_in_crate(krate.crate_id); + impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() + } + pub fn target_trait(&self, db: &impl DefDatabase) -> Option { db.impl_data(self.id).target_trait.clone() } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index b034d4e44..32f05a4d8 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use ra_arena::map::ArenaMap; -use ra_db::salsa; +use ra_db::{salsa, CrateId}; use crate::{ ty::{ @@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase { fn generic_defaults(&self, def: GenericDefId) -> Substs; #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] - fn impls_in_crate(&self, krate: Crate) -> Arc; + fn impls_in_crate(&self, krate: CrateId) -> Arc; #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7f0ff2e8c..489fcd64b 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -5,14 +5,19 @@ use std::sync::Arc; use arrayvec::ArrayVec; -use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; +use hir_def::{ + lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, + HasModule, ImplId, TraitId, +}; +use ra_db::CrateId; +use ra_prof::profile; use rustc_hash::FxHashMap; use crate::{ db::HirDatabase, ty::primitive::{FloatBitness, Uncertain}, ty::{Ty, TypeCtor}, - AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, + AssocItem, Crate, Function, Mutability, Name, Trait, }; use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; @@ -37,54 +42,58 @@ impl TyFingerprint { #[derive(Debug, PartialEq, Eq)] pub struct CrateImplBlocks { - impls: FxHashMap>, - impls_by_trait: FxHashMap>, + impls: FxHashMap>, + impls_by_trait: FxHashMap>, } impl CrateImplBlocks { pub(crate) fn impls_in_crate_query( db: &impl HirDatabase, - krate: Crate, + krate: CrateId, ) -> Arc { - let mut crate_impl_blocks = + let _p = profile("impls_in_crate_query"); + let mut res = CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; - if let Some(module) = krate.root_module(db) { - crate_impl_blocks.collect_recursive(db, module); + + let crate_def_map = db.crate_def_map(krate); + for (_module_id, module_data) in crate_def_map.modules.iter() { + for &impl_id in module_data.impls.iter() { + let impl_data = db.impl_data(impl_id); + let resolver = impl_id.resolver(db); + + let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; + + match &impl_data.target_trait { + Some(trait_ref) => { + if let Some(tr) = + TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) + { + res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); + } + } + None => { + if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { + res.impls.entry(target_ty_fp).or_default().push(impl_id); + } + } + } + } } - Arc::new(crate_impl_blocks) + + Arc::new(res) } - pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator + '_ { + pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator + '_ { let fingerprint = TyFingerprint::for_impl(ty); fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() } - pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator + '_ { - self.impls_by_trait.get(&tr).into_iter().flatten().copied() + pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator + '_ { + self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() } - pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { + pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() } - - fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { - for impl_block in module.impl_blocks(db) { - let target_ty = impl_block.target_ty(db); - - if impl_block.target_trait(db).is_some() { - if let Some(tr) = impl_block.target_trait_ref(db) { - self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); - } - } else { - if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { - self.impls.entry(target_ty_fp).or_default().push(impl_block); - } - } - } - - for child in module.children(db) { - self.collect_recursive(db, child); - } - } } fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option> { @@ -279,14 +288,14 @@ fn iterate_inherent_methods( mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &ty.value)? { - let impls = db.impls_in_crate(krate); + let impls = db.impls_in_crate(krate.crate_id); for impl_block in impls.lookup_impl_blocks(&ty.value) { - for item in impl_block.items(db) { + for &item in db.impl_data(impl_block).items.iter() { if !is_valid_candidate(db, name, mode, item) { continue; } - if let Some(result) = callback(&ty.value, item) { + if let Some(result) = callback(&ty.value, item.into()) { return Some(result); } } @@ -299,17 +308,17 @@ fn is_valid_candidate( db: &impl HirDatabase, name: Option<&Name>, mode: LookupMode, - item: AssocItem, + item: AssocItemId, ) -> bool { match item { - AssocItem::Function(m) => { - let data = db.function_data(m.id); - name.map_or(true, |name| data.name == *name) + AssocItemId::FunctionId(m) => { + let data = db.function_data(m); + name.map_or(true, |name| &data.name == name) && (data.has_self_param || mode == LookupMode::Path) } - AssocItem::Const(c) => { - name.map_or(true, |name| Some(name) == c.name(db).as_ref()) - && (mode == LookupMode::Path) + AssocItemId::ConstId(c) => { + let data = db.const_data(c); + name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path) } _ => false, } @@ -344,11 +353,11 @@ impl Ty { mut callback: impl FnMut(AssocItem) -> Option, ) -> Option { for krate in def_crates(db, krate, &self)? { - let impls = db.impls_in_crate(krate); + let impls = db.impls_in_crate(krate.crate_id); for impl_block in impls.lookup_impl_blocks(&self) { - for item in impl_block.items(db) { - if let Some(result) = callback(item) { + for &item in db.impl_data(impl_block).items.iter() { + if let Some(result) = callback(item.into()) { return Some(result); } } diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index eb7b5c4ef..12dc96572 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -1,3 +1,3 @@ //! FIXME: write short doc here -pub use hir_ty::primitive::{FloatBitness, IntBitness, Signedness, FloatTy, IntTy, Uncertain}; +pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}; diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index b9a5d651f..2eeb03099 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -88,8 +88,8 @@ pub(crate) fn impls_for_trait_query( for dep in krate.dependencies(db) { impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); } - let crate_impl_blocks = db.impls_in_crate(krate); - impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); + let crate_impl_blocks = db.impls_in_crate(krate.crate_id); + impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); impls.into_iter().collect() } diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 2b3100fc3..b3ebd9145 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; +use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor}; use ra_db::SourceDatabase; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; @@ -56,11 +56,11 @@ fn impls_for_def( }; let krate = module.krate(); - let impls = db.impls_in_crate(krate); + let impls = ImplBlock::all_in_crate(db, krate); Some( impls - .all_impls() + .into_iter() .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) .map(|imp| imp.to_nav(db)) .collect(), @@ -77,9 +77,9 @@ fn impls_for_trait( let tr = hir::Trait::from_source(db, src)?; let krate = module.krate(); - let impls = db.impls_in_crate(krate); + let impls = ImplBlock::for_trait(db, krate, tr); - Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect()) + Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) } fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { -- cgit v1.2.3