]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/method_resolution.rs
hir_ty: introduce visible_from_module param into method resolution
[rust.git] / crates / hir_ty / src / method_resolution.rs
index da6bc2a4a174ad038ce34b0fdde96a6a21efc2f0..6c34982a1892d70b55fcb53452e0dcec108f5b9d 100644 (file)
@@ -295,6 +295,7 @@ pub(crate) fn lookup_method(
     env: Arc<TraitEnvironment>,
     krate: CrateId,
     traits_in_scope: &FxHashSet<TraitId>,
+    visible_from_module: Option<ModuleId>,
     name: &Name,
 ) -> Option<(Ty, FunctionId)> {
     iterate_method_candidates(
@@ -303,6 +304,7 @@ pub(crate) fn lookup_method(
         env,
         krate,
         &traits_in_scope,
+        visible_from_module,
         Some(name),
         LookupMode::MethodCall,
         |ty, f| match f {
@@ -333,6 +335,7 @@ pub fn iterate_method_candidates<T>(
     env: Arc<TraitEnvironment>,
     krate: CrateId,
     traits_in_scope: &FxHashSet<TraitId>,
+    visible_from_module: Option<ModuleId>,
     name: Option<&Name>,
     mode: LookupMode,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
@@ -344,6 +347,7 @@ pub fn iterate_method_candidates<T>(
         env,
         krate,
         traits_in_scope,
+        visible_from_module,
         name,
         mode,
         &mut |ty, item| {
@@ -361,6 +365,7 @@ fn iterate_method_candidates_impl(
     env: Arc<TraitEnvironment>,
     krate: CrateId,
     traits_in_scope: &FxHashSet<TraitId>,
+    visible_from_module: Option<ModuleId>,
     name: Option<&Name>,
     mode: LookupMode,
     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
@@ -398,6 +403,7 @@ fn iterate_method_candidates_impl(
                     env.clone(),
                     krate,
                     traits_in_scope,
+                    visible_from_module,
                     name,
                     callback,
                 ) {
@@ -427,6 +433,7 @@ fn iterate_method_candidates_with_autoref(
     env: Arc<TraitEnvironment>,
     krate: CrateId,
     traits_in_scope: &FxHashSet<TraitId>,
+    visible_from_module: Option<ModuleId>,
     name: Option<&Name>,
     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
 ) -> bool {
@@ -437,6 +444,7 @@ fn iterate_method_candidates_with_autoref(
         env.clone(),
         krate,
         &traits_in_scope,
+        visible_from_module,
         name,
         &mut callback,
     ) {
@@ -453,6 +461,7 @@ fn iterate_method_candidates_with_autoref(
         env.clone(),
         krate,
         &traits_in_scope,
+        visible_from_module,
         name,
         &mut callback,
     ) {
@@ -469,6 +478,7 @@ fn iterate_method_candidates_with_autoref(
         env,
         krate,
         &traits_in_scope,
+        visible_from_module,
         name,
         &mut callback,
     ) {
@@ -484,6 +494,7 @@ fn iterate_method_candidates_by_receiver(
     env: Arc<TraitEnvironment>,
     krate: CrateId,
     traits_in_scope: &FxHashSet<TraitId>,
+    visible_from_module: Option<ModuleId>,
     name: Option<&Name>,
     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
 ) -> bool {
@@ -491,7 +502,15 @@ fn iterate_method_candidates_by_receiver(
     // be found in any of the derefs of receiver_ty, so we have to go through
     // that.
     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
-        if iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback) {
+        if iterate_inherent_methods(
+            self_ty,
+            db,
+            name,
+            Some(receiver_ty),
+            krate,
+            visible_from_module,
+            &mut callback,
+        ) {
             return true;
         }
     }
@@ -521,7 +540,7 @@ fn iterate_method_candidates_for_self_ty(
     name: Option<&Name>,
     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
 ) -> bool {
-    if iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) {
+    if iterate_inherent_methods(self_ty, db, name, None, krate, None, &mut callback) {
         return true;
     }
     iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
@@ -558,7 +577,7 @@ fn iterate_trait_method_candidates(
         // iteration
         let mut known_implemented = false;
         for (_name, item) in data.items.iter() {
-            if !is_valid_candidate(db, name, receiver_ty, *item, self_ty) {
+            if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) {
                 continue;
             }
             if !known_implemented {
@@ -582,6 +601,7 @@ fn iterate_inherent_methods(
     name: Option<&Name>,
     receiver_ty: Option<&Canonical<Ty>>,
     krate: CrateId,
+    visible_from_module: Option<ModuleId>,
     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
 ) -> bool {
     let def_crates = match self_ty.value.def_crates(db, krate) {
@@ -593,7 +613,7 @@ fn iterate_inherent_methods(
 
         for &impl_def in impls.for_self_ty(&self_ty.value) {
             for &item in db.impl_data(impl_def).items.iter() {
-                if !is_valid_candidate(db, name, receiver_ty, item, self_ty) {
+                if !is_valid_candidate(db, name, receiver_ty, item, self_ty, visible_from_module) {
                     continue;
                 }
                 // we have to check whether the self type unifies with the type
@@ -638,6 +658,7 @@ fn is_valid_candidate(
     receiver_ty: Option<&Canonical<Ty>>,
     item: AssocItemId,
     self_ty: &Canonical<Ty>,
+    visible_from_module: Option<ModuleId>,
 ) -> bool {
     match item {
         AssocItemId::FunctionId(m) => {
@@ -659,6 +680,12 @@ fn is_valid_candidate(
                     return false;
                 }
             }
+            if let Some(from_module) = visible_from_module {
+                if !db.fn_visibility(m).is_visible_from(db.upcast(), from_module) {
+                    return false;
+                }
+            }
+
             true
         }
         AssocItemId::ConstId(c) => {