aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/method_resolution.rs')
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs21
1 files changed, 19 insertions, 2 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index df5901835..7b0ff8161 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -20,7 +20,7 @@ use crate::{
20 db::HirDatabase, 20 db::HirDatabase,
21 primitive::{FloatBitness, Uncertain}, 21 primitive::{FloatBitness, Uncertain},
22 utils::all_super_traits, 22 utils::all_super_traits,
23 Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 23 ApplicationTy, Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
24}; 24};
25 25
26/// This is used as a key for indexing impls. 26/// This is used as a key for indexing impls.
@@ -214,7 +214,7 @@ pub fn iterate_method_candidates<T>(
214 // the methods by autoderef order of *receiver types*, not *self 214 // the methods by autoderef order of *receiver types*, not *self
215 // types*. 215 // types*.
216 216
217 let deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 217 let deref_chain = autoderef_method_receiver(db, krate, ty);
218 for i in 0..deref_chain.len() { 218 for i in 0..deref_chain.len() {
219 if let Some(result) = iterate_method_candidates_with_autoref( 219 if let Some(result) = iterate_method_candidates_with_autoref(
220 &deref_chain[i..], 220 &deref_chain[i..],
@@ -548,3 +548,20 @@ fn generic_implements_goal(
548 let obligation = super::Obligation::Trait(trait_ref); 548 let obligation = super::Obligation::Trait(trait_ref);
549 Canonical { num_vars, value: InEnvironment::new(env, obligation) } 549 Canonical { num_vars, value: InEnvironment::new(env, obligation) }
550} 550}
551
552fn autoderef_method_receiver(
553 db: &impl HirDatabase,
554 krate: CrateId,
555 ty: InEnvironment<Canonical<Ty>>,
556) -> Vec<Canonical<Ty>> {
557 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
558 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
559 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) =
560 deref_chain.last().map(|ty| &ty.value)
561 {
562 let num_vars = deref_chain.last().unwrap().num_vars;
563 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone());
564 deref_chain.push(Canonical { value: unsized_ty, num_vars })
565 }
566 deref_chain
567}