diff options
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 41 |
4 files changed, 60 insertions, 27 deletions
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 3df48842d..5707a5696 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -358,10 +358,17 @@ impl SourceAnalyzer { | |||
358 | // FIXME check that? | 358 | // FIXME check that? |
359 | // FIXME replace Unknown by bound vars here | 359 | // FIXME replace Unknown by bound vars here |
360 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 360 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
361 | |||
362 | let env = TraitEnvironment::lower(db, &self.resolver); | ||
363 | let krate = self.resolver.krate()?; | ||
364 | let traits_in_scope = self.resolver.traits_in_scope(db); | ||
365 | |||
361 | method_resolution::iterate_method_candidates( | 366 | method_resolution::iterate_method_candidates( |
362 | &canonical, | 367 | &canonical, |
363 | db, | 368 | db, |
364 | &self.resolver, | 369 | env, |
370 | krate, | ||
371 | &traits_in_scope, | ||
365 | name, | 372 | name, |
366 | method_resolution::LookupMode::MethodCall, | 373 | method_resolution::LookupMode::MethodCall, |
367 | |ty, it| match it { | 374 | |ty, it| match it { |
@@ -382,10 +389,17 @@ impl SourceAnalyzer { | |||
382 | // FIXME check that? | 389 | // FIXME check that? |
383 | // FIXME replace Unknown by bound vars here | 390 | // FIXME replace Unknown by bound vars here |
384 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 391 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
392 | |||
393 | let env = TraitEnvironment::lower(db, &self.resolver); | ||
394 | let krate = self.resolver.krate()?; | ||
395 | let traits_in_scope = self.resolver.traits_in_scope(db); | ||
396 | |||
385 | method_resolution::iterate_method_candidates( | 397 | method_resolution::iterate_method_candidates( |
386 | &canonical, | 398 | &canonical, |
387 | db, | 399 | db, |
388 | &self.resolver, | 400 | env, |
401 | krate, | ||
402 | &traits_in_scope, | ||
389 | name, | 403 | name, |
390 | method_resolution::LookupMode::Path, | 404 | method_resolution::LookupMode::Path, |
391 | |ty, it| callback(ty, it.into()), | 405 | |ty, it| callback(ty, it.into()), |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 3af05394c..d6a17e469 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -569,12 +569,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
569 | ) -> Ty { | 569 | ) -> Ty { |
570 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); | 570 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); |
571 | let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone()); | 571 | let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone()); |
572 | let resolved = method_resolution::lookup_method( | 572 | |
573 | &canonicalized_receiver.value, | 573 | let traits_in_scope = self.resolver.traits_in_scope(self.db); |
574 | self.db, | 574 | |
575 | method_name, | 575 | let resolved = self.resolver.krate().and_then(|krate| { |
576 | &self.resolver, | 576 | method_resolution::lookup_method( |
577 | ); | 577 | &canonicalized_receiver.value, |
578 | self.db, | ||
579 | self.trait_env.clone(), | ||
580 | krate, | ||
581 | &traits_in_scope, | ||
582 | method_name, | ||
583 | ) | ||
584 | }); | ||
578 | let (derefed_receiver_ty, method_ty, def_generics) = match resolved { | 585 | let (derefed_receiver_ty, method_ty, def_generics) = match resolved { |
579 | Some((ty, func)) => { | 586 | Some((ty, func)) => { |
580 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | 587 | let ty = canonicalized_receiver.decanonicalize_ty(ty); |
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs index ffd358367..2c1d4831d 100644 --- a/crates/ra_hir_ty/src/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs | |||
@@ -11,7 +11,7 @@ use hir_expand::name::Name; | |||
11 | 11 | ||
12 | use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; | 12 | use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; |
13 | 13 | ||
14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 14 | use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef}; |
15 | 15 | ||
16 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 16 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
17 | pub(super) fn infer_path( | 17 | pub(super) fn infer_path( |
@@ -193,11 +193,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
193 | } | 193 | } |
194 | 194 | ||
195 | let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); | 195 | let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); |
196 | let env = TraitEnvironment::lower(self.db, &self.resolver); | ||
197 | let krate = self.resolver.krate()?; | ||
198 | let traits_in_scope = self.resolver.traits_in_scope(self.db); | ||
196 | 199 | ||
197 | method_resolution::iterate_method_candidates( | 200 | method_resolution::iterate_method_candidates( |
198 | &canonical_ty.value, | 201 | &canonical_ty.value, |
199 | self.db, | 202 | self.db, |
200 | &self.resolver.clone(), | 203 | env, |
204 | krate, | ||
205 | &traits_in_scope, | ||
201 | Some(name), | 206 | Some(name), |
202 | method_resolution::LookupMode::Path, | 207 | method_resolution::LookupMode::Path, |
203 | move |_ty, item| { | 208 | move |_ty, item| { |
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index e43fadf20..5bacbbd7c 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -6,8 +6,8 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{ | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocContainerId, | 9 | lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, |
10 | AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId, | 10 | HasModule, ImplId, Lookup, TraitId, |
11 | }; | 11 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use ra_db::CrateId; | 13 | use ra_db::CrateId; |
@@ -144,14 +144,24 @@ impl Ty { | |||
144 | pub(crate) fn lookup_method( | 144 | pub(crate) fn lookup_method( |
145 | ty: &Canonical<Ty>, | 145 | ty: &Canonical<Ty>, |
146 | db: &impl HirDatabase, | 146 | db: &impl HirDatabase, |
147 | env: Arc<TraitEnvironment>, | ||
148 | krate: CrateId, | ||
149 | traits_in_scope: &FxHashSet<TraitId>, | ||
147 | name: &Name, | 150 | name: &Name, |
148 | resolver: &Resolver, | ||
149 | ) -> Option<(Ty, FunctionId)> { | 151 | ) -> Option<(Ty, FunctionId)> { |
150 | iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f | 152 | iterate_method_candidates( |
151 | { | 153 | ty, |
152 | AssocItemId::FunctionId(f) => Some((ty.clone(), f)), | 154 | db, |
153 | _ => None, | 155 | env, |
154 | }) | 156 | krate, |
157 | &traits_in_scope, | ||
158 | Some(name), | ||
159 | LookupMode::MethodCall, | ||
160 | |ty, f| match f { | ||
161 | AssocItemId::FunctionId(f) => Some((ty.clone(), f)), | ||
162 | _ => None, | ||
163 | }, | ||
164 | ) | ||
155 | } | 165 | } |
156 | 166 | ||
157 | /// Whether we're looking up a dotted method call (like `v.len()`) or a path | 167 | /// Whether we're looking up a dotted method call (like `v.len()`) or a path |
@@ -172,14 +182,13 @@ pub enum LookupMode { | |||
172 | pub fn iterate_method_candidates<T>( | 182 | pub fn iterate_method_candidates<T>( |
173 | ty: &Canonical<Ty>, | 183 | ty: &Canonical<Ty>, |
174 | db: &impl HirDatabase, | 184 | db: &impl HirDatabase, |
175 | resolver: &Resolver, | 185 | env: Arc<TraitEnvironment>, |
186 | krate: CrateId, | ||
187 | traits_in_scope: &FxHashSet<TraitId>, | ||
176 | name: Option<&Name>, | 188 | name: Option<&Name>, |
177 | mode: LookupMode, | 189 | mode: LookupMode, |
178 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, | 190 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, |
179 | ) -> Option<T> { | 191 | ) -> Option<T> { |
180 | let traits_in_scope = resolver.traits_in_scope(db); | ||
181 | let krate = resolver.krate()?; | ||
182 | let env = TraitEnvironment::lower(db, resolver); | ||
183 | match mode { | 192 | match mode { |
184 | LookupMode::MethodCall => { | 193 | LookupMode::MethodCall => { |
185 | // For method calls, rust first does any number of autoderef, and then one | 194 | // For method calls, rust first does any number of autoderef, and then one |
@@ -190,9 +199,7 @@ pub fn iterate_method_candidates<T>( | |||
190 | // Also note that when we've got a receiver like &S, even if the method we | 199 | // Also note that when we've got a receiver like &S, even if the method we |
191 | // find in the end takes &self, we still do the autoderef step (just as | 200 | // find in the end takes &self, we still do the autoderef step (just as |
192 | // rustc does an autoderef and then autoref again). | 201 | // rustc does an autoderef and then autoref again). |
193 | let environment = TraitEnvironment::lower(db, resolver); | 202 | let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; |
194 | let ty = InEnvironment { value: ty.clone(), environment }; | ||
195 | let krate = resolver.krate()?; | ||
196 | 203 | ||
197 | // We have to be careful about the order we're looking at candidates | 204 | // We have to be careful about the order we're looking at candidates |
198 | // in here. Consider the case where we're resolving `x.clone()` | 205 | // in here. Consider the case where we're resolving `x.clone()` |
@@ -214,7 +221,7 @@ pub fn iterate_method_candidates<T>( | |||
214 | db, | 221 | db, |
215 | env.clone(), | 222 | env.clone(), |
216 | krate, | 223 | krate, |
217 | &traits_in_scope, | 224 | traits_in_scope, |
218 | name, | 225 | name, |
219 | &mut callback, | 226 | &mut callback, |
220 | ) { | 227 | ) { |
@@ -230,7 +237,7 @@ pub fn iterate_method_candidates<T>( | |||
230 | db, | 237 | db, |
231 | env, | 238 | env, |
232 | krate, | 239 | krate, |
233 | &traits_in_scope, | 240 | traits_in_scope, |
234 | name, | 241 | name, |
235 | &mut callback, | 242 | &mut callback, |
236 | ) | 243 | ) |