@@ -27,32 +27,6 @@ pub(crate) fn goto_type_definition(
27
27
kind if kind. is_trivia ( ) => 0 ,
28
28
_ => 1 ,
29
29
} ) ?;
30
- let token: SyntaxToken = sema. descend_into_macros_single ( token) ;
31
-
32
- let ( ty, node) = sema. token_ancestors_with_macros ( token) . find_map ( |node| {
33
- let ty = match_ast ! {
34
- match node {
35
- ast:: Expr ( it) => sema. type_of_expr( & it) ?. original,
36
- ast:: Pat ( it) => sema. type_of_pat( & it) ?. original,
37
- ast:: SelfParam ( it) => sema. type_of_self( & it) ?,
38
- ast:: Type ( it) => sema. resolve_type( & it) ?,
39
- ast:: RecordField ( it) => sema. to_def( & it) . map( |d| d. ty( db. upcast( ) ) ) ?,
40
- // can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
41
- ast:: NameRef ( it) => {
42
- if let Some ( record_field) = ast:: RecordExprField :: for_name_ref( & it) {
43
- let ( _, _, ty) = sema. resolve_record_field( & record_field) ?;
44
- ty
45
- } else {
46
- let record_field = ast:: RecordPatField :: for_field_name_ref( & it) ?;
47
- sema. resolve_record_pat_field( & record_field) ?. ty( db)
48
- }
49
- } ,
50
- _ => return None ,
51
- }
52
- } ;
53
-
54
- Some ( ( ty, node) )
55
- } ) ?;
56
30
57
31
let mut res = Vec :: new ( ) ;
58
32
let mut push = |def : hir:: ModuleDef | {
@@ -62,21 +36,56 @@ pub(crate) fn goto_type_definition(
62
36
}
63
37
}
64
38
} ;
39
+ let range = token. text_range ( ) ;
40
+ sema. descend_into_macros ( token)
41
+ . iter ( )
42
+ . filter_map ( |token| {
43
+ let ty = sema. token_ancestors_with_macros ( token. clone ( ) ) . find_map ( |node| {
44
+ let ty = match_ast ! {
45
+ match node {
46
+ ast:: Expr ( it) => sema. type_of_expr( & it) ?. original,
47
+ ast:: Pat ( it) => sema. type_of_pat( & it) ?. original,
48
+ ast:: SelfParam ( it) => sema. type_of_self( & it) ?,
49
+ ast:: Type ( it) => sema. resolve_type( & it) ?,
50
+ ast:: RecordField ( it) => sema. to_def( & it) . map( |d| d. ty( db. upcast( ) ) ) ?,
51
+ // can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
52
+ ast:: NameRef ( it) => {
53
+ if let Some ( record_field) = ast:: RecordExprField :: for_name_ref( & it) {
54
+ let ( _, _, ty) = sema. resolve_record_field( & record_field) ?;
55
+ ty
56
+ } else {
57
+ let record_field = ast:: RecordPatField :: for_field_name_ref( & it) ?;
58
+ sema. resolve_record_pat_field( & record_field) ?. ty( db)
59
+ }
60
+ } ,
61
+ _ => return None ,
62
+ }
63
+ } ;
65
64
66
- let ty = ty. strip_references ( ) ;
67
- ty. walk ( db, |t| {
68
- if let Some ( adt) = t. as_adt ( ) {
69
- push ( adt. into ( ) ) ;
70
- } else if let Some ( trait_) = t. as_dyn_trait ( ) {
71
- push ( trait_. into ( ) ) ;
72
- } else if let Some ( traits) = t. as_impl_traits ( db) {
73
- traits. into_iter ( ) . for_each ( |it| push ( it. into ( ) ) ) ;
74
- } else if let Some ( trait_) = t. as_associated_type_parent_trait ( db) {
75
- push ( trait_. into ( ) ) ;
76
- }
77
- } ) ;
78
-
79
- Some ( RangeInfo :: new ( node. text_range ( ) , res) )
65
+ Some ( ty)
66
+ } ) ;
67
+ ty
68
+ } )
69
+ . for_each ( |ty| {
70
+ // collect from each `ty` into the `res` result vec
71
+ let ty = ty. strip_references ( ) ;
72
+ ty. walk ( db, |t| {
73
+ if let Some ( adt) = t. as_adt ( ) {
74
+ push ( adt. into ( ) ) ;
75
+ } else if let Some ( trait_) = t. as_dyn_trait ( ) {
76
+ push ( trait_. into ( ) ) ;
77
+ } else if let Some ( traits) = t. as_impl_traits ( db) {
78
+ traits. into_iter ( ) . for_each ( |it| push ( it. into ( ) ) ) ;
79
+ } else if let Some ( trait_) = t. as_associated_type_parent_trait ( db) {
80
+ push ( trait_. into ( ) ) ;
81
+ }
82
+ } ) ;
83
+ } ) ;
84
+ if res. is_empty ( ) {
85
+ None
86
+ } else {
87
+ Some ( RangeInfo :: new ( range, res) )
88
+ }
80
89
}
81
90
82
91
#[ cfg( test) ]
0 commit comments