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.rs43
1 files changed, 19 insertions, 24 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 6af39828be..1549a40c91 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -541,9 +541,10 @@ pub fn iterate_method_candidates_dyn(
// types*.
let deref_chain = autoderef_method_receiver(db, krate, ty);
- for i in 0..deref_chain.len() {
+ let mut deref_chains = stdx::slice_tails(&deref_chain);
+ deref_chains.try_for_each(|deref_chain| {
iterate_method_candidates_with_autoref(
- &deref_chain[i..],
+ deref_chain,
db,
env.clone(),
krate,
@@ -551,9 +552,8 @@ pub fn iterate_method_candidates_dyn(
visible_from_module,
name,
callback,
- )?;
- }
- ControlFlow::Continue(())
+ )
+ })
}
LookupMode::Path => {
// No autoderef for path lookups
@@ -716,15 +716,14 @@ fn iterate_trait_method_candidates(
// if ty is `dyn Trait`, the trait doesn't need to be in scope
let inherent_trait =
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
- let env_traits = match self_ty.value.kind(&Interner) {
- TyKind::Placeholder(_) => {
- // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
+ let env_traits = matches!(self_ty.value.kind(&Interner), TyKind::Placeholder(_))
+ // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
+ .then(|| {
env.traits_in_scope_from_clauses(self_ty.value.clone())
.flat_map(|t| all_super_traits(db.upcast(), t))
- .collect()
- }
- _ => Vec::new(),
- };
+ })
+ .into_iter()
+ .flatten();
let traits = inherent_trait.chain(env_traits).chain(traits_in_scope.iter().copied());
'traits: for t in traits {
@@ -747,10 +746,10 @@ fn iterate_trait_method_candidates(
// trait, but if we find out it doesn't, we'll skip the rest of the
// iteration
let mut known_implemented = false;
- for (_name, item) in data.items.iter() {
+ for &(_, 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, env.clone(), name, receiver_ty, *item, self_ty, None) {
+ if !is_valid_candidate(db, env.clone(), name, receiver_ty, item, self_ty, None) {
continue;
}
if !known_implemented {
@@ -761,7 +760,7 @@ fn iterate_trait_method_candidates(
}
known_implemented = true;
// FIXME: we shouldn't be ignoring the binders here
- callback(self_ty, *item)?
+ callback(self_ty, item)?
}
}
ControlFlow::Continue(())
@@ -774,18 +773,14 @@ fn filter_inherent_impls_for_self_ty<'i>(
// inherent methods on arrays are fingerprinted as [T; {unknown}], so we must also consider them when
// resolving a method call on an array with a known len
let array_impls = {
- if let TyKind::Array(parameters, array_len) = self_ty.kind(&Interner) {
- if !array_len.is_unknown() {
+ match self_ty.kind(&Interner) {
+ TyKind::Array(parameters, array_len) if !array_len.is_unknown() => {
let unknown_array_len_ty =
- TyKind::Array(parameters.clone(), consteval::usize_const(None))
- .intern(&Interner);
+ TyKind::Array(parameters.clone(), consteval::usize_const(None));
- Some(impls.for_self_ty(&unknown_array_len_ty))
- } else {
- None
+ Some(impls.for_self_ty(&unknown_array_len_ty.intern(&Interner)))
}
- } else {
- None
+ _ => None,
}
}
.into_iter()