aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/method_resolution.rs')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs86
1 files changed, 23 insertions, 63 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index eb5ca6769..d20aeaacf 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -5,16 +5,14 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::CrateModuleId;
9use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
10 9
11use crate::{ 10use crate::{
12 db::HirDatabase, 11 db::HirDatabase,
13 impl_block::{ImplBlock, ImplId},
14 resolve::Resolver, 12 resolve::Resolver,
15 ty::primitive::{FloatBitness, Uncertain}, 13 ty::primitive::{FloatBitness, Uncertain},
16 ty::{Ty, TypeCtor}, 14 ty::{Ty, TypeCtor},
17 AssocItem, Crate, Function, Module, Mutability, Name, Trait, 15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,
18}; 16};
19 17
20use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 18use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef};
@@ -39,65 +37,46 @@ impl TyFingerprint {
39 37
40#[derive(Debug, PartialEq, Eq)] 38#[derive(Debug, PartialEq, Eq)]
41pub struct CrateImplBlocks { 39pub struct CrateImplBlocks {
42 /// To make sense of the CrateModuleIds, we need the source root. 40 impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>,
43 krate: Crate, 41 impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>,
44 impls: FxHashMap<TyFingerprint, Vec<(CrateModuleId, ImplId)>>,
45 impls_by_trait: FxHashMap<Trait, Vec<(CrateModuleId, ImplId)>>,
46} 42}
47 43
48impl CrateImplBlocks { 44impl CrateImplBlocks {
49 pub fn lookup_impl_blocks<'a>(&'a self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + 'a { 45 pub(crate) fn impls_in_crate_query(
46 db: &impl HirDatabase,
47 krate: Crate,
48 ) -> Arc<CrateImplBlocks> {
49 let mut crate_impl_blocks =
50 CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() };
51 if let Some(module) = krate.root_module(db) {
52 crate_impl_blocks.collect_recursive(db, module);
53 }
54 Arc::new(crate_impl_blocks)
55 }
56 pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ {
50 let fingerprint = TyFingerprint::for_impl(ty); 57 let fingerprint = TyFingerprint::for_impl(ty);
51 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( 58 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
52 move |(module_id, impl_id)| {
53 let module = Module::new(self.krate, *module_id);
54 ImplBlock::from_id(module, *impl_id)
55 },
56 )
57 } 59 }
58 60
59 pub fn lookup_impl_blocks_for_trait<'a>( 61 pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ {
60 &'a self, 62 self.impls_by_trait.get(&tr).into_iter().flatten().copied()
61 tr: Trait,
62 ) -> impl Iterator<Item = ImplBlock> + 'a {
63 self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map(
64 move |(module_id, impl_id)| {
65 let module = Module::new(self.krate, *module_id);
66 ImplBlock::from_id(module, *impl_id)
67 },
68 )
69 } 63 }
70 64
71 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { 65 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a {
72 self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map( 66 self.impls.values().chain(self.impls_by_trait.values()).flatten().copied()
73 move |(module_id, impl_id)| {
74 let module = Module::new(self.krate, *module_id);
75 ImplBlock::from_id(module, *impl_id)
76 },
77 )
78 } 67 }
79 68
80 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { 69 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
81 let module_impl_blocks = db.impls_in_module(module); 70 for impl_block in module.impl_blocks(db) {
82
83 for (impl_id, _) in module_impl_blocks.impls.iter() {
84 let impl_block = ImplBlock::from_id(module_impl_blocks.module, impl_id);
85
86 let target_ty = impl_block.target_ty(db); 71 let target_ty = impl_block.target_ty(db);
87 72
88 if impl_block.target_trait(db).is_some() { 73 if impl_block.target_trait(db).is_some() {
89 if let Some(tr) = impl_block.target_trait_ref(db) { 74 if let Some(tr) = impl_block.target_trait_ref(db) {
90 self.impls_by_trait 75 self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block);
91 .entry(tr.trait_)
92 .or_insert_with(Vec::new)
93 .push((module.id.module_id, impl_id));
94 } 76 }
95 } else { 77 } else {
96 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { 78 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
97 self.impls 79 self.impls.entry(target_ty_fp).or_default().push(impl_block);
98 .entry(target_ty_fp)
99 .or_insert_with(Vec::new)
100 .push((module.id.module_id, impl_id));
101 } 80 }
102 } 81 }
103 } 82 }
@@ -106,21 +85,6 @@ impl CrateImplBlocks {
106 self.collect_recursive(db, child); 85 self.collect_recursive(db, child);
107 } 86 }
108 } 87 }
109
110 pub(crate) fn impls_in_crate_query(
111 db: &impl HirDatabase,
112 krate: Crate,
113 ) -> Arc<CrateImplBlocks> {
114 let mut crate_impl_blocks = CrateImplBlocks {
115 krate,
116 impls: FxHashMap::default(),
117 impls_by_trait: FxHashMap::default(),
118 };
119 if let Some(module) = krate.root_module(db) {
120 crate_impl_blocks.collect_recursive(db, module);
121 }
122 Arc::new(crate_impl_blocks)
123 }
124} 88}
125 89
126fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { 90fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> {
@@ -264,14 +228,10 @@ fn iterate_trait_method_candidates<T>(
264 'traits: for t in traits { 228 'traits: for t in traits {
265 let data = t.trait_data(db); 229 let data = t.trait_data(db);
266 230
267 // FIXME this is a bit of a hack, since Chalk should say the same thing
268 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
269 let inherently_implemented = ty.value.inherent_trait() == Some(t);
270
271 // we'll be lazy about checking whether the type implements the 231 // we'll be lazy about checking whether the type implements the
272 // trait, but if we find out it doesn't, we'll skip the rest of the 232 // trait, but if we find out it doesn't, we'll skip the rest of the
273 // iteration 233 // iteration
274 let mut known_implemented = inherently_implemented; 234 let mut known_implemented = false;
275 for &item in data.items() { 235 for &item in data.items() {
276 if !is_valid_candidate(db, name, mode, item) { 236 if !is_valid_candidate(db, name, mode, item) {
277 continue; 237 continue;