Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/method_resolution.rs')
-rw-r--r--crates/hir-ty/src/method_resolution.rs124
1 files changed, 71 insertions, 53 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index cec6356633..1e30897362 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -489,9 +489,8 @@ pub fn def_crates<'db>(
/// Look up the method with the given name.
pub(crate) fn lookup_method<'db>(
- db: &'db dyn HirDatabase,
ty: &Canonical<'db, Ty<'db>>,
- env: Arc<TraitEnvironment<'db>>,
+ table: &mut InferenceTable<'db>,
traits_in_scope: &FxHashSet<TraitId>,
visible_from_module: VisibleFromModule,
name: &Name,
@@ -499,8 +498,7 @@ pub(crate) fn lookup_method<'db>(
let mut not_visible = None;
let res = iterate_method_candidates(
ty,
- db,
- env,
+ table,
traits_in_scope,
visible_from_module,
Some(name),
@@ -656,8 +654,7 @@ impl ReceiverAdjustments {
// FIXME add a context type here?
pub(crate) fn iterate_method_candidates<'db, T>(
ty: &Canonical<'db, Ty<'db>>,
- db: &'db dyn HirDatabase,
- env: Arc<TraitEnvironment<'db>>,
+ table: &mut InferenceTable<'db>,
traits_in_scope: &FxHashSet<TraitId>,
visible_from_module: VisibleFromModule,
name: Option<&Name>,
@@ -665,10 +662,9 @@ pub(crate) fn iterate_method_candidates<'db, T>(
mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>,
) -> Option<T> {
let mut slot = None;
- _ = iterate_method_candidates_dyn(
+ _ = iterate_method_candidates_dyn_impl(
ty,
- db,
- env,
+ table,
traits_in_scope,
visible_from_module,
name,
@@ -985,6 +981,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
is_not_orphan
}
+/// To be used from `hir` only.
pub fn iterate_path_candidates<'db>(
ty: &Canonical<'db, Ty<'db>>,
db: &'db dyn HirDatabase,
@@ -1007,6 +1004,7 @@ pub fn iterate_path_candidates<'db>(
)
}
+/// To be used from `hir` only.
pub fn iterate_method_candidates_dyn<'db>(
ty: &Canonical<'db, Ty<'db>>,
db: &'db dyn HirDatabase,
@@ -1017,6 +1015,26 @@ pub fn iterate_method_candidates_dyn<'db>(
mode: LookupMode,
callback: &mut dyn MethodCandidateCallback,
) -> ControlFlow<()> {
+ iterate_method_candidates_dyn_impl(
+ ty,
+ &mut InferenceTable::new(db, env, None),
+ traits_in_scope,
+ visible_from_module,
+ name,
+ mode,
+ callback,
+ )
+}
+
+fn iterate_method_candidates_dyn_impl<'db>(
+ ty: &Canonical<'db, Ty<'db>>,
+ table: &mut InferenceTable<'db>,
+ traits_in_scope: &FxHashSet<TraitId>,
+ visible_from_module: VisibleFromModule,
+ name: Option<&Name>,
+ mode: LookupMode,
+ callback: &mut dyn MethodCandidateCallback,
+) -> ControlFlow<()> {
let _p = tracing::info_span!(
"iterate_method_candidates_dyn",
?mode,
@@ -1046,28 +1064,28 @@ pub fn iterate_method_candidates_dyn<'db>(
// the methods by autoderef order of *receiver types*, not *self
// types*.
- let mut table = InferenceTable::new(db, env);
- let ty = table.instantiate_canonical(*ty);
- let deref_chain = autoderef_method_receiver(&mut table, ty);
-
- deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
- iterate_method_candidates_with_autoref(
- &mut table,
- receiver_ty,
- adj,
- traits_in_scope,
- visible_from_module,
- name,
- callback,
- )
+ table.run_in_snapshot(|table| {
+ let ty = table.instantiate_canonical(*ty);
+ let deref_chain = autoderef_method_receiver(table, ty);
+
+ deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
+ iterate_method_candidates_with_autoref(
+ table,
+ receiver_ty,
+ adj,
+ traits_in_scope,
+ visible_from_module,
+ name,
+ callback,
+ )
+ })
})
}
LookupMode::Path => {
// No autoderef for path lookups
iterate_method_candidates_for_self_ty(
ty,
- db,
- env,
+ table,
traits_in_scope,
visible_from_module,
name,
@@ -1250,39 +1268,39 @@ fn iterate_method_candidates_by_receiver<'db>(
#[tracing::instrument(skip_all, fields(name = ?name))]
fn iterate_method_candidates_for_self_ty<'db>(
self_ty: &Canonical<'db, Ty<'db>>,
- db: &'db dyn HirDatabase,
- env: Arc<TraitEnvironment<'db>>,
+ table: &mut InferenceTable<'db>,
traits_in_scope: &FxHashSet<TraitId>,
visible_from_module: VisibleFromModule,
name: Option<&Name>,
callback: &mut dyn MethodCandidateCallback,
) -> ControlFlow<()> {
- let mut table = InferenceTable::new(db, env);
- let self_ty = table.instantiate_canonical(*self_ty);
- iterate_inherent_methods(
- self_ty,
- &mut table,
- name,
- None,
- None,
- visible_from_module,
- LookupMode::Path,
- &mut |adjustments, item, is_visible| {
- callback.on_inherent_method(adjustments, item, is_visible)
- },
- )?;
- iterate_trait_method_candidates(
- self_ty,
- &mut table,
- traits_in_scope,
- name,
- None,
- None,
- LookupMode::Path,
- &mut |adjustments, item, is_visible| {
- callback.on_trait_method(adjustments, item, is_visible)
- },
- )
+ table.run_in_snapshot(|table| {
+ let self_ty = table.instantiate_canonical(*self_ty);
+ iterate_inherent_methods(
+ self_ty,
+ table,
+ name,
+ None,
+ None,
+ visible_from_module,
+ LookupMode::Path,
+ &mut |adjustments, item, is_visible| {
+ callback.on_inherent_method(adjustments, item, is_visible)
+ },
+ )?;
+ iterate_trait_method_candidates(
+ self_ty,
+ table,
+ traits_in_scope,
+ name,
+ None,
+ None,
+ LookupMode::Path,
+ &mut |adjustments, item, is_visible| {
+ callback.on_trait_method(adjustments, item, is_visible)
+ },
+ )
+ })
}
#[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]