@@ -709,6 +709,33 @@ fn iterate_trait_method_candidates(
709
709
false
710
710
}
711
711
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
+
712
739
fn iterate_inherent_methods (
713
740
self_ty : & Canonical < Ty > ,
714
741
db : & dyn HirDatabase ,
@@ -726,25 +753,7 @@ fn iterate_inherent_methods(
726
753
for krate in def_crates {
727
754
let impls = db. inherent_impls_in_crate ( krate) ;
728
755
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 ) ;
748
757
749
758
for & impl_def in impls_for_self_ty {
750
759
for & item in db. impl_data ( impl_def) . items . iter ( ) {
@@ -798,6 +807,28 @@ pub fn resolve_indexing_op(
798
807
None
799
808
}
800
809
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
+
801
832
fn is_valid_candidate (
802
833
db : & dyn HirDatabase ,
803
834
env : Arc < TraitEnvironment > ,
@@ -823,21 +854,9 @@ fn is_valid_candidate(
823
854
Some ( ty) => ty,
824
855
None => return false ,
825
856
} ;
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 ;
841
860
}
842
861
}
843
862
if let Some ( from_module) = visible_from_module {
0 commit comments