aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/source_analyzer.rs18
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs19
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs9
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs41
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
12use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; 12use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 14use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef};
15 15
16impl<'a, D: HirDatabase> InferenceContext<'a, D> { 16impl<'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
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{ 8use 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};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use ra_db::CrateId; 13use ra_db::CrateId;
@@ -144,14 +144,24 @@ impl Ty {
144pub(crate) fn lookup_method( 144pub(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 {
172pub fn iterate_method_candidates<T>( 182pub 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 )