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_ty/src/method_resolution.rs | 35 ++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'crates/hir_ty/src/method_resolution.rs') 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 From ac2a831b2e61a5a3ef5edd20791b4b2db48402b2 Mon Sep 17 00:00:00 2001 From: cynecx Date: Sat, 20 Mar 2021 19:48:35 +0100 Subject: hir_ty: iterate_method_candidates_for_self_ty pass `visible_from_module` down to `iterate_inherent_methods` --- crates/hir_ty/src/method_resolution.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'crates/hir_ty/src/method_resolution.rs') diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 6c34982a1..80e7b7b79 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -420,6 +420,7 @@ fn iterate_method_candidates_impl( env, krate, traits_in_scope, + visible_from_module, name, callback, ) @@ -537,10 +538,12 @@ fn iterate_method_candidates_for_self_ty( env: Arc, krate: CrateId, traits_in_scope: &FxHashSet, + visible_from_module: Option, name: Option<&Name>, mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, ) -> bool { - if iterate_inherent_methods(self_ty, db, name, None, krate, None, &mut callback) { + if iterate_inherent_methods(self_ty, db, name, None, krate, visible_from_module, &mut callback) + { return true; } iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback) @@ -577,6 +580,8 @@ fn iterate_trait_method_candidates( // iteration let mut known_implemented = false; for (_name, item) in data.items.iter() { + // Don't pass a `visible_from_module` down to `is_valid_candidate`, + // since only inherent methods should be included into visibility checking. if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) { continue; } -- cgit v1.2.3 From 42abfa0f885834c3c2bf61a4d0fafaa3f570debd Mon Sep 17 00:00:00 2001 From: cynecx Date: Sat, 20 Mar 2021 20:35:57 +0100 Subject: hir_ty: add coverage testing for autoderef_visibility_method test --- crates/hir_ty/src/method_resolution.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/hir_ty/src/method_resolution.rs') diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 80e7b7b79..f91208068 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -687,6 +687,7 @@ fn is_valid_candidate( } if let Some(from_module) = visible_from_module { if !db.fn_visibility(m).is_visible_from(db.upcast(), from_module) { + cov_mark::hit!(autoderef_candidate_not_visible); return false; } } -- cgit v1.2.3 From 96c88680b2d680f42809f838e79213e087d1fa1c Mon Sep 17 00:00:00 2001 From: cynecx Date: Wed, 24 Mar 2021 22:59:59 +0100 Subject: hir_def: move visibility queries from hir_ty to hir_def --- crates/hir_ty/src/method_resolution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/hir_ty/src/method_resolution.rs') diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index f91208068..54192ec30 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -686,7 +686,7 @@ fn is_valid_candidate( } } if let Some(from_module) = visible_from_module { - if !db.fn_visibility(m).is_visible_from(db.upcast(), from_module) { + if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) { cov_mark::hit!(autoderef_candidate_not_visible); return false; } -- cgit v1.2.3