aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-27 09:31:40 +0000
committerAleksey Kladov <[email protected]>2019-11-27 09:34:26 +0000
commit825049bc6247f6d596910cd99f76f891d5435a86 (patch)
tree24e9543a78e13477a85c38f98a58f402d7a40ef9 /crates/ra_hir/src/ty/infer
parente91ebfc752bdfa8fc20be6ea97a14aa6a4d897ae (diff)
Decouple
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs86
1 files changed, 49 insertions, 37 deletions
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 8d8b56d2d..09ff79728 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -2,14 +2,14 @@
2 2
3use hir_def::{ 3use hir_def::{
4 path::{Path, PathSegment}, 4 path::{Path, PathSegment},
5 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, 5 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
6 AssocItemId, ContainerId, Lookup,
6}; 7};
7use hir_expand::name::Name; 8use hir_expand::name::Name;
8 9
9use crate::{ 10use crate::{
10 db::HirDatabase, 11 db::HirDatabase,
11 ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, 12 ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId},
12 AssocItem, Container, Function,
13}; 13};
14 14
15use super::{ExprOrPatId, InferenceContext, TraitRef}; 15use super::{ExprOrPatId, InferenceContext, TraitRef};
@@ -143,31 +143,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
143 id: ExprOrPatId, 143 id: ExprOrPatId,
144 ) -> Option<(ValueNs, Option<Substs>)> { 144 ) -> Option<(ValueNs, Option<Substs>)> {
145 let trait_ = trait_ref.trait_; 145 let trait_ = trait_ref.trait_;
146 let item = 146 let item = self
147 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map( 147 .db
148 |item| match item { 148 .trait_data(trait_)
149 AssocItem::Function(func) => { 149 .items
150 if segment.name == func.name(self.db) { 150 .iter()
151 Some(AssocItem::Function(func)) 151 .map(|(_name, id)| (*id).into())
152 } else { 152 .find_map(|item| match item {
153 None 153 AssocItemId::FunctionId(func) => {
154 } 154 if segment.name == self.db.function_data(func).name {
155 Some(AssocItemId::FunctionId(func))
156 } else {
157 None
155 } 158 }
159 }
156 160
157 AssocItem::Const(konst) => { 161 AssocItemId::ConstId(konst) => {
158 if konst.name(self.db).map_or(false, |n| n == segment.name) { 162 if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == &segment.name)
159 Some(AssocItem::Const(konst)) 163 {
160 } else { 164 Some(AssocItemId::ConstId(konst))
161 None 165 } else {
162 } 166 None
163 } 167 }
164 AssocItem::TypeAlias(_) => None, 168 }
165 }, 169 AssocItemId::TypeAliasId(_) => None,
166 )?; 170 })?;
167 let def = match item { 171 let def = match item {
168 AssocItem::Function(f) => ValueNs::FunctionId(f.id), 172 AssocItemId::FunctionId(f) => ValueNs::FunctionId(f),
169 AssocItem::Const(c) => ValueNs::ConstId(c.id), 173 AssocItemId::ConstId(c) => ValueNs::ConstId(c),
170 AssocItem::TypeAlias(_) => unreachable!(), 174 AssocItemId::TypeAliasId(_) => unreachable!(),
171 }; 175 };
172 let substs = Substs::build_for_def(self.db, item) 176 let substs = Substs::build_for_def(self.db, item)
173 .use_parent_substs(&trait_ref.substs) 177 .use_parent_substs(&trait_ref.substs)
@@ -197,16 +201,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
197 Some(name), 201 Some(name),
198 method_resolution::LookupMode::Path, 202 method_resolution::LookupMode::Path,
199 move |_ty, item| { 203 move |_ty, item| {
200 let def = match item { 204 let (def, container) = match item {
201 AssocItem::Function(f) => ValueNs::FunctionId(f.id), 205 AssocItemId::FunctionId(f) => {
202 AssocItem::Const(c) => ValueNs::ConstId(c.id), 206 (ValueNs::FunctionId(f), f.lookup(self.db).container)
203 AssocItem::TypeAlias(_) => unreachable!(), 207 }
208 AssocItemId::ConstId(c) => (ValueNs::ConstId(c), c.lookup(self.db).container),
209 AssocItemId::TypeAliasId(_) => unreachable!(),
204 }; 210 };
205 let substs = match item.container(self.db) { 211 let substs = match container {
206 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), 212 ContainerId::ImplId(_) => self.find_self_types(&def, ty.clone()),
207 Container::Trait(t) => { 213 ContainerId::TraitId(trait_) => {
208 // we're picking this method 214 // we're picking this method
209 let trait_substs = Substs::build_for_def(self.db, t.id) 215 let trait_substs = Substs::build_for_def(self.db, trait_)
210 .push(ty.clone()) 216 .push(ty.clone())
211 .fill(std::iter::repeat_with(|| self.new_type_var())) 217 .fill(std::iter::repeat_with(|| self.new_type_var()))
212 .build(); 218 .build();
@@ -215,29 +221,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
215 .fill_with_params() 221 .fill_with_params()
216 .build(); 222 .build();
217 self.obligations.push(super::Obligation::Trait(TraitRef { 223 self.obligations.push(super::Obligation::Trait(TraitRef {
218 trait_: t.id, 224 trait_,
219 substs: trait_substs, 225 substs: trait_substs,
220 })); 226 }));
221 Some(substs) 227 Some(substs)
222 } 228 }
229 ContainerId::ModuleId(_) => None,
223 }; 230 };
224 231
225 self.write_assoc_resolution(id, item); 232 self.write_assoc_resolution(id, item.into());
226 Some((def, substs)) 233 Some((def, substs))
227 }, 234 },
228 ) 235 )
229 } 236 }
230 237
231 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { 238 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> {
232 if let ValueNs::FunctionId(func) = def { 239 if let ValueNs::FunctionId(func) = *def {
233 let func = Function::from(*func);
234 // We only do the infer if parent has generic params 240 // We only do the infer if parent has generic params
235 let gen = self.db.generic_params(func.id.into()); 241 let gen = self.db.generic_params(func.into());
236 if gen.count_parent_params() == 0 { 242 if gen.count_parent_params() == 0 {
237 return None; 243 return None;
238 } 244 }
239 245
240 let impl_block = func.impl_block(self.db)?.target_ty(self.db); 246 let impl_id = match func.lookup(self.db).container {
247 ContainerId::ImplId(it) => it,
248 _ => return None,
249 };
250 let resolver = impl_id.resolver(self.db);
251 let impl_data = self.db.impl_data(impl_id);
252 let impl_block = Ty::from_hir(self.db, &resolver, &impl_data.target_type);
241 let impl_block_substs = impl_block.substs()?; 253 let impl_block_substs = impl_block.substs()?;
242 let actual_substs = actual_def_ty.substs()?; 254 let actual_substs = actual_def_ty.substs()?;
243 255