@@ -821,24 +821,38 @@ pub fn associated_type_shorthand_candidates<R>(
821
821
res : TypeNs ,
822
822
mut cb : impl FnMut ( & Name , & TraitRef , TypeAliasId ) -> Option < R > ,
823
823
) -> Option < R > {
824
- let traits_from_env: Vec < _ > = match res {
825
- TypeNs :: SelfType ( impl_id) => match db. impl_trait ( impl_id) {
826
- None => vec ! [ ] ,
827
- // FIXME: how to correctly handle higher-ranked bounds here?
828
- Some ( trait_ref) => vec ! [ trait_ref. value. shift_bound_vars_out( DebruijnIndex :: ONE ) ] ,
829
- } ,
824
+ let mut search = |t| {
825
+ for t in all_super_trait_refs ( db, t) {
826
+ let data = db. trait_data ( t. hir_trait_id ( ) ) ;
827
+
828
+ for ( name, assoc_id) in & data. items {
829
+ if let AssocItemId :: TypeAliasId ( alias) = assoc_id {
830
+ if let Some ( result) = cb ( name, & t, * alias) {
831
+ return Some ( result) ;
832
+ }
833
+ }
834
+ }
835
+ }
836
+ None
837
+ } ;
838
+
839
+ match res {
840
+ // FIXME: how to correctly handle higher-ranked bounds here?
841
+ TypeNs :: SelfType ( impl_id) => {
842
+ search ( db. impl_trait ( impl_id) ?. value . shift_bound_vars_out ( DebruijnIndex :: ONE ) )
843
+ }
830
844
TypeNs :: GenericParam ( param_id) => {
831
845
let predicates = db. generic_predicates_for_param ( param_id) ;
832
- let mut traits_ : Vec < _ > = predicates
833
- . iter ( )
834
- . filter_map ( |pred| match & pred . value . value {
835
- // FIXME: how to correctly handle higher-ranked bounds here?
836
- WhereClause :: Implemented ( tr ) => {
837
- Some ( tr . clone ( ) . shift_bound_vars_out ( DebruijnIndex :: ONE ) )
838
- }
839
- _ => None ,
840
- } )
841
- . collect ( ) ;
846
+ let res = predicates. iter ( ) . find_map ( |pred| match & pred . value . value {
847
+ // FIXME: how to correctly handle higher-ranked bounds here?
848
+ WhereClause :: Implemented ( tr ) => {
849
+ search ( tr . clone ( ) . shift_bound_vars_out ( DebruijnIndex :: ONE ) )
850
+ }
851
+ _ => None ,
852
+ } ) ;
853
+ if let res @ Some ( _ ) = res {
854
+ return res ;
855
+ }
842
856
// Handle `Self::Type` referring to own associated type in trait definitions
843
857
if let GenericDefId :: TraitId ( trait_id) = param_id. parent {
844
858
let generics = generics ( db. upcast ( ) , trait_id. into ( ) ) ;
@@ -849,30 +863,13 @@ pub fn associated_type_shorthand_candidates<R>(
849
863
trait_id : to_chalk_trait_id ( trait_id) ,
850
864
substitution : Substitution :: bound_vars ( & generics, DebruijnIndex :: INNERMOST ) ,
851
865
} ;
852
- traits_ . push ( trait_ref) ;
866
+ return search ( trait_ref) ;
853
867
}
854
868
}
855
- traits_
856
- }
857
- _ => vec ! [ ] ,
858
- } ;
859
-
860
- for t in traits_from_env. into_iter ( ) . flat_map ( move |t| all_super_trait_refs ( db, t) ) {
861
- let data = db. trait_data ( t. hir_trait_id ( ) ) ;
862
-
863
- for ( name, assoc_id) in & data. items {
864
- match assoc_id {
865
- AssocItemId :: TypeAliasId ( alias) => {
866
- if let Some ( result) = cb ( name, & t, * alias) {
867
- return Some ( result) ;
868
- }
869
- }
870
- AssocItemId :: FunctionId ( _) | AssocItemId :: ConstId ( _) => { }
871
- }
869
+ None
872
870
}
871
+ _ => None ,
873
872
}
874
-
875
- None
876
873
}
877
874
878
875
/// Build the type of all specific fields of a struct or enum variant.
0 commit comments