@@ -823,8 +823,9 @@ impl FunctionBody {
823823 } ) ;
824824
825825 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 ( ) ;
828829
829830 Some ( ContainerInfo {
830831 is_in_tail,
@@ -990,24 +991,54 @@ impl FunctionBody {
990991 }
991992}
992993
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 ) ,
1001998}
1002999
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
10111042}
10121043
10131044/// checks if relevant var is used with `&mut` access inside body
0 commit comments