@@ -531,40 +531,61 @@ fn trait_applicable_items(
531
531
} )
532
532
. collect ( ) ;
533
533
534
- trait_candidates. retain ( |& candidate_trait_id| {
535
- // we care about the following cases:
536
- // 1. Trait's definition crate
537
- // 2. Definition crates for all trait's generic arguments
538
- // a. This is recursive for fundamental types: `Into<Box<A>> for ()`` is OK, but
539
- // `Into<Vec<A>> for ()`` is *not*.
540
- // 3. Receiver type definition crate
541
- // a. This is recursive for fundamental types
542
- let defining_crate_for_trait = Trait :: from ( candidate_trait_id) . krate ( db) ;
543
- let Some ( receiver) = trait_candidate. receiver_ty . fingerprint_for_trait_impl ( ) else {
544
- return false ;
545
- } ;
546
-
547
- // in order to handle implied bounds through an associated type, keep any
548
- // method receiver that matches `TyFingerprint::Unnameable`. this receiver
549
- // won't be in `TraitImpls` anyways, as `TraitImpls` only contains actual
550
- // implementations.
551
- if matches ! ( receiver, TyFingerprint :: Unnameable ) {
552
- return true ;
534
+ let autoderef_method_receiver = {
535
+ let mut deref_chain = trait_candidate. receiver_ty . autoderef ( db) . collect :: < Vec < _ > > ( ) ;
536
+ // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
537
+ if let Some ( ( ty, _len) ) = deref_chain. last ( ) . and_then ( |ty| ty. as_array ( db) ) {
538
+ let slice = Type :: new_slice ( ty) ;
539
+ deref_chain. push ( slice) ;
553
540
}
541
+ deref_chain
542
+ . into_iter ( )
543
+ . filter_map ( |ty| Some ( ( ty. krate ( db) . into ( ) , ty. fingerprint_for_trait_impl ( ) ?) ) )
544
+ . sorted ( )
545
+ . unique ( )
546
+ . collect :: < Vec < _ > > ( )
547
+ } ;
554
548
555
- let definitions_exist_in_trait_crate = db
556
- . trait_impls_in_crate ( defining_crate_for_trait. into ( ) )
557
- . has_impls_for_trait_and_self_ty ( candidate_trait_id, receiver) ;
549
+ // can be empty if the entire deref chain is has no valid trait impl fingerprints
550
+ if autoderef_method_receiver. is_empty ( ) {
551
+ return Default :: default ( ) ;
552
+ }
558
553
559
- // this is a closure for laziness: if `definitions_exist_in_trait_crate` is true,
560
- // we can avoid a second db lookup.
561
- let definitions_exist_in_receiver_crate = || {
562
- db. trait_impls_in_crate ( trait_candidate. receiver_ty . krate ( db) . into ( ) )
563
- . has_impls_for_trait_and_self_ty ( candidate_trait_id, receiver)
564
- } ;
554
+ // in order to handle implied bounds through an associated type, keep all traits if any
555
+ // type in the deref chain matches `TyFingerprint::Unnameable`. This fingerprint
556
+ // won't be in `TraitImpls` anyways, as `TraitImpls` only contains actual implementations.
557
+ if !autoderef_method_receiver
558
+ . iter ( )
559
+ . any ( |( _, fingerprint) | matches ! ( fingerprint, TyFingerprint :: Unnameable ) )
560
+ {
561
+ trait_candidates. retain ( |& candidate_trait_id| {
562
+ // we care about the following cases:
563
+ // 1. Trait's definition crate
564
+ // 2. Definition crates for all trait's generic arguments
565
+ // a. This is recursive for fundamental types: `Into<Box<A>> for ()`` is OK, but
566
+ // `Into<Vec<A>> for ()`` is *not*.
567
+ // 3. Receiver type definition crate
568
+ // a. This is recursive for fundamental types
569
+ let defining_crate_for_trait = Trait :: from ( candidate_trait_id) . krate ( db) ;
570
+
571
+ let trait_impls_in_crate = db. trait_impls_in_crate ( defining_crate_for_trait. into ( ) ) ;
572
+ let definitions_exist_in_trait_crate =
573
+ autoderef_method_receiver. iter ( ) . any ( |& ( _, fingerprint) | {
574
+ trait_impls_in_crate
575
+ . has_impls_for_trait_and_self_ty ( candidate_trait_id, fingerprint)
576
+ } ) ;
577
+ // this is a closure for laziness: if `definitions_exist_in_trait_crate` is true,
578
+ // we can avoid a second db lookup.
579
+ let definitions_exist_in_receiver_crate = || {
580
+ autoderef_method_receiver. iter ( ) . any ( |& ( krate, fingerprint) | {
581
+ db. trait_impls_in_crate ( krate)
582
+ . has_impls_for_trait_and_self_ty ( candidate_trait_id, fingerprint)
583
+ } )
584
+ } ;
565
585
566
- definitions_exist_in_trait_crate || definitions_exist_in_receiver_crate ( )
567
- } ) ;
586
+ definitions_exist_in_trait_crate || definitions_exist_in_receiver_crate ( )
587
+ } ) ;
588
+ }
568
589
569
590
let mut located_imports = FxIndexSet :: default ( ) ;
570
591
let mut trait_import_paths = FxHashMap :: default ( ) ;
0 commit comments