@@ -20,7 +20,7 @@ use crate::{
2020 db:: HirDatabase ,
2121 primitive:: { FloatBitness , Uncertain } ,
2222 utils:: all_super_traits,
23- Canonical , InEnvironment , TraitEnvironment , TraitRef , Ty , TypeCtor , TypeWalk ,
23+ ApplicationTy , Canonical , InEnvironment , TraitEnvironment , TraitRef , Ty , TypeCtor , TypeWalk ,
2424} ;
2525
2626/// This is used as a key for indexing impls.
@@ -214,7 +214,7 @@ pub fn iterate_method_candidates<T>(
214214 // the methods by autoderef order of *receiver types*, not *self
215215 // types*.
216216
217- let deref_chain: Vec < _ > = autoderef :: autoderef ( db, Some ( krate) , ty) . collect ( ) ;
217+ let deref_chain = autoderef_method_receiver ( db, krate, ty) ;
218218 for i in 0 ..deref_chain. len ( ) {
219219 if let Some ( result) = iterate_method_candidates_with_autoref (
220220 & deref_chain[ i..] ,
@@ -548,3 +548,20 @@ fn generic_implements_goal(
548548 let obligation = super :: Obligation :: Trait ( trait_ref) ;
549549 Canonical { num_vars, value : InEnvironment :: new ( env, obligation) }
550550}
551+
552+ fn 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+ }
0 commit comments