@@ -8,6 +8,7 @@ use ide_db::{
88 helpers:: { pick_best_token, try_resolve_derive_input_at} ,
99 RootDatabase ,
1010} ;
11+ use itertools:: Itertools ;
1112use syntax:: { ast, match_ast, AstNode , AstToken , SyntaxKind :: * , SyntaxToken , TextRange , T } ;
1213
1314use crate :: {
@@ -52,8 +53,8 @@ pub(crate) fn goto_definition(
5253 let nav = resolve_doc_path_for_def ( db, def, & link, ns) ?. try_to_nav ( db) ?;
5354 return Some ( RangeInfo :: new ( original_token. text_range ( ) , vec ! [ nav] ) ) ;
5455 }
55-
56- let navs = sema . descend_into_macros_many ( original_token. clone ( ) )
56+ let navs = sema
57+ . descend_into_macros_many ( original_token. clone ( ) )
5758 . into_iter ( )
5859 . filter_map ( |token| {
5960 let parent = token. parent ( ) ?;
@@ -65,28 +66,34 @@ pub(crate) fn goto_definition(
6566 ast:: Name ( name) => {
6667 match NameClass :: classify( & sema, & name) ? {
6768 NameClass :: Definition ( def) | NameClass :: ConstReference ( def) => {
68- try_find_trait_item_definition( sema. db, & def) . unwrap_or_else( || def_to_nav( sema. db, def) )
69+ try_find_trait_item_definition( sema. db, & def)
70+ . unwrap_or_else( || def_to_nav( sema. db, def) )
6971 }
7072 NameClass :: PatFieldShorthand { local_def, field_ref } => {
7173 local_and_field_to_nav( sema. db, local_def, field_ref)
7274 } ,
7375 }
7476 } ,
75- ast:: Lifetime ( lt) => if let Some ( name_class) = NameClass :: classify_lifetime( & sema, & lt) {
76- match name_class {
77- NameClass :: Definition ( def) => def_to_nav( sema. db, def) ,
78- _ => return None ,
77+ ast:: Lifetime ( lt) => {
78+ match NameClass :: classify_lifetime( & sema, & lt) {
79+ Some ( name_class) => {
80+ match name_class {
81+ NameClass :: Definition ( def) => def_to_nav( sema. db, def) ,
82+ _ => return None ,
83+ }
84+ }
85+ None => reference_definition( & sema, Either :: Left ( & lt) ) ,
7986 }
80- } else {
81- reference_definition( & sema, Either :: Left ( & lt) )
8287 } ,
83- ast:: TokenTree ( tt) => try_lookup_include_path_or_derive( & sema, tt, token, position. file_id) ?,
88+ ast:: TokenTree ( tt) =>
89+ try_lookup_include_path_or_derive( & sema, tt, token, position. file_id) ?,
8490 _ => return None ,
8591 }
8692 } ;
8793 Some ( navs)
8894 } )
8995 . flatten ( )
96+ . unique ( )
9097 . collect :: < Vec < NavigationTarget > > ( ) ;
9198
9299 Some ( RangeInfo :: new ( original_token. text_range ( ) , navs) )
@@ -199,6 +206,7 @@ mod tests {
199206
200207 use crate :: fixture;
201208
209+ #[ track_caller]
202210 fn check ( ra_fixture : & str ) {
203211 let ( analysis, position, expected) = fixture:: annotations ( ra_fixture) ;
204212 let navs = analysis. goto_definition ( position) . unwrap ( ) . expect ( "no definition found" ) . info ;
@@ -1447,4 +1455,41 @@ struct Foo;
14471455 "# ,
14481456 ) ;
14491457 }
1458+
1459+ #[ test]
1460+ fn goto_def_in_macro_multi ( ) {
1461+ check (
1462+ r#"
1463+ struct Foo {
1464+ foo: ()
1465+ //^^^
1466+ }
1467+ macro_rules! foo {
1468+ ($ident:ident) => {
1469+ fn $ident(Foo { $ident }: Foo) {}
1470+ }
1471+ }
1472+ foo!(foo$0);
1473+ //^^^
1474+ //^^^
1475+ "# ,
1476+ ) ;
1477+ check (
1478+ r#"
1479+ fn bar() {}
1480+ //^^^
1481+ struct bar;
1482+ //^^^
1483+ macro_rules! foo {
1484+ ($ident:ident) => {
1485+ fn foo() {
1486+ let _: $ident = $ident;
1487+ }
1488+ }
1489+ }
1490+
1491+ foo!(bar$0);
1492+ "# ,
1493+ ) ;
1494+ }
14501495}
0 commit comments