diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 8e986ddde..84d9a1e18 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -296,6 +296,7 @@ pub(crate) fn lookup_method( | |||
296 | env: Arc<TraitEnvironment>, | 296 | env: Arc<TraitEnvironment>, |
297 | krate: CrateId, | 297 | krate: CrateId, |
298 | traits_in_scope: &FxHashSet<TraitId>, | 298 | traits_in_scope: &FxHashSet<TraitId>, |
299 | visible_from_module: Option<ModuleId>, | ||
299 | name: &Name, | 300 | name: &Name, |
300 | ) -> Option<(Ty, FunctionId)> { | 301 | ) -> Option<(Ty, FunctionId)> { |
301 | iterate_method_candidates( | 302 | iterate_method_candidates( |
@@ -304,6 +305,7 @@ pub(crate) fn lookup_method( | |||
304 | env, | 305 | env, |
305 | krate, | 306 | krate, |
306 | &traits_in_scope, | 307 | &traits_in_scope, |
308 | visible_from_module, | ||
307 | Some(name), | 309 | Some(name), |
308 | LookupMode::MethodCall, | 310 | LookupMode::MethodCall, |
309 | |ty, f| match f { | 311 | |ty, f| match f { |
@@ -334,6 +336,7 @@ pub fn iterate_method_candidates<T>( | |||
334 | env: Arc<TraitEnvironment>, | 336 | env: Arc<TraitEnvironment>, |
335 | krate: CrateId, | 337 | krate: CrateId, |
336 | traits_in_scope: &FxHashSet<TraitId>, | 338 | traits_in_scope: &FxHashSet<TraitId>, |
339 | visible_from_module: Option<ModuleId>, | ||
337 | name: Option<&Name>, | 340 | name: Option<&Name>, |
338 | mode: LookupMode, | 341 | mode: LookupMode, |
339 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, | 342 | mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, |
@@ -345,6 +348,7 @@ pub fn iterate_method_candidates<T>( | |||
345 | env, | 348 | env, |
346 | krate, | 349 | krate, |
347 | traits_in_scope, | 350 | traits_in_scope, |
351 | visible_from_module, | ||
348 | name, | 352 | name, |
349 | mode, | 353 | mode, |
350 | &mut |ty, item| { | 354 | &mut |ty, item| { |
@@ -362,6 +366,7 @@ fn iterate_method_candidates_impl( | |||
362 | env: Arc<TraitEnvironment>, | 366 | env: Arc<TraitEnvironment>, |
363 | krate: CrateId, | 367 | krate: CrateId, |
364 | traits_in_scope: &FxHashSet<TraitId>, | 368 | traits_in_scope: &FxHashSet<TraitId>, |
369 | visible_from_module: Option<ModuleId>, | ||
365 | name: Option<&Name>, | 370 | name: Option<&Name>, |
366 | mode: LookupMode, | 371 | mode: LookupMode, |
367 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 372 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
@@ -399,6 +404,7 @@ fn iterate_method_candidates_impl( | |||
399 | env.clone(), | 404 | env.clone(), |
400 | krate, | 405 | krate, |
401 | traits_in_scope, | 406 | traits_in_scope, |
407 | visible_from_module, | ||
402 | name, | 408 | name, |
403 | callback, | 409 | callback, |
404 | ) { | 410 | ) { |
@@ -415,6 +421,7 @@ fn iterate_method_candidates_impl( | |||
415 | env, | 421 | env, |
416 | krate, | 422 | krate, |
417 | traits_in_scope, | 423 | traits_in_scope, |
424 | visible_from_module, | ||
418 | name, | 425 | name, |
419 | callback, | 426 | callback, |
420 | ) | 427 | ) |
@@ -428,6 +435,7 @@ fn iterate_method_candidates_with_autoref( | |||
428 | env: Arc<TraitEnvironment>, | 435 | env: Arc<TraitEnvironment>, |
429 | krate: CrateId, | 436 | krate: CrateId, |
430 | traits_in_scope: &FxHashSet<TraitId>, | 437 | traits_in_scope: &FxHashSet<TraitId>, |
438 | visible_from_module: Option<ModuleId>, | ||
431 | name: Option<&Name>, | 439 | name: Option<&Name>, |
432 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 440 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
433 | ) -> bool { | 441 | ) -> bool { |
@@ -438,6 +446,7 @@ fn iterate_method_candidates_with_autoref( | |||
438 | env.clone(), | 446 | env.clone(), |
439 | krate, | 447 | krate, |
440 | &traits_in_scope, | 448 | &traits_in_scope, |
449 | visible_from_module, | ||
441 | name, | 450 | name, |
442 | &mut callback, | 451 | &mut callback, |
443 | ) { | 452 | ) { |
@@ -454,6 +463,7 @@ fn iterate_method_candidates_with_autoref( | |||
454 | env.clone(), | 463 | env.clone(), |
455 | krate, | 464 | krate, |
456 | &traits_in_scope, | 465 | &traits_in_scope, |
466 | visible_from_module, | ||
457 | name, | 467 | name, |
458 | &mut callback, | 468 | &mut callback, |
459 | ) { | 469 | ) { |
@@ -470,6 +480,7 @@ fn iterate_method_candidates_with_autoref( | |||
470 | env, | 480 | env, |
471 | krate, | 481 | krate, |
472 | &traits_in_scope, | 482 | &traits_in_scope, |
483 | visible_from_module, | ||
473 | name, | 484 | name, |
474 | &mut callback, | 485 | &mut callback, |
475 | ) { | 486 | ) { |
@@ -485,6 +496,7 @@ fn iterate_method_candidates_by_receiver( | |||
485 | env: Arc<TraitEnvironment>, | 496 | env: Arc<TraitEnvironment>, |
486 | krate: CrateId, | 497 | krate: CrateId, |
487 | traits_in_scope: &FxHashSet<TraitId>, | 498 | traits_in_scope: &FxHashSet<TraitId>, |
499 | visible_from_module: Option<ModuleId>, | ||
488 | name: Option<&Name>, | 500 | name: Option<&Name>, |
489 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 501 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
490 | ) -> bool { | 502 | ) -> bool { |
@@ -492,7 +504,15 @@ fn iterate_method_candidates_by_receiver( | |||
492 | // be found in any of the derefs of receiver_ty, so we have to go through | 504 | // be found in any of the derefs of receiver_ty, so we have to go through |
493 | // that. | 505 | // that. |
494 | for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) { | 506 | for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) { |
495 | if iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback) { | 507 | if iterate_inherent_methods( |
508 | self_ty, | ||
509 | db, | ||
510 | name, | ||
511 | Some(receiver_ty), | ||
512 | krate, | ||
513 | visible_from_module, | ||
514 | &mut callback, | ||
515 | ) { | ||
496 | return true; | 516 | return true; |
497 | } | 517 | } |
498 | } | 518 | } |
@@ -519,10 +539,12 @@ fn iterate_method_candidates_for_self_ty( | |||
519 | env: Arc<TraitEnvironment>, | 539 | env: Arc<TraitEnvironment>, |
520 | krate: CrateId, | 540 | krate: CrateId, |
521 | traits_in_scope: &FxHashSet<TraitId>, | 541 | traits_in_scope: &FxHashSet<TraitId>, |
542 | visible_from_module: Option<ModuleId>, | ||
522 | name: Option<&Name>, | 543 | name: Option<&Name>, |
523 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 544 | mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
524 | ) -> bool { | 545 | ) -> bool { |
525 | if iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) { | 546 | if iterate_inherent_methods(self_ty, db, name, None, krate, visible_from_module, &mut callback) |
547 | { | ||
526 | return true; | 548 | return true; |
527 | } | 549 | } |
528 | iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback) | 550 | iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback) |
@@ -559,7 +581,9 @@ fn iterate_trait_method_candidates( | |||
559 | // iteration | 581 | // iteration |
560 | let mut known_implemented = false; | 582 | let mut known_implemented = false; |
561 | for (_name, item) in data.items.iter() { | 583 | for (_name, item) in data.items.iter() { |
562 | if !is_valid_candidate(db, name, receiver_ty, *item, self_ty) { | 584 | // Don't pass a `visible_from_module` down to `is_valid_candidate`, |
585 | // since only inherent methods should be included into visibility checking. | ||
586 | if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) { | ||
563 | continue; | 587 | continue; |
564 | } | 588 | } |
565 | if !known_implemented { | 589 | if !known_implemented { |
@@ -583,6 +607,7 @@ fn iterate_inherent_methods( | |||
583 | name: Option<&Name>, | 607 | name: Option<&Name>, |
584 | receiver_ty: Option<&Canonical<Ty>>, | 608 | receiver_ty: Option<&Canonical<Ty>>, |
585 | krate: CrateId, | 609 | krate: CrateId, |
610 | visible_from_module: Option<ModuleId>, | ||
586 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 611 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
587 | ) -> bool { | 612 | ) -> bool { |
588 | let def_crates = match self_ty.value.def_crates(db, krate) { | 613 | let def_crates = match self_ty.value.def_crates(db, krate) { |
@@ -594,7 +619,7 @@ fn iterate_inherent_methods( | |||
594 | 619 | ||
595 | for &impl_def in impls.for_self_ty(&self_ty.value) { | 620 | for &impl_def in impls.for_self_ty(&self_ty.value) { |
596 | for &item in db.impl_data(impl_def).items.iter() { | 621 | for &item in db.impl_data(impl_def).items.iter() { |
597 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty) { | 622 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty, visible_from_module) { |
598 | continue; | 623 | continue; |
599 | } | 624 | } |
600 | // we have to check whether the self type unifies with the type | 625 | // we have to check whether the self type unifies with the type |
@@ -639,6 +664,7 @@ fn is_valid_candidate( | |||
639 | receiver_ty: Option<&Canonical<Ty>>, | 664 | receiver_ty: Option<&Canonical<Ty>>, |
640 | item: AssocItemId, | 665 | item: AssocItemId, |
641 | self_ty: &Canonical<Ty>, | 666 | self_ty: &Canonical<Ty>, |
667 | visible_from_module: Option<ModuleId>, | ||
642 | ) -> bool { | 668 | ) -> bool { |
643 | match item { | 669 | match item { |
644 | AssocItemId::FunctionId(m) => { | 670 | AssocItemId::FunctionId(m) => { |
@@ -660,6 +686,13 @@ fn is_valid_candidate( | |||
660 | return false; | 686 | return false; |
661 | } | 687 | } |
662 | } | 688 | } |
689 | if let Some(from_module) = visible_from_module { | ||
690 | if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) { | ||
691 | cov_mark::hit!(autoderef_candidate_not_visible); | ||
692 | return false; | ||
693 | } | ||
694 | } | ||
695 | |||
663 | true | 696 | true |
664 | } | 697 | } |
665 | AssocItemId::ConstId(c) => { | 698 | AssocItemId::ConstId(c) => { |