aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs72
1 files changed, 51 insertions, 21 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 55435e6ea..e43fadf20 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -12,7 +12,7 @@ use hir_def::{
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use ra_db::CrateId; 13use ra_db::CrateId;
14use ra_prof::profile; 14use ra_prof::profile;
15use rustc_hash::FxHashMap; 15use rustc_hash::{FxHashMap, FxHashSet};
16 16
17use super::Substs; 17use super::Substs;
18use crate::{ 18use crate::{
@@ -177,6 +177,9 @@ pub fn iterate_method_candidates<T>(
177 mode: LookupMode, 177 mode: LookupMode,
178 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 178 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
179) -> Option<T> { 179) -> Option<T> {
180 let traits_in_scope = resolver.traits_in_scope(db);
181 let krate = resolver.krate()?;
182 let env = TraitEnvironment::lower(db, resolver);
180 match mode { 183 match mode {
181 LookupMode::MethodCall => { 184 LookupMode::MethodCall => {
182 // For method calls, rust first does any number of autoderef, and then one 185 // For method calls, rust first does any number of autoderef, and then one
@@ -209,7 +212,9 @@ pub fn iterate_method_candidates<T>(
209 if let Some(result) = iterate_method_candidates_with_autoref( 212 if let Some(result) = iterate_method_candidates_with_autoref(
210 &deref_chain[i..], 213 &deref_chain[i..],
211 db, 214 db,
212 resolver, 215 env.clone(),
216 krate,
217 &traits_in_scope,
213 name, 218 name,
214 &mut callback, 219 &mut callback,
215 ) { 220 ) {
@@ -220,7 +225,15 @@ pub fn iterate_method_candidates<T>(
220 } 225 }
221 LookupMode::Path => { 226 LookupMode::Path => {
222 // No autoderef for path lookups 227 // No autoderef for path lookups
223 iterate_method_candidates_for_self_ty(&ty, db, resolver, name, &mut callback) 228 iterate_method_candidates_for_self_ty(
229 &ty,
230 db,
231 env,
232 krate,
233 &traits_in_scope,
234 name,
235 &mut callback,
236 )
224 } 237 }
225 } 238 }
226} 239}
@@ -228,7 +241,9 @@ pub fn iterate_method_candidates<T>(
228fn iterate_method_candidates_with_autoref<T>( 241fn iterate_method_candidates_with_autoref<T>(
229 deref_chain: &[Canonical<Ty>], 242 deref_chain: &[Canonical<Ty>],
230 db: &impl HirDatabase, 243 db: &impl HirDatabase,
231 resolver: &Resolver, 244 env: Arc<TraitEnvironment>,
245 krate: CrateId,
246 traits_in_scope: &FxHashSet<TraitId>,
232 name: Option<&Name>, 247 name: Option<&Name>,
233 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 248 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
234) -> Option<T> { 249) -> Option<T> {
@@ -236,7 +251,9 @@ fn iterate_method_candidates_with_autoref<T>(
236 &deref_chain[0], 251 &deref_chain[0],
237 &deref_chain[1..], 252 &deref_chain[1..],
238 db, 253 db,
239 resolver, 254 env.clone(),
255 krate,
256 &traits_in_scope,
240 name, 257 name,
241 &mut callback, 258 &mut callback,
242 ) { 259 ) {
@@ -250,7 +267,9 @@ fn iterate_method_candidates_with_autoref<T>(
250 &refed, 267 &refed,
251 deref_chain, 268 deref_chain,
252 db, 269 db,
253 resolver, 270 env.clone(),
271 krate,
272 &traits_in_scope,
254 name, 273 name,
255 &mut callback, 274 &mut callback,
256 ) { 275 ) {
@@ -264,7 +283,9 @@ fn iterate_method_candidates_with_autoref<T>(
264 &ref_muted, 283 &ref_muted,
265 deref_chain, 284 deref_chain,
266 db, 285 db,
267 resolver, 286 env.clone(),
287 krate,
288 &traits_in_scope,
268 name, 289 name,
269 &mut callback, 290 &mut callback,
270 ) { 291 ) {
@@ -277,14 +298,15 @@ fn iterate_method_candidates_by_receiver<T>(
277 receiver_ty: &Canonical<Ty>, 298 receiver_ty: &Canonical<Ty>,
278 rest_of_deref_chain: &[Canonical<Ty>], 299 rest_of_deref_chain: &[Canonical<Ty>],
279 db: &impl HirDatabase, 300 db: &impl HirDatabase,
280 resolver: &Resolver, 301 env: Arc<TraitEnvironment>,
302 krate: CrateId,
303 traits_in_scope: &FxHashSet<TraitId>,
281 name: Option<&Name>, 304 name: Option<&Name>,
282 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 305 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
283) -> Option<T> { 306) -> Option<T> {
284 // We're looking for methods with *receiver* type receiver_ty. These could 307 // We're looking for methods with *receiver* type receiver_ty. These could
285 // be found in any of the derefs of receiver_ty, so we have to go through 308 // be found in any of the derefs of receiver_ty, so we have to go through
286 // that. 309 // that.
287 let krate = resolver.krate()?;
288 for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) { 310 for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
289 if let Some(result) = 311 if let Some(result) =
290 iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback) 312 iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback)
@@ -296,7 +318,9 @@ fn iterate_method_candidates_by_receiver<T>(
296 if let Some(result) = iterate_trait_method_candidates( 318 if let Some(result) = iterate_trait_method_candidates(
297 self_ty, 319 self_ty,
298 db, 320 db,
299 resolver, 321 env.clone(),
322 krate,
323 &traits_in_scope,
300 name, 324 name,
301 Some(receiver_ty), 325 Some(receiver_ty),
302 &mut callback, 326 &mut callback,
@@ -310,17 +334,25 @@ fn iterate_method_candidates_by_receiver<T>(
310fn iterate_method_candidates_for_self_ty<T>( 334fn iterate_method_candidates_for_self_ty<T>(
311 self_ty: &Canonical<Ty>, 335 self_ty: &Canonical<Ty>,
312 db: &impl HirDatabase, 336 db: &impl HirDatabase,
313 resolver: &Resolver, 337 env: Arc<TraitEnvironment>,
338 krate: CrateId,
339 traits_in_scope: &FxHashSet<TraitId>,
314 name: Option<&Name>, 340 name: Option<&Name>,
315 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 341 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
316) -> Option<T> { 342) -> Option<T> {
317 let krate = resolver.krate()?;
318 if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) { 343 if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) {
319 return Some(result); 344 return Some(result);
320 } 345 }
321 if let Some(result) = 346 if let Some(result) = iterate_trait_method_candidates(
322 iterate_trait_method_candidates(self_ty, db, resolver, name, None, &mut callback) 347 self_ty,
323 { 348 db,
349 env,
350 krate,
351 traits_in_scope,
352 name,
353 None,
354 &mut callback,
355 ) {
324 return Some(result); 356 return Some(result);
325 } 357 }
326 None 358 None
@@ -329,14 +361,13 @@ fn iterate_method_candidates_for_self_ty<T>(
329fn iterate_trait_method_candidates<T>( 361fn iterate_trait_method_candidates<T>(
330 self_ty: &Canonical<Ty>, 362 self_ty: &Canonical<Ty>,
331 db: &impl HirDatabase, 363 db: &impl HirDatabase,
332 resolver: &Resolver, 364 env: Arc<TraitEnvironment>,
365 krate: CrateId,
366 traits_in_scope: &FxHashSet<TraitId>,
333 name: Option<&Name>, 367 name: Option<&Name>,
334 receiver_ty: Option<&Canonical<Ty>>, 368 receiver_ty: Option<&Canonical<Ty>>,
335 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 369 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
336) -> Option<T> { 370) -> Option<T> {
337 let krate = resolver.krate()?;
338 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
339 let env = TraitEnvironment::lower(db, resolver);
340 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 371 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
341 let inherent_trait = self_ty.value.inherent_trait().into_iter(); 372 let inherent_trait = self_ty.value.inherent_trait().into_iter();
342 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 373 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
@@ -344,8 +375,7 @@ fn iterate_trait_method_candidates<T>(
344 .trait_predicates_for_self_ty(&self_ty.value) 375 .trait_predicates_for_self_ty(&self_ty.value)
345 .map(|tr| tr.trait_) 376 .map(|tr| tr.trait_)
346 .flat_map(|t| all_super_traits(db, t)); 377 .flat_map(|t| all_super_traits(db, t));
347 let traits = 378 let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied());
348 inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
349 'traits: for t in traits { 379 'traits: for t in traits {
350 let data = db.trait_data(t); 380 let data = db.trait_data(t);
351 381