@@ -709,6 +709,33 @@ fn iterate_trait_method_candidates(
709709 false
710710}
711711
712+ fn filter_inherent_impls_for_self_ty < ' i > (
713+ impls : & ' i InherentImpls ,
714+ self_ty : & Ty ,
715+ ) -> impl Iterator < Item = & ' i ImplId > {
716+ // inherent methods on arrays are fingerprinted as [T; {unknown}], so we must also consider them when
717+ // resolving a method call on an array with a known len
718+ let array_impls = {
719+ if let TyKind :: Array ( parameters, array_len) = self_ty. kind ( & Interner ) {
720+ if !array_len. is_unknown ( ) {
721+ let unknown_array_len_ty =
722+ TyKind :: Array ( parameters. clone ( ) , consteval:: usize_const ( None ) )
723+ . intern ( & Interner ) ;
724+
725+ Some ( impls. for_self_ty ( & unknown_array_len_ty) )
726+ } else {
727+ None
728+ }
729+ } else {
730+ None
731+ }
732+ }
733+ . into_iter ( )
734+ . flatten ( ) ;
735+
736+ impls. for_self_ty ( self_ty) . iter ( ) . chain ( array_impls)
737+ }
738+
712739fn iterate_inherent_methods (
713740 self_ty : & Canonical < Ty > ,
714741 db : & dyn HirDatabase ,
@@ -726,25 +753,7 @@ fn iterate_inherent_methods(
726753 for krate in def_crates {
727754 let impls = db. inherent_impls_in_crate ( krate) ;
728755
729- let impls_for_self_ty = impls. for_self_ty ( & self_ty. value ) . iter ( ) . chain (
730- {
731- if let TyKind :: Array ( parameters, array_len) = self_ty. value . kind ( & Interner ) {
732- if !array_len. is_unknown ( ) {
733- let unknown_array_len_ty =
734- TyKind :: Array ( parameters. clone ( ) , consteval:: usize_const ( None ) )
735- . intern ( & Interner ) ;
736-
737- Some ( impls. for_self_ty ( & unknown_array_len_ty) )
738- } else {
739- None
740- }
741- } else {
742- None
743- }
744- }
745- . into_iter ( )
746- . flatten ( ) ,
747- ) ;
756+ let impls_for_self_ty = filter_inherent_impls_for_self_ty ( & impls, & self_ty. value ) ;
748757
749758 for & impl_def in impls_for_self_ty {
750759 for & item in db. impl_data ( impl_def) . items . iter ( ) {
@@ -798,6 +807,28 @@ pub fn resolve_indexing_op(
798807 None
799808}
800809
810+ fn is_transformed_receiver_ty_equal ( transformed_receiver_ty : & Ty , receiver_ty : & Ty ) -> bool {
811+ if transformed_receiver_ty == receiver_ty {
812+ return true ;
813+ }
814+
815+ // a transformed receiver may be considered equal (and a valid method call candidate) if it is an array
816+ // with an unknown (i.e. generic) length, and the receiver is an array with the same item type but a known len,
817+ // this allows inherent methods on arrays to be considered valid resolution candidates
818+ match ( transformed_receiver_ty. kind ( & Interner ) , receiver_ty. kind ( & Interner ) ) {
819+ (
820+ TyKind :: Array ( transformed_array_ty, transformed_array_len) ,
821+ TyKind :: Array ( receiver_array_ty, receiver_array_len) ,
822+ ) if transformed_array_ty == receiver_array_ty
823+ && transformed_array_len. is_unknown ( )
824+ && !receiver_array_len. is_unknown ( ) =>
825+ {
826+ true
827+ }
828+ _ => false ,
829+ }
830+ }
831+
801832fn is_valid_candidate (
802833 db : & dyn HirDatabase ,
803834 env : Arc < TraitEnvironment > ,
@@ -823,21 +854,9 @@ fn is_valid_candidate(
823854 Some ( ty) => ty,
824855 None => return false ,
825856 } ;
826- if transformed_receiver_ty != receiver_ty. value {
827- match (
828- transformed_receiver_ty. kind ( & Interner ) ,
829- receiver_ty. value . kind ( & Interner ) ,
830- ) {
831- (
832- TyKind :: Array ( transformed_array_ty, transformed_array_len) ,
833- TyKind :: Array ( receiver_array_ty, receiver_array_len) ,
834- ) if transformed_array_ty == receiver_array_ty
835- && transformed_array_len. is_unknown ( )
836- && !receiver_array_len. is_unknown ( ) => { }
837- _ => {
838- return false ;
839- }
840- }
857+
858+ if !is_transformed_receiver_ty_equal ( & transformed_receiver_ty, & receiver_ty. value ) {
859+ return false ;
841860 }
842861 }
843862 if let Some ( from_module) = visible_from_module {
0 commit comments