From 34bb13e293e757bb7267eb76884caacb4b94b48b Mon Sep 17 00:00:00 2001 From: cynecx Date: Sat, 20 Mar 2021 19:28:26 +0100 Subject: hir_ty: introduce visible_from_module param into method resolution --- crates/hir/src/lib.rs | 7 +++++++ crates/hir_ty/src/infer/expr.rs | 1 + crates/hir_ty/src/infer/path.rs | 1 + crates/hir_ty/src/method_resolution.rs | 35 ++++++++++++++++++++++++++++++---- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 30e577671..1a65a5cad 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1967,12 +1967,18 @@ impl Type { let env = self.ty.environment.clone(); let krate = krate.id; + let from_module = match self.as_adt() { + Some(adt) => Some(adt.module(db).id), + None => None, + }; + method_resolution::iterate_method_candidates( &canonical, db, env, krate, traits_in_scope, + from_module, name, method_resolution::LookupMode::MethodCall, |ty, it| match it { @@ -2004,6 +2010,7 @@ impl Type { env, krate, traits_in_scope, + None, name, method_resolution::LookupMode::Path, |ty, it| callback(ty, it.into()), diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 9bf9f87e4..b08880cdf 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -849,6 +849,7 @@ impl<'a> InferenceContext<'a> { self.trait_env.clone(), krate, &traits_in_scope, + self.resolver.module(), method_name, ) }); diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 58cce56ab..cefa38509 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs @@ -230,6 +230,7 @@ impl<'a> InferenceContext<'a> { self.trait_env.clone(), krate, &traits_in_scope, + None, Some(name), method_resolution::LookupMode::Path, move |_ty, item| { diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index da6bc2a4a..6c34982a1 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -295,6 +295,7 @@ pub(crate) fn lookup_method( env: Arc, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, 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( env: Arc, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, name: Option<&Name>, mode: LookupMode, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, @@ -344,6 +347,7 @@ pub fn iterate_method_candidates( env, krate, traits_in_scope, + visible_from_module, name, mode, &mut |ty, item| { @@ -361,6 +365,7 @@ fn iterate_method_candidates_impl( env: Arc, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, 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, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, 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, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, 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>, krate: CrateId, + visible_from_module: Option, 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>, item: AssocItemId, self_ty: &Canonical, + visible_from_module: Option, ) -> 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) => { -- cgit v1.2.3