aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r--crates/ide/src/goto_definition.rs267
1 files changed, 162 insertions, 105 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 912144f8b..a1d2bce1d 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,15 +1,18 @@
1use either::Either; 1use either::Either;
2use hir::Semantics; 2use hir::{HasAttrs, ModuleDef, Semantics};
3use ide_db::{ 3use ide_db::{
4 base_db::FileId, 4 defs::{Definition, NameClass, NameRefClass},
5 defs::{NameClass, NameRefClass},
6 symbol_index, RootDatabase, 5 symbol_index, RootDatabase,
7}; 6};
8use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; 7use syntax::{
8 ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextSize, TokenAtOffset, T,
9};
9 10
10use crate::{ 11use crate::{
11 display::{ToNav, TryToNav}, 12 display::{ToNav, TryToNav},
12 FilePosition, NavigationTarget, RangeInfo, SymbolKind, 13 doc_links::extract_definitions_from_markdown,
14 runnables::doc_owner_to_def,
15 FilePosition, NavigationTarget, RangeInfo,
13}; 16};
14 17
15// Feature: Go to Definition 18// Feature: Go to Definition
@@ -30,6 +33,10 @@ pub(crate) fn goto_definition(
30 let original_token = pick_best(file.token_at_offset(position.offset))?; 33 let original_token = pick_best(file.token_at_offset(position.offset))?;
31 let token = sema.descend_into_macros(original_token.clone()); 34 let token = sema.descend_into_macros(original_token.clone());
32 let parent = token.parent(); 35 let parent = token.parent();
36 if let Some(comment) = ast::Comment::cast(token.clone()) {
37 let nav = def_for_doc_comment(&sema, position, &comment)?.try_to_nav(db)?;
38 return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
39 }
33 40
34 let nav_targets = match_ast! { 41 let nav_targets = match_ast! {
35 match parent { 42 match parent {
@@ -41,19 +48,6 @@ pub(crate) fn goto_definition(
41 let nav = def.try_to_nav(sema.db)?; 48 let nav = def.try_to_nav(sema.db)?;
42 vec![nav] 49 vec![nav]
43 }, 50 },
44 ast::SelfParam(self_param) => {
45 vec![self_to_nav_target(self_param, position.file_id)?]
46 },
47 ast::PathSegment(segment) => {
48 segment.self_token()?;
49 let path = segment.parent_path();
50 if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) {
51 return None;
52 }
53 let func = segment.syntax().ancestors().find_map(ast::Fn::cast)?;
54 let self_param = func.param_list()?.self_param()?;
55 vec![self_to_nav_target(self_param, position.file_id)?]
56 },
57 ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) { 51 ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
58 let def = name_class.referenced_or_defined(sema.db); 52 let def = name_class.referenced_or_defined(sema.db);
59 let nav = def.try_to_nav(sema.db)?; 53 let nav = def.try_to_nav(sema.db)?;
@@ -68,31 +62,64 @@ pub(crate) fn goto_definition(
68 Some(RangeInfo::new(original_token.text_range(), nav_targets)) 62 Some(RangeInfo::new(original_token.text_range(), nav_targets))
69} 63}
70 64
65fn def_for_doc_comment(
66 sema: &Semantics<RootDatabase>,
67 position: FilePosition,
68 doc_comment: &ast::Comment,
69) -> Option<hir::ModuleDef> {
70 let parent = doc_comment.syntax().parent();
71 let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?;
72
73 let def = doc_owner_to_def(sema, parent)?;
74 match def {
75 Definition::ModuleDef(def) => match def {
76 ModuleDef::Module(it) => it.resolve_doc_path(sema.db, &link, ns),
77 ModuleDef::Function(it) => it.resolve_doc_path(sema.db, &link, ns),
78 ModuleDef::Adt(it) => it.resolve_doc_path(sema.db, &link, ns),
79 ModuleDef::Variant(it) => it.resolve_doc_path(sema.db, &link, ns),
80 ModuleDef::Const(it) => it.resolve_doc_path(sema.db, &link, ns),
81 ModuleDef::Static(it) => it.resolve_doc_path(sema.db, &link, ns),
82 ModuleDef::Trait(it) => it.resolve_doc_path(sema.db, &link, ns),
83 ModuleDef::TypeAlias(it) => it.resolve_doc_path(sema.db, &link, ns),
84 ModuleDef::BuiltinType(_) => return None,
85 },
86 Definition::Macro(it) => it.resolve_doc_path(sema.db, &link, ns),
87 Definition::Field(it) => it.resolve_doc_path(sema.db, &link, ns),
88 Definition::SelfType(_)
89 | Definition::Local(_)
90 | Definition::GenericParam(_)
91 | Definition::Label(_) => return None,
92 }
93}
94
95fn extract_positioned_link_from_comment(
96 position: FilePosition,
97 comment: &ast::Comment,
98) -> Option<(String, Option<hir::Namespace>)> {
99 let comment_range = comment.syntax().text_range();
100 let doc_comment = comment.doc_comment()?;
101 let def_links = extract_definitions_from_markdown(doc_comment);
102 let (def_link, ns, _) = def_links.iter().min_by_key(|(_, _, def_link_range)| {
103 let matched_position = comment_range.start() + TextSize::from(def_link_range.start as u32);
104 match position.offset.checked_sub(matched_position) {
105 Some(distance) => distance,
106 None => comment_range.end(),
107 }
108 })?;
109 Some((def_link.to_string(), ns.clone()))
110}
111
71fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { 112fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
72 return tokens.max_by_key(priority); 113 return tokens.max_by_key(priority);
73 fn priority(n: &SyntaxToken) -> usize { 114 fn priority(n: &SyntaxToken) -> usize {
74 match n.kind() { 115 match n.kind() {
75 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2, 116 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | COMMENT => 2,
76 kind if kind.is_trivia() => 0, 117 kind if kind.is_trivia() => 0,
77 _ => 1, 118 _ => 1,
78 } 119 }
79 } 120 }
80} 121}
81 122
82fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<NavigationTarget> {
83 let self_token = self_param.self_token()?;
84 Some(NavigationTarget {
85 file_id,
86 full_range: self_param.syntax().text_range(),
87 focus_range: Some(self_token.text_range()),
88 name: self_token.text().clone(),
89 kind: Some(SymbolKind::SelfParam),
90 container_name: None,
91 description: None,
92 docs: None,
93 })
94}
95
96#[derive(Debug)] 123#[derive(Debug)]
97pub(crate) enum ReferenceResult { 124pub(crate) enum ReferenceResult {
98 Exact(NavigationTarget), 125 Exact(NavigationTarget),
@@ -166,7 +193,7 @@ mod tests {
166 check( 193 check(
167 r#" 194 r#"
168 //- /main.rs crate:main deps:std 195 //- /main.rs crate:main deps:std
169 extern crate std<|>; 196 extern crate std$0;
170 //- /std/lib.rs crate:std 197 //- /std/lib.rs crate:std
171 // empty 198 // empty
172 //^ file 199 //^ file
@@ -179,7 +206,7 @@ mod tests {
179 check( 206 check(
180 r#" 207 r#"
181 //- /main.rs crate:main deps:std 208 //- /main.rs crate:main deps:std
182 extern crate std as abc<|>; 209 extern crate std as abc$0;
183 //- /std/lib.rs crate:std 210 //- /std/lib.rs crate:std
184 // empty 211 // empty
185 //^ file 212 //^ file
@@ -193,7 +220,7 @@ mod tests {
193 r#" 220 r#"
194struct Foo; 221struct Foo;
195 //^^^ 222 //^^^
196enum E { X(Foo<|>) } 223enum E { X(Foo$0) }
197"#, 224"#,
198 ); 225 );
199 } 226 }
@@ -204,7 +231,7 @@ enum E { X(Foo<|>) }
204 r#" 231 r#"
205struct Foo; 232struct Foo;
206 //^^^ 233 //^^^
207enum E { X(<|>Foo) } 234enum E { X($0Foo) }
208"#, 235"#,
209 ); 236 );
210 } 237 }
@@ -217,7 +244,7 @@ enum E { X(<|>Foo) }
217use a::Foo; 244use a::Foo;
218mod a; 245mod a;
219mod b; 246mod b;
220enum E { X(Foo<|>) } 247enum E { X(Foo$0) }
221 248
222//- /a.rs 249//- /a.rs
223struct Foo; 250struct Foo;
@@ -233,7 +260,7 @@ struct Foo;
233 check( 260 check(
234 r#" 261 r#"
235//- /lib.rs 262//- /lib.rs
236mod <|>foo; 263mod $0foo;
237 264
238//- /foo.rs 265//- /foo.rs
239// empty 266// empty
@@ -244,7 +271,7 @@ mod <|>foo;
244 check( 271 check(
245 r#" 272 r#"
246//- /lib.rs 273//- /lib.rs
247mod <|>foo; 274mod $0foo;
248 275
249//- /foo/mod.rs 276//- /foo/mod.rs
250// empty 277// empty
@@ -260,7 +287,7 @@ mod <|>foo;
260macro_rules! foo { () => { () } } 287macro_rules! foo { () => { () } }
261 //^^^ 288 //^^^
262fn bar() { 289fn bar() {
263 <|>foo!(); 290 $0foo!();
264} 291}
265"#, 292"#,
266 ); 293 );
@@ -273,7 +300,7 @@ fn bar() {
273//- /lib.rs 300//- /lib.rs
274use foo::foo; 301use foo::foo;
275fn bar() { 302fn bar() {
276 <|>foo!(); 303 $0foo!();
277} 304}
278 305
279//- /foo/lib.rs 306//- /foo/lib.rs
@@ -289,7 +316,7 @@ macro_rules! foo { () => { () } }
289 check( 316 check(
290 r#" 317 r#"
291//- /lib.rs 318//- /lib.rs
292use foo::foo<|>; 319use foo::foo$0;
293 320
294//- /foo/lib.rs 321//- /foo/lib.rs
295#[macro_export] 322#[macro_export]
@@ -312,7 +339,7 @@ define_fn!(foo);
312 //^^^ 339 //^^^
313 340
314fn bar() { 341fn bar() {
315 <|>foo(); 342 $0foo();
316} 343}
317"#, 344"#,
318 ); 345 );
@@ -331,7 +358,7 @@ macro_rules! define_fn {
331//^^^^^^^^^^^^^ 358//^^^^^^^^^^^^^
332 359
333fn bar() { 360fn bar() {
334 <|>foo(); 361 $0foo();
335} 362}
336"#, 363"#,
337 ); 364 );
@@ -347,7 +374,7 @@ macro_rules! foo {() => {0}}
347 374
348fn bar() { 375fn bar() {
349 match (0,1) { 376 match (0,1) {
350 (<|>foo!(), _) => {} 377 ($0foo!(), _) => {}
351 } 378 }
352} 379}
353"#, 380"#,
@@ -363,7 +390,7 @@ macro_rules! foo {() => {0}}
363 //^^^ 390 //^^^
364fn bar() { 391fn bar() {
365 match 0 { 392 match 0 {
366 <|>foo!() => {} 393 $0foo!() => {}
367 } 394 }
368} 395}
369"#, 396"#,
@@ -375,7 +402,7 @@ fn bar() {
375 check( 402 check(
376 r#" 403 r#"
377//- /lib.rs crate:main deps:foo 404//- /lib.rs crate:main deps:foo
378use foo as bar<|>; 405use foo as bar$0;
379 406
380//- /foo/lib.rs crate:foo 407//- /foo/lib.rs crate:foo
381// empty 408// empty
@@ -389,7 +416,7 @@ use foo as bar<|>;
389 check( 416 check(
390 r#" 417 r#"
391//- /lib.rs crate:main deps:foo 418//- /lib.rs crate:main deps:foo
392use foo::foo as bar<|>; 419use foo::foo as bar$0;
393 420
394//- /foo/lib.rs crate:foo 421//- /foo/lib.rs crate:foo
395#[macro_export] 422#[macro_export]
@@ -410,7 +437,7 @@ impl Foo {
410} 437}
411 438
412fn bar(foo: &Foo) { 439fn bar(foo: &Foo) {
413 foo.frobnicate<|>(); 440 foo.frobnicate$0();
414} 441}
415"#, 442"#,
416 ); 443 );
@@ -425,7 +452,7 @@ struct Foo {
425} //^^^^ 452} //^^^^
426 453
427fn bar(foo: &Foo) { 454fn bar(foo: &Foo) {
428 foo.spam<|>; 455 foo.spam$0;
429} 456}
430"#, 457"#,
431 ); 458 );
@@ -442,7 +469,7 @@ struct Foo {
442 469
443fn bar() -> Foo { 470fn bar() -> Foo {
444 Foo { 471 Foo {
445 spam<|>: 0, 472 spam$0: 0,
446 } 473 }
447} 474}
448"#, 475"#,
@@ -459,7 +486,7 @@ struct Foo {
459} //^^^^ 486} //^^^^
460 487
461fn bar(foo: Foo) -> Foo { 488fn bar(foo: Foo) -> Foo {
462 let Foo { spam<|>: _, } = foo 489 let Foo { spam$0: _, } = foo
463} 490}
464"#, 491"#,
465 ); 492 );
@@ -474,7 +501,7 @@ struct Foo { spam: u32 }
474 //^^^^ 501 //^^^^
475 502
476fn bar() -> Foo { 503fn bar() -> Foo {
477 Foo { spam<|>: m!() } 504 Foo { spam$0: m!() }
478} 505}
479", 506",
480 ); 507 );
@@ -489,7 +516,7 @@ struct Foo(u32);
489 516
490fn bar() { 517fn bar() {
491 let foo = Foo(0); 518 let foo = Foo(0);
492 foo.<|>0; 519 foo.$00;
493} 520}
494"#, 521"#,
495 ); 522 );
@@ -505,7 +532,7 @@ impl Foo {
505} //^^^^^^^^^^ 532} //^^^^^^^^^^
506 533
507fn bar(foo: &Foo) { 534fn bar(foo: &Foo) {
508 Foo::frobnicate<|>(); 535 Foo::frobnicate$0();
509} 536}
510"#, 537"#,
511 ); 538 );
@@ -520,7 +547,7 @@ trait Foo {
520} //^^^^^^^^^^ 547} //^^^^^^^^^^
521 548
522fn bar() { 549fn bar() {
523 Foo::frobnicate<|>(); 550 Foo::frobnicate$0();
524} 551}
525"#, 552"#,
526 ); 553 );
@@ -537,7 +564,7 @@ trait Trait {
537impl Trait for Foo {} 564impl Trait for Foo {}
538 565
539fn bar() { 566fn bar() {
540 Foo::frobnicate<|>(); 567 Foo::frobnicate$0();
541} 568}
542"#, 569"#,
543 ); 570 );
@@ -551,7 +578,7 @@ struct Foo;
551impl Foo { 578impl Foo {
552 //^^^ 579 //^^^
553 pub fn new() -> Self { 580 pub fn new() -> Self {
554 Self<|> {} 581 Self$0 {}
555 } 582 }
556} 583}
557"#, 584"#,
@@ -561,7 +588,7 @@ impl Foo {
561struct Foo; 588struct Foo;
562impl Foo { 589impl Foo {
563 //^^^ 590 //^^^
564 pub fn new() -> Self<|> { 591 pub fn new() -> Self$0 {
565 Self {} 592 Self {}
566 } 593 }
567} 594}
@@ -573,7 +600,7 @@ impl Foo {
573enum Foo { A } 600enum Foo { A }
574impl Foo { 601impl Foo {
575 //^^^ 602 //^^^
576 pub fn new() -> Self<|> { 603 pub fn new() -> Self$0 {
577 Foo::A 604 Foo::A
578 } 605 }
579} 606}
@@ -585,7 +612,7 @@ impl Foo {
585enum Foo { A } 612enum Foo { A }
586impl Foo { 613impl Foo {
587 //^^^ 614 //^^^
588 pub fn thing(a: &Self<|>) { 615 pub fn thing(a: &Self$0) {
589 } 616 }
590} 617}
591"#, 618"#,
@@ -603,7 +630,7 @@ trait Make {
603impl Make for Foo { 630impl Make for Foo {
604 //^^^ 631 //^^^
605 fn new() -> Self { 632 fn new() -> Self {
606 Self<|> {} 633 Self$0 {}
607 } 634 }
608} 635}
609"#, 636"#,
@@ -617,7 +644,7 @@ trait Make {
617} 644}
618impl Make for Foo { 645impl Make for Foo {
619 //^^^ 646 //^^^
620 fn new() -> Self<|> { 647 fn new() -> Self$0 {
621 Self {} 648 Self {}
622 } 649 }
623} 650}
@@ -629,7 +656,7 @@ impl Make for Foo {
629 fn goto_def_when_used_on_definition_name_itself() { 656 fn goto_def_when_used_on_definition_name_itself() {
630 check( 657 check(
631 r#" 658 r#"
632struct Foo<|> { value: u32 } 659struct Foo$0 { value: u32 }
633 //^^^ 660 //^^^
634 "#, 661 "#,
635 ); 662 );
@@ -637,21 +664,21 @@ struct Foo<|> { value: u32 }
637 check( 664 check(
638 r#" 665 r#"
639struct Foo { 666struct Foo {
640 field<|>: string, 667 field$0: string,
641} //^^^^^ 668} //^^^^^
642"#, 669"#,
643 ); 670 );
644 671
645 check( 672 check(
646 r#" 673 r#"
647fn foo_test<|>() { } 674fn foo_test$0() { }
648 //^^^^^^^^ 675 //^^^^^^^^
649"#, 676"#,
650 ); 677 );
651 678
652 check( 679 check(
653 r#" 680 r#"
654enum Foo<|> { Variant } 681enum Foo$0 { Variant }
655 //^^^ 682 //^^^
656"#, 683"#,
657 ); 684 );
@@ -660,7 +687,7 @@ enum Foo<|> { Variant }
660 r#" 687 r#"
661enum Foo { 688enum Foo {
662 Variant1, 689 Variant1,
663 Variant2<|>, 690 Variant2$0,
664 //^^^^^^^^ 691 //^^^^^^^^
665 Variant3, 692 Variant3,
666} 693}
@@ -669,35 +696,35 @@ enum Foo {
669 696
670 check( 697 check(
671 r#" 698 r#"
672static INNER<|>: &str = ""; 699static INNER$0: &str = "";
673 //^^^^^ 700 //^^^^^
674"#, 701"#,
675 ); 702 );
676 703
677 check( 704 check(
678 r#" 705 r#"
679const INNER<|>: &str = ""; 706const INNER$0: &str = "";
680 //^^^^^ 707 //^^^^^
681"#, 708"#,
682 ); 709 );
683 710
684 check( 711 check(
685 r#" 712 r#"
686type Thing<|> = Option<()>; 713type Thing$0 = Option<()>;
687 //^^^^^ 714 //^^^^^
688"#, 715"#,
689 ); 716 );
690 717
691 check( 718 check(
692 r#" 719 r#"
693trait Foo<|> { } 720trait Foo$0 { }
694 //^^^ 721 //^^^
695"#, 722"#,
696 ); 723 );
697 724
698 check( 725 check(
699 r#" 726 r#"
700mod bar<|> { } 727mod bar$0 { }
701 //^^^ 728 //^^^
702"#, 729"#,
703 ); 730 );
@@ -714,7 +741,7 @@ fn foo() {}
714 //^^^ 741 //^^^
715id! { 742id! {
716 fn bar() { 743 fn bar() {
717 fo<|>o(); 744 fo$0o();
718 } 745 }
719} 746}
720mod confuse_index { fn foo(); } 747mod confuse_index { fn foo(); }
@@ -743,7 +770,7 @@ pub mod __export {
743fn foo() -> i8 {} 770fn foo() -> i8 {}
744 //^^^ 771 //^^^
745fn test() { 772fn test() {
746 format!("{}", fo<|>o()) 773 format!("{}", fo$0o())
747} 774}
748"#, 775"#,
749 ); 776 );
@@ -761,7 +788,7 @@ macro_rules! include {}
761//^^^^^^^^^^^^^^^^^^^ 788//^^^^^^^^^^^^^^^^^^^
762 789
763fn f() { 790fn f() {
764 foo<|>(); 791 foo$0();
765} 792}
766 793
767mod confuse_index { 794mod confuse_index {
@@ -778,7 +805,7 @@ fn foo() {}
778 fn goto_for_type_param() { 805 fn goto_for_type_param() {
779 check( 806 check(
780 r#" 807 r#"
781struct Foo<T: Clone> { t: <|>T } 808struct Foo<T: Clone> { t: $0T }
782 //^ 809 //^
783"#, 810"#,
784 ); 811 );
@@ -796,7 +823,7 @@ fn foo() {
796 let x = 1; 823 let x = 1;
797 //^ 824 //^
798 id!({ 825 id!({
799 let y = <|>x; 826 let y = $0x;
800 let z = y; 827 let z = y;
801 }); 828 });
802} 829}
@@ -814,7 +841,7 @@ fn foo() {
814 id!({ 841 id!({
815 let y = x; 842 let y = x;
816 //^ 843 //^
817 let z = <|>y; 844 let z = $0y;
818 }); 845 });
819} 846}
820"#, 847"#,
@@ -829,7 +856,7 @@ fn main() {
829 fn foo() { 856 fn foo() {
830 let x = 92; 857 let x = 92;
831 //^ 858 //^
832 <|>x; 859 $0x;
833 } 860 }
834} 861}
835"#, 862"#,
@@ -843,7 +870,7 @@ fn main() {
843fn bar() { 870fn bar() {
844 macro_rules! foo { () => { () } } 871 macro_rules! foo { () => { () } }
845 //^^^ 872 //^^^
846 <|>foo!(); 873 $0foo!();
847} 874}
848"#, 875"#,
849 ); 876 );
@@ -857,7 +884,7 @@ struct Foo { x: i32 }
857fn main() { 884fn main() {
858 let x = 92; 885 let x = 92;
859 //^ 886 //^
860 Foo { x<|> }; 887 Foo { x$0 };
861} 888}
862"#, 889"#,
863 ) 890 )
@@ -872,7 +899,7 @@ enum Foo {
872} //^ 899} //^
873fn baz(foo: Foo) { 900fn baz(foo: Foo) {
874 match foo { 901 match foo {
875 Foo::Bar { x<|> } => x 902 Foo::Bar { x$0 } => x
876 }; 903 };
877} 904}
878"#, 905"#,
@@ -887,7 +914,7 @@ enum Foo { Bar }
887 //^^^ 914 //^^^
888impl Foo { 915impl Foo {
889 fn baz(self) { 916 fn baz(self) {
890 match self { Self::Bar<|> => {} } 917 match self { Self::Bar$0 => {} }
891 } 918 }
892} 919}
893"#, 920"#,
@@ -902,7 +929,7 @@ enum Foo { Bar { val: i32 } }
902 //^^^ 929 //^^^
903impl Foo { 930impl Foo {
904 fn baz(self) -> i32 { 931 fn baz(self) -> i32 {
905 match self { Self::Bar<|> { val } => {} } 932 match self { Self::Bar$0 { val } => {} }
906 } 933 }
907} 934}
908"#, 935"#,
@@ -916,7 +943,7 @@ impl Foo {
916enum Foo { Bar } 943enum Foo { Bar }
917 //^^^ 944 //^^^
918impl Foo { 945impl Foo {
919 fn baz(self) { Self::Bar<|>; } 946 fn baz(self) { Self::Bar$0; }
920} 947}
921"#, 948"#,
922 ); 949 );
@@ -929,7 +956,7 @@ impl Foo {
929enum Foo { Bar { val: i32 } } 956enum Foo { Bar { val: i32 } }
930 //^^^ 957 //^^^
931impl Foo { 958impl Foo {
932 fn baz(self) { Self::Bar<|> {val: 4}; } 959 fn baz(self) { Self::Bar$0 {val: 4}; }
933} 960}
934"#, 961"#,
935 ); 962 );
@@ -939,7 +966,7 @@ impl Foo {
939 fn goto_def_for_type_alias_generic_parameter() { 966 fn goto_def_for_type_alias_generic_parameter() {
940 check( 967 check(
941 r#" 968 r#"
942type Alias<T> = T<|>; 969type Alias<T> = T$0;
943 //^ 970 //^
944"#, 971"#,
945 ) 972 )
@@ -950,7 +977,7 @@ type Alias<T> = T<|>;
950 check( 977 check(
951 r#" 978 r#"
952//- /lib.rs 979//- /lib.rs
953foo::module<|>::mac!(); 980foo::module$0::mac!();
954 981
955//- /foo/lib.rs 982//- /foo/lib.rs
956pub mod module { 983pub mod module {
@@ -972,7 +999,7 @@ trait Iterator {
972 //^^^^ 999 //^^^^
973} 1000}
974 1001
975fn f() -> impl Iterator<Item<|> = u8> {} 1002fn f() -> impl Iterator<Item$0 = u8> {}
976"#, 1003"#,
977 ); 1004 );
978 } 1005 }
@@ -987,7 +1014,7 @@ trait Iterator {
987 type B; 1014 type B;
988} 1015}
989 1016
990fn f() -> impl Iterator<A<|> = u8, B = ()> {} 1017fn f() -> impl Iterator<A$0 = u8, B = ()> {}
991"#, 1018"#,
992 ); 1019 );
993 check( 1020 check(
@@ -998,7 +1025,7 @@ trait Iterator {
998 //^ 1025 //^
999} 1026}
1000 1027
1001fn f() -> impl Iterator<A = u8, B<|> = ()> {} 1028fn f() -> impl Iterator<A = u8, B$0 = ()> {}
1002"#, 1029"#,
1003 ); 1030 );
1004 } 1031 }
@@ -1012,7 +1039,7 @@ trait Iterator {
1012 //^^^^ 1039 //^^^^
1013} 1040}
1014 1041
1015fn g() -> <() as Iterator<Item<|> = ()>>::Item {} 1042fn g() -> <() as Iterator<Item$0 = ()>>::Item {}
1016"#, 1043"#,
1017 ); 1044 );
1018 } 1045 }
@@ -1027,7 +1054,7 @@ trait Iterator {
1027 type B; 1054 type B;
1028} 1055}
1029 1056
1030fn g() -> <() as Iterator<A<|> = (), B = u8>>::B {} 1057fn g() -> <() as Iterator<A$0 = (), B = u8>>::B {}
1031"#, 1058"#,
1032 ); 1059 );
1033 check( 1060 check(
@@ -1038,7 +1065,7 @@ trait Iterator {
1038 //^ 1065 //^
1039} 1066}
1040 1067
1041fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {} 1068fn g() -> <() as Iterator<A = (), B$0 = u8>>::A {}
1042"#, 1069"#,
1043 ); 1070 );
1044 } 1071 }
@@ -1052,7 +1079,7 @@ struct Foo {}
1052impl Foo { 1079impl Foo {
1053 fn bar(self: &Foo) { 1080 fn bar(self: &Foo) {
1054 //^^^^ 1081 //^^^^
1055 let foo = sel<|>f; 1082 let foo = sel$0f;
1056 } 1083 }
1057}"#, 1084}"#,
1058 ) 1085 )
@@ -1065,7 +1092,7 @@ impl Foo {
1065struct Foo {} 1092struct Foo {}
1066 1093
1067impl Foo { 1094impl Foo {
1068 fn bar(&self<|>) { 1095 fn bar(&self$0) {
1069 //^^^^ 1096 //^^^^
1070 } 1097 }
1071}"#, 1098}"#,
@@ -1076,7 +1103,7 @@ impl Foo {
1076 fn goto_lifetime_param_on_decl() { 1103 fn goto_lifetime_param_on_decl() {
1077 check( 1104 check(
1078 r#" 1105 r#"
1079fn foo<'foobar<|>>(_: &'foobar ()) { 1106fn foo<'foobar$0>(_: &'foobar ()) {
1080 //^^^^^^^ 1107 //^^^^^^^
1081}"#, 1108}"#,
1082 ) 1109 )
@@ -1086,7 +1113,7 @@ fn foo<'foobar<|>>(_: &'foobar ()) {
1086 fn goto_lifetime_param_decl() { 1113 fn goto_lifetime_param_decl() {
1087 check( 1114 check(
1088 r#" 1115 r#"
1089fn foo<'foobar>(_: &'foobar<|> ()) { 1116fn foo<'foobar>(_: &'foobar$0 ()) {
1090 //^^^^^^^ 1117 //^^^^^^^
1091}"#, 1118}"#,
1092 ) 1119 )
@@ -1097,7 +1124,7 @@ fn foo<'foobar>(_: &'foobar<|> ()) {
1097 check( 1124 check(
1098 r#" 1125 r#"
1099fn foo<'foobar>(_: &'foobar ()) { 1126fn foo<'foobar>(_: &'foobar ()) {
1100 fn foo<'foobar>(_: &'foobar<|> ()) {} 1127 fn foo<'foobar>(_: &'foobar$0 ()) {}
1101 //^^^^^^^ 1128 //^^^^^^^
1102}"#, 1129}"#,
1103 ) 1130 )
@@ -1108,13 +1135,13 @@ fn foo<'foobar>(_: &'foobar ()) {
1108 fn goto_lifetime_hrtb() { 1135 fn goto_lifetime_hrtb() {
1109 check( 1136 check(
1110 r#"trait Foo<T> {} 1137 r#"trait Foo<T> {}
1111fn foo<T>() where for<'a> T: Foo<&'a<|> (u8, u16)>, {} 1138fn foo<T>() where for<'a> T: Foo<&'a$0 (u8, u16)>, {}
1112 //^^ 1139 //^^
1113"#, 1140"#,
1114 ); 1141 );
1115 check( 1142 check(
1116 r#"trait Foo<T> {} 1143 r#"trait Foo<T> {}
1117fn foo<T>() where for<'a<|>> T: Foo<&'a (u8, u16)>, {} 1144fn foo<T>() where for<'a$0> T: Foo<&'a (u8, u16)>, {}
1118 //^^ 1145 //^^
1119"#, 1146"#,
1120 ); 1147 );
@@ -1125,7 +1152,7 @@ fn foo<T>() where for<'a<|>> T: Foo<&'a (u8, u16)>, {}
1125 fn goto_lifetime_hrtb_for_type() { 1152 fn goto_lifetime_hrtb_for_type() {
1126 check( 1153 check(
1127 r#"trait Foo<T> {} 1154 r#"trait Foo<T> {}
1128fn foo<T>() where T: for<'a> Foo<&'a<|> (u8, u16)>, {} 1155fn foo<T>() where T: for<'a> Foo<&'a$0 (u8, u16)>, {}
1129 //^^ 1156 //^^
1130"#, 1157"#,
1131 ); 1158 );
@@ -1139,10 +1166,40 @@ fn foo<'foo>(_: &'foo ()) {
1139 'foo: { 1166 'foo: {
1140 //^^^^ 1167 //^^^^
1141 'bar: loop { 1168 'bar: loop {
1142 break 'foo<|>; 1169 break 'foo$0;
1143 } 1170 }
1144 } 1171 }
1145}"#, 1172}"#,
1146 ) 1173 )
1147 } 1174 }
1175
1176 #[test]
1177 fn goto_def_for_intra_doc_link_same_file() {
1178 check(
1179 r#"
1180/// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar)
1181pub fn bar() { }
1182
1183/// You might want to see [`std::fs::read()`] too.
1184pub fn foo() { }
1185 //^^^
1186
1187}"#,
1188 )
1189 }
1190
1191 #[test]
1192 fn goto_def_for_intra_doc_link_inner() {
1193 check(
1194 r#"
1195//- /main.rs
1196mod m;
1197struct S;
1198 //^
1199
1200//- /m.rs
1201//! [`super::S$0`]
1202"#,
1203 )
1204 }
1148} 1205}