aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r--crates/hir_ty/src/method_resolution.rs41
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) => {