diff options
author | Aleksey Kladov <[email protected]> | 2019-11-26 12:27:33 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-26 12:36:25 +0000 |
commit | 45d05ed78384b28fbd341068f36912a2e0308292 (patch) | |
tree | 5b7f7abfc59e6e832be7fb0b22b3dcc704de946c /crates/ra_hir | |
parent | 4c43631829d8bac8b7533c994d8cf1241a95ce70 (diff) |
id-ify impls_in_crate_query
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 101 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 4 |
5 files changed, 69 insertions, 51 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 { | |||
997 | } | 997 | } |
998 | 998 | ||
999 | impl ImplBlock { | 999 | impl ImplBlock { |
1000 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | ||
1001 | let impls = db.impls_in_crate(krate.crate_id); | ||
1002 | impls.all_impls().map(Self::from).collect() | ||
1003 | } | ||
1004 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | ||
1005 | let impls = db.impls_in_crate(krate.crate_id); | ||
1006 | impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() | ||
1007 | } | ||
1008 | |||
1000 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 1009 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
1001 | db.impl_data(self.id).target_trait.clone() | 1010 | db.impl_data(self.id).target_trait.clone() |
1002 | } | 1011 | } |
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 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_arena::map::ArenaMap; | 5 | use ra_arena::map::ArenaMap; |
6 | use ra_db::salsa; | 6 | use ra_db::{salsa, CrateId}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | ty::{ | 9 | ty::{ |
@@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase { | |||
60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; | 60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; |
61 | 61 | ||
62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
63 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 63 | fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>; |
64 | 64 | ||
65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] | 65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] |
66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; | 66 | 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 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, | ||
10 | HasModule, ImplId, TraitId, | ||
11 | }; | ||
12 | use ra_db::CrateId; | ||
13 | use ra_prof::profile; | ||
9 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
10 | 15 | ||
11 | use crate::{ | 16 | use crate::{ |
12 | db::HirDatabase, | 17 | db::HirDatabase, |
13 | ty::primitive::{FloatBitness, Uncertain}, | 18 | ty::primitive::{FloatBitness, Uncertain}, |
14 | ty::{Ty, TypeCtor}, | 19 | ty::{Ty, TypeCtor}, |
15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, | 20 | AssocItem, Crate, Function, Mutability, Name, Trait, |
16 | }; | 21 | }; |
17 | 22 | ||
18 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 23 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -37,54 +42,58 @@ impl TyFingerprint { | |||
37 | 42 | ||
38 | #[derive(Debug, PartialEq, Eq)] | 43 | #[derive(Debug, PartialEq, Eq)] |
39 | pub struct CrateImplBlocks { | 44 | pub struct CrateImplBlocks { |
40 | impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>, | 45 | impls: FxHashMap<TyFingerprint, Vec<ImplId>>, |
41 | impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>, | 46 | impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>, |
42 | } | 47 | } |
43 | 48 | ||
44 | impl CrateImplBlocks { | 49 | impl CrateImplBlocks { |
45 | pub(crate) fn impls_in_crate_query( | 50 | pub(crate) fn impls_in_crate_query( |
46 | db: &impl HirDatabase, | 51 | db: &impl HirDatabase, |
47 | krate: Crate, | 52 | krate: CrateId, |
48 | ) -> Arc<CrateImplBlocks> { | 53 | ) -> Arc<CrateImplBlocks> { |
49 | let mut crate_impl_blocks = | 54 | let _p = profile("impls_in_crate_query"); |
55 | let mut res = | ||
50 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; | 56 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; |
51 | if let Some(module) = krate.root_module(db) { | 57 | |
52 | crate_impl_blocks.collect_recursive(db, module); | 58 | let crate_def_map = db.crate_def_map(krate); |
59 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
60 | for &impl_id in module_data.impls.iter() { | ||
61 | let impl_data = db.impl_data(impl_id); | ||
62 | let resolver = impl_id.resolver(db); | ||
63 | |||
64 | let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; | ||
65 | |||
66 | match &impl_data.target_trait { | ||
67 | Some(trait_ref) => { | ||
68 | if let Some(tr) = | ||
69 | TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) | ||
70 | { | ||
71 | res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); | ||
72 | } | ||
73 | } | ||
74 | None => { | ||
75 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
76 | res.impls.entry(target_ty_fp).or_default().push(impl_id); | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | } | ||
53 | } | 81 | } |
54 | Arc::new(crate_impl_blocks) | 82 | |
83 | Arc::new(res) | ||
55 | } | 84 | } |
56 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ { | 85 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ { |
57 | let fingerprint = TyFingerprint::for_impl(ty); | 86 | let fingerprint = TyFingerprint::for_impl(ty); |
58 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() | 87 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() |
59 | } | 88 | } |
60 | 89 | ||
61 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ { | 90 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ { |
62 | self.impls_by_trait.get(&tr).into_iter().flatten().copied() | 91 | self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() |
63 | } | 92 | } |
64 | 93 | ||
65 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { | 94 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a { |
66 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() | 95 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() |
67 | } | 96 | } |
68 | |||
69 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { | ||
70 | for impl_block in module.impl_blocks(db) { | ||
71 | let target_ty = impl_block.target_ty(db); | ||
72 | |||
73 | if impl_block.target_trait(db).is_some() { | ||
74 | if let Some(tr) = impl_block.target_trait_ref(db) { | ||
75 | self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); | ||
76 | } | ||
77 | } else { | ||
78 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
79 | self.impls.entry(target_ty_fp).or_default().push(impl_block); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | for child in module.children(db) { | ||
85 | self.collect_recursive(db, child); | ||
86 | } | ||
87 | } | ||
88 | } | 97 | } |
89 | 98 | ||
90 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { | 99 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { |
@@ -279,14 +288,14 @@ fn iterate_inherent_methods<T>( | |||
279 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 288 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, |
280 | ) -> Option<T> { | 289 | ) -> Option<T> { |
281 | for krate in def_crates(db, krate, &ty.value)? { | 290 | for krate in def_crates(db, krate, &ty.value)? { |
282 | let impls = db.impls_in_crate(krate); | 291 | let impls = db.impls_in_crate(krate.crate_id); |
283 | 292 | ||
284 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 293 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
285 | for item in impl_block.items(db) { | 294 | for &item in db.impl_data(impl_block).items.iter() { |
286 | if !is_valid_candidate(db, name, mode, item) { | 295 | if !is_valid_candidate(db, name, mode, item) { |
287 | continue; | 296 | continue; |
288 | } | 297 | } |
289 | if let Some(result) = callback(&ty.value, item) { | 298 | if let Some(result) = callback(&ty.value, item.into()) { |
290 | return Some(result); | 299 | return Some(result); |
291 | } | 300 | } |
292 | } | 301 | } |
@@ -299,17 +308,17 @@ fn is_valid_candidate( | |||
299 | db: &impl HirDatabase, | 308 | db: &impl HirDatabase, |
300 | name: Option<&Name>, | 309 | name: Option<&Name>, |
301 | mode: LookupMode, | 310 | mode: LookupMode, |
302 | item: AssocItem, | 311 | item: AssocItemId, |
303 | ) -> bool { | 312 | ) -> bool { |
304 | match item { | 313 | match item { |
305 | AssocItem::Function(m) => { | 314 | AssocItemId::FunctionId(m) => { |
306 | let data = db.function_data(m.id); | 315 | let data = db.function_data(m); |
307 | name.map_or(true, |name| data.name == *name) | 316 | name.map_or(true, |name| &data.name == name) |
308 | && (data.has_self_param || mode == LookupMode::Path) | 317 | && (data.has_self_param || mode == LookupMode::Path) |
309 | } | 318 | } |
310 | AssocItem::Const(c) => { | 319 | AssocItemId::ConstId(c) => { |
311 | name.map_or(true, |name| Some(name) == c.name(db).as_ref()) | 320 | let data = db.const_data(c); |
312 | && (mode == LookupMode::Path) | 321 | name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path) |
313 | } | 322 | } |
314 | _ => false, | 323 | _ => false, |
315 | } | 324 | } |
@@ -344,11 +353,11 @@ impl Ty { | |||
344 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 353 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
345 | ) -> Option<T> { | 354 | ) -> Option<T> { |
346 | for krate in def_crates(db, krate, &self)? { | 355 | for krate in def_crates(db, krate, &self)? { |
347 | let impls = db.impls_in_crate(krate); | 356 | let impls = db.impls_in_crate(krate.crate_id); |
348 | 357 | ||
349 | for impl_block in impls.lookup_impl_blocks(&self) { | 358 | for impl_block in impls.lookup_impl_blocks(&self) { |
350 | for item in impl_block.items(db) { | 359 | for &item in db.impl_data(impl_block).items.iter() { |
351 | if let Some(result) = callback(item) { | 360 | if let Some(result) = callback(item.into()) { |
352 | return Some(result); | 361 | return Some(result); |
353 | } | 362 | } |
354 | } | 363 | } |
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 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | pub use hir_ty::primitive::{FloatBitness, IntBitness, Signedness, FloatTy, IntTy, Uncertain}; | 3 | 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( | |||
88 | for dep in krate.dependencies(db) { | 88 | for dep in krate.dependencies(db) { |
89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); | 89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); |
90 | } | 90 | } |
91 | let crate_impl_blocks = db.impls_in_crate(krate); | 91 | let crate_impl_blocks = db.impls_in_crate(krate.crate_id); |
92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); | 92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); |
93 | impls.into_iter().collect() | 93 | impls.into_iter().collect() |
94 | } | 94 | } |
95 | 95 | ||