@@ -823,8 +823,9 @@ impl FunctionBody {
823
823
} ) ;
824
824
825
825
let parent = self . parent ( ) ?;
826
- let generic_param_lists = parent_generic_param_lists ( & parent) ;
827
- let where_clauses = parent_where_clauses ( & parent) ;
826
+ let parents = generic_parents ( & parent) ;
827
+ let generic_param_lists = parents. iter ( ) . filter_map ( |it| it. generic_param_list ( ) ) . collect ( ) ;
828
+ let where_clauses = parents. iter ( ) . filter_map ( |it| it. where_clause ( ) ) . collect ( ) ;
828
829
829
830
Some ( ContainerInfo {
830
831
is_in_tail,
@@ -990,24 +991,54 @@ impl FunctionBody {
990
991
}
991
992
}
992
993
993
- fn parent_where_clauses ( parent : & SyntaxNode ) -> Vec < ast:: WhereClause > {
994
- let mut where_clause: Vec < ast:: WhereClause > = parent
995
- . ancestors ( )
996
- . filter_map ( ast:: AnyHasGenericParams :: cast)
997
- . filter_map ( |it| it. where_clause ( ) )
998
- . collect ( ) ;
999
- where_clause. reverse ( ) ;
1000
- where_clause
994
+ enum GenericParent {
995
+ Fn ( ast:: Fn ) ,
996
+ Impl ( ast:: Impl ) ,
997
+ Trait ( ast:: Trait ) ,
1001
998
}
1002
999
1003
- fn parent_generic_param_lists ( parent : & SyntaxNode ) -> Vec < ast:: GenericParamList > {
1004
- let mut generic_param_list: Vec < ast:: GenericParamList > = parent
1005
- . ancestors ( )
1006
- . filter_map ( ast:: AnyHasGenericParams :: cast)
1007
- . filter_map ( |it| it. generic_param_list ( ) )
1008
- . collect ( ) ;
1009
- generic_param_list. reverse ( ) ;
1010
- generic_param_list
1000
+ impl GenericParent {
1001
+ fn generic_param_list ( & self ) -> Option < ast:: GenericParamList > {
1002
+ match self {
1003
+ GenericParent :: Fn ( fn_) => fn_. generic_param_list ( ) ,
1004
+ GenericParent :: Impl ( impl_) => impl_. generic_param_list ( ) ,
1005
+ GenericParent :: Trait ( trait_) => trait_. generic_param_list ( ) ,
1006
+ }
1007
+ }
1008
+
1009
+ fn where_clause ( & self ) -> Option < ast:: WhereClause > {
1010
+ match self {
1011
+ GenericParent :: Fn ( fn_) => fn_. where_clause ( ) ,
1012
+ GenericParent :: Impl ( impl_) => impl_. where_clause ( ) ,
1013
+ GenericParent :: Trait ( trait_) => trait_. where_clause ( ) ,
1014
+ }
1015
+ }
1016
+ }
1017
+
1018
+ /// Search `parent`'s ancestors for items with potentially applicable generic parameters
1019
+ fn generic_parents ( parent : & SyntaxNode ) -> Vec < GenericParent > {
1020
+ let mut list = Vec :: new ( ) ;
1021
+ if let Some ( parent_item) = parent. ancestors ( ) . find_map ( ast:: Item :: cast) {
1022
+ match parent_item {
1023
+ ast:: Item :: Fn ( ref fn_) => {
1024
+ if let Some ( parent_parent) = parent_item
1025
+ . syntax ( )
1026
+ . parent ( )
1027
+ . and_then ( |it| it. parent ( ) )
1028
+ . and_then ( ast:: Item :: cast)
1029
+ {
1030
+ match parent_parent {
1031
+ ast:: Item :: Impl ( impl_) => list. push ( GenericParent :: Impl ( impl_) ) ,
1032
+ ast:: Item :: Trait ( trait_) => list. push ( GenericParent :: Trait ( trait_) ) ,
1033
+ _ => ( ) ,
1034
+ }
1035
+ }
1036
+ list. push ( GenericParent :: Fn ( fn_. clone ( ) ) ) ;
1037
+ }
1038
+ _ => ( ) ,
1039
+ }
1040
+ }
1041
+ list
1011
1042
}
1012
1043
1013
1044
/// checks if relevant var is used with `&mut` access inside body
0 commit comments