diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 86 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 10 |
4 files changed, 61 insertions, 49 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 9f3e6c43f..b9d3a1713 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | expr::{ExprId, PatId}, | 11 | expr::{ExprId, PatId}, |
12 | path::known, | 12 | path::known, |
13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
14 | DefWithBodyId, | 14 | AssocItemId, DefWithBodyId, |
15 | }; | 15 | }; |
16 | use hir_expand::{ | 16 | use hir_expand::{ |
17 | hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, | 17 | hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, |
@@ -380,7 +380,7 @@ impl SourceAnalyzer { | |||
380 | name, | 380 | name, |
381 | method_resolution::LookupMode::MethodCall, | 381 | method_resolution::LookupMode::MethodCall, |
382 | |ty, it| match it { | 382 | |ty, it| match it { |
383 | AssocItem::Function(f) => callback(ty, f), | 383 | AssocItemId::FunctionId(f) => callback(ty, f.into()), |
384 | _ => None, | 384 | _ => None, |
385 | }, | 385 | }, |
386 | ) | 386 | ) |
@@ -391,7 +391,7 @@ impl SourceAnalyzer { | |||
391 | db: &impl HirDatabase, | 391 | db: &impl HirDatabase, |
392 | ty: &Type, | 392 | ty: &Type, |
393 | name: Option<&Name>, | 393 | name: Option<&Name>, |
394 | callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 394 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, |
395 | ) -> Option<T> { | 395 | ) -> Option<T> { |
396 | // There should be no inference vars in types passed here | 396 | // There should be no inference vars in types passed here |
397 | // FIXME check that? | 397 | // FIXME check that? |
@@ -403,7 +403,7 @@ impl SourceAnalyzer { | |||
403 | &self.resolver, | 403 | &self.resolver, |
404 | name, | 404 | name, |
405 | method_resolution::LookupMode::Path, | 405 | method_resolution::LookupMode::Path, |
406 | callback, | 406 | |ty, it| callback(ty, it.into()), |
407 | ) | 407 | ) |
408 | } | 408 | } |
409 | 409 | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index beb2efb7a..db9a8c9d1 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -26,7 +26,7 @@ use hir_def::{ | |||
26 | path::known, | 26 | path::known, |
27 | resolver::{HasResolver, Resolver, TypeNs}, | 27 | resolver::{HasResolver, Resolver, TypeNs}, |
28 | type_ref::{Mutability, TypeRef}, | 28 | type_ref::{Mutability, TypeRef}, |
29 | AdtId, DefWithBodyId, | 29 | AdtId, AssocItemId, DefWithBodyId, |
30 | }; | 30 | }; |
31 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 31 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
32 | use ra_arena::map::ArenaMap; | 32 | use ra_arena::map::ArenaMap; |
@@ -255,8 +255,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
255 | self.result.variant_resolutions.insert(id, variant); | 255 | self.result.variant_resolutions.insert(id, variant); |
256 | } | 256 | } |
257 | 257 | ||
258 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItem) { | 258 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId) { |
259 | self.result.assoc_resolutions.insert(id, item); | 259 | self.result.assoc_resolutions.insert(id, item.into()); |
260 | } | 260 | } |
261 | 261 | ||
262 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { | 262 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { |
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 | ||
3 | use hir_def::{ | 3 | use 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 | }; |
7 | use hir_expand::name::Name; | 8 | use hir_expand::name::Name; |
8 | 9 | ||
9 | use crate::{ | 10 | use 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 | ||
15 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 15 | use 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 | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7df2649c9..02e81fb34 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | ty::primitive::{FloatBitness, Uncertain}, | 19 | ty::primitive::{FloatBitness, Uncertain}, |
20 | ty::{utils::all_super_traits, Ty, TypeCtor}, | 20 | ty::{utils::all_super_traits, Ty, TypeCtor}, |
21 | AssocItem, Function, | 21 | Function, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 24 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -157,7 +157,7 @@ pub(crate) fn lookup_method( | |||
157 | ) -> Option<(Ty, Function)> { | 157 | ) -> Option<(Ty, Function)> { |
158 | iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f | 158 | iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f |
159 | { | 159 | { |
160 | AssocItem::Function(f) => Some((ty.clone(), f)), | 160 | AssocItemId::FunctionId(f) => Some((ty.clone(), f.into())), |
161 | _ => None, | 161 | _ => None, |
162 | }) | 162 | }) |
163 | } | 163 | } |
@@ -183,7 +183,7 @@ pub(crate) fn iterate_method_candidates<T>( | |||
183 | resolver: &Resolver, | 183 | resolver: &Resolver, |
184 | name: Option<&Name>, | 184 | name: Option<&Name>, |
185 | mode: LookupMode, | 185 | mode: LookupMode, |
186 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 186 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, |
187 | ) -> Option<T> { | 187 | ) -> Option<T> { |
188 | let krate = resolver.krate()?; | 188 | let krate = resolver.krate()?; |
189 | match mode { | 189 | match mode { |
@@ -239,7 +239,7 @@ fn iterate_trait_method_candidates<T>( | |||
239 | resolver: &Resolver, | 239 | resolver: &Resolver, |
240 | name: Option<&Name>, | 240 | name: Option<&Name>, |
241 | mode: LookupMode, | 241 | mode: LookupMode, |
242 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 242 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, |
243 | ) -> Option<T> { | 243 | ) -> Option<T> { |
244 | let krate = resolver.krate()?; | 244 | let krate = resolver.krate()?; |
245 | // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) | 245 | // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) |
@@ -285,7 +285,7 @@ fn iterate_inherent_methods<T>( | |||
285 | name: Option<&Name>, | 285 | name: Option<&Name>, |
286 | mode: LookupMode, | 286 | mode: LookupMode, |
287 | krate: CrateId, | 287 | krate: CrateId, |
288 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 288 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, |
289 | ) -> Option<T> { | 289 | ) -> Option<T> { |
290 | for krate in ty.value.def_crates(db, krate)? { | 290 | for krate in ty.value.def_crates(db, krate)? { |
291 | let impls = db.impls_in_crate(krate); | 291 | let impls = db.impls_in_crate(krate); |