]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/goto_definition.rs
c236039f45deabb2cec335910b13f7b5919add99
[rust.git] / crates / ide / src / goto_definition.rs
1 use std::convert::TryInto;
2
3 use either::Either;
4 use hir::{AsAssocItem, InFile, ModuleDef, Semantics};
5 use ide_db::{
6     base_db::{AnchoredPath, FileId, FileLoader},
7     defs::{Definition, NameClass, NameRefClass},
8     RootDatabase,
9 };
10 use syntax::{
11     ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, TokenAtOffset, T,
12 };
13
14 use crate::{
15     display::TryToNav,
16     doc_links::{doc_attributes, extract_definitions_from_markdown, resolve_doc_path_for_def},
17     FilePosition, NavigationTarget, RangeInfo,
18 };
19
20 // Feature: Go to Definition
21 //
22 // Navigates to the definition of an identifier.
23 //
24 // |===
25 // | Editor  | Shortcut
26 //
27 // | VS Code | kbd:[F12]
28 // |===
29 //
30 // image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[]
31 pub(crate) fn goto_definition(
32     db: &RootDatabase,
33     position: FilePosition,
34 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
35     let sema = Semantics::new(db);
36     let file = sema.parse(position.file_id).syntax().clone();
37     let original_token = pick_best(file.token_at_offset(position.offset))?;
38     let token = sema.descend_into_macros(original_token.clone());
39     let parent = token.parent()?;
40     if let Some(_) = ast::Comment::cast(token.clone()) {
41         let (attributes, def) = doc_attributes(&sema, &parent)?;
42
43         let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?;
44         let (_, link, ns) =
45             extract_definitions_from_markdown(docs.as_str()).into_iter().find(|(range, ..)| {
46                 doc_mapping.map(range.clone()).map_or(false, |InFile { file_id, value: range }| {
47                     file_id == position.file_id.into() && range.contains(position.offset)
48                 })
49             })?;
50         let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?;
51         return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
52     }
53     let nav = match_ast! {
54         match parent {
55             ast::NameRef(name_ref) => {
56                 reference_definition(&sema, Either::Right(&name_ref))
57             },
58             ast::Name(name) => {
59                 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
60                 try_find_trait_fn_definition(&sema.db, &def)
61                     .or_else(|| def.try_to_nav(sema.db))
62             },
63             ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
64                 let def = name_class.referenced_or_defined(sema.db);
65                 def.try_to_nav(sema.db)
66             } else {
67                 reference_definition(&sema, Either::Left(&lt))
68             },
69             ast::TokenTree(tt) => try_lookup_include_path(sema.db, tt, token, position.file_id),
70             _ => return None,
71         }
72     };
73
74     Some(RangeInfo::new(original_token.text_range(), nav.into_iter().collect()))
75 }
76
77 fn try_lookup_include_path(
78     db: &RootDatabase,
79     tt: ast::TokenTree,
80     token: SyntaxToken,
81     file_id: FileId,
82 ) -> Option<NavigationTarget> {
83     let path = ast::String::cast(token)?.value()?.into_owned();
84     let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?;
85     let name = macro_call.path()?.segment()?.name_ref()?;
86     if !matches!(&*name.text(), "include" | "include_str" | "include_bytes") {
87         return None;
88     }
89     let file_id = db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?;
90     let size = db.file_text(file_id).len().try_into().ok()?;
91     Some(NavigationTarget {
92         file_id,
93         full_range: TextRange::new(0.into(), size),
94         name: path.into(),
95         focus_range: None,
96         kind: None,
97         container_name: None,
98         description: None,
99         docs: None,
100     })
101 }
102
103 /// finds the trait definition of an impl'd function
104 /// e.g.
105 /// ```rust
106 /// trait A { fn a(); }
107 /// struct S;
108 /// impl A for S { fn a(); } // <-- on this function, will get the location of a() in the trait
109 /// ```
110 fn try_find_trait_fn_definition(db: &RootDatabase, def: &Definition) -> Option<NavigationTarget> {
111     match def {
112         Definition::ModuleDef(ModuleDef::Function(f)) => {
113             let name = def.name(db)?;
114             let assoc = f.as_assoc_item(db)?;
115             let imp = match assoc.container(db) {
116                 hir::AssocItemContainer::Impl(imp) => imp,
117                 _ => return None,
118             };
119             let trait_ = imp.trait_(db)?;
120             trait_
121                 .items(db)
122                 .iter()
123                 .find_map(|itm| (itm.name(db)? == name).then(|| itm.try_to_nav(db)).flatten())
124         }
125         _ => None,
126     }
127 }
128
129 fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
130     return tokens.max_by_key(priority);
131     fn priority(n: &SyntaxToken) -> usize {
132         match n.kind() {
133             IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | COMMENT => 2,
134             kind if kind.is_trivia() => 0,
135             _ => 1,
136         }
137     }
138 }
139
140 pub(crate) fn reference_definition(
141     sema: &Semantics<RootDatabase>,
142     name_ref: Either<&ast::Lifetime, &ast::NameRef>,
143 ) -> Option<NavigationTarget> {
144     let name_kind = name_ref.either(
145         |lifetime| NameRefClass::classify_lifetime(sema, lifetime),
146         |name_ref| NameRefClass::classify(sema, name_ref),
147     )?;
148     let def = name_kind.referenced(sema.db);
149     def.try_to_nav(sema.db)
150 }
151
152 #[cfg(test)]
153 mod tests {
154     use ide_db::base_db::FileRange;
155
156     use crate::fixture;
157
158     fn check(ra_fixture: &str) {
159         let (analysis, position, expected) = fixture::nav_target_annotation(ra_fixture);
160         let mut navs =
161             analysis.goto_definition(position).unwrap().expect("no definition found").info;
162         if navs.len() == 0 {
163             panic!("unresolved reference")
164         }
165         assert_eq!(navs.len(), 1);
166
167         let nav = navs.pop().unwrap();
168         assert_eq!(expected, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() });
169     }
170
171     fn check_unresolved(ra_fixture: &str) {
172         let (analysis, position) = fixture::position(ra_fixture);
173         let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
174
175         assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {:?}", navs)
176     }
177
178     #[test]
179     fn goto_def_for_extern_crate() {
180         check(
181             r#"
182 //- /main.rs crate:main deps:std
183 extern crate std$0;
184 //- /std/lib.rs crate:std
185 // empty
186 //^ file
187 "#,
188         )
189     }
190
191     #[test]
192     fn goto_def_for_renamed_extern_crate() {
193         check(
194             r#"
195 //- /main.rs crate:main deps:std
196 extern crate std as abc$0;
197 //- /std/lib.rs crate:std
198 // empty
199 //^ file
200 "#,
201         )
202     }
203
204     #[test]
205     fn goto_def_in_items() {
206         check(
207             r#"
208 struct Foo;
209      //^^^
210 enum E { X(Foo$0) }
211 "#,
212         );
213     }
214
215     #[test]
216     fn goto_def_at_start_of_item() {
217         check(
218             r#"
219 struct Foo;
220      //^^^
221 enum E { X($0Foo) }
222 "#,
223         );
224     }
225
226     #[test]
227     fn goto_definition_resolves_correct_name() {
228         check(
229             r#"
230 //- /lib.rs
231 use a::Foo;
232 mod a;
233 mod b;
234 enum E { X(Foo$0) }
235
236 //- /a.rs
237 struct Foo;
238      //^^^
239 //- /b.rs
240 struct Foo;
241 "#,
242         );
243     }
244
245     #[test]
246     fn goto_def_for_module_declaration() {
247         check(
248             r#"
249 //- /lib.rs
250 mod $0foo;
251
252 //- /foo.rs
253 // empty
254 //^ file
255 "#,
256         );
257
258         check(
259             r#"
260 //- /lib.rs
261 mod $0foo;
262
263 //- /foo/mod.rs
264 // empty
265 //^ file
266 "#,
267         );
268     }
269
270     #[test]
271     fn goto_def_for_macros() {
272         check(
273             r#"
274 macro_rules! foo { () => { () } }
275            //^^^
276 fn bar() {
277     $0foo!();
278 }
279 "#,
280         );
281     }
282
283     #[test]
284     fn goto_def_for_macros_from_other_crates() {
285         check(
286             r#"
287 //- /lib.rs crate:main deps:foo
288 use foo::foo;
289 fn bar() {
290     $0foo!();
291 }
292
293 //- /foo/lib.rs crate:foo
294 #[macro_export]
295 macro_rules! foo { () => { () } }
296            //^^^
297 "#,
298         );
299     }
300
301     #[test]
302     fn goto_def_for_macros_in_use_tree() {
303         check(
304             r#"
305 //- /lib.rs crate:main deps:foo
306 use foo::foo$0;
307
308 //- /foo/lib.rs crate:foo
309 #[macro_export]
310 macro_rules! foo { () => { () } }
311            //^^^
312 "#,
313         );
314     }
315
316     #[test]
317     fn goto_def_for_macro_defined_fn_with_arg() {
318         check(
319             r#"
320 //- /lib.rs
321 macro_rules! define_fn {
322     ($name:ident) => (fn $name() {})
323 }
324
325 define_fn!(foo);
326          //^^^
327
328 fn bar() {
329    $0foo();
330 }
331 "#,
332         );
333     }
334
335     #[test]
336     fn goto_def_for_macro_defined_fn_no_arg() {
337         check(
338             r#"
339 //- /lib.rs
340 macro_rules! define_fn {
341     () => (fn foo() {})
342 }
343
344   define_fn!();
345 //^^^^^^^^^^^^^
346
347 fn bar() {
348    $0foo();
349 }
350 "#,
351         );
352     }
353
354     #[test]
355     fn goto_definition_works_for_macro_inside_pattern() {
356         check(
357             r#"
358 //- /lib.rs
359 macro_rules! foo {() => {0}}
360            //^^^
361
362 fn bar() {
363     match (0,1) {
364         ($0foo!(), _) => {}
365     }
366 }
367 "#,
368         );
369     }
370
371     #[test]
372     fn goto_definition_works_for_macro_inside_match_arm_lhs() {
373         check(
374             r#"
375 //- /lib.rs
376 macro_rules! foo {() => {0}}
377            //^^^
378 fn bar() {
379     match 0 {
380         $0foo!() => {}
381     }
382 }
383 "#,
384         );
385     }
386
387     #[test]
388     fn goto_def_for_use_alias() {
389         check(
390             r#"
391 //- /lib.rs crate:main deps:foo
392 use foo as bar$0;
393
394 //- /foo/lib.rs crate:foo
395 // empty
396 //^ file
397 "#,
398         );
399     }
400
401     #[test]
402     fn goto_def_for_use_alias_foo_macro() {
403         check(
404             r#"
405 //- /lib.rs crate:main deps:foo
406 use foo::foo as bar$0;
407
408 //- /foo/lib.rs crate:foo
409 #[macro_export]
410 macro_rules! foo { () => { () } }
411            //^^^
412 "#,
413         );
414     }
415
416     #[test]
417     fn goto_def_for_methods() {
418         check(
419             r#"
420 struct Foo;
421 impl Foo {
422     fn frobnicate(&self) { }
423      //^^^^^^^^^^
424 }
425
426 fn bar(foo: &Foo) {
427     foo.frobnicate$0();
428 }
429 "#,
430         );
431     }
432
433     #[test]
434     fn goto_def_for_fields() {
435         check(
436             r#"
437 struct Foo {
438     spam: u32,
439 } //^^^^
440
441 fn bar(foo: &Foo) {
442     foo.spam$0;
443 }
444 "#,
445         );
446     }
447
448     #[test]
449     fn goto_def_for_record_fields() {
450         check(
451             r#"
452 //- /lib.rs
453 struct Foo {
454     spam: u32,
455 } //^^^^
456
457 fn bar() -> Foo {
458     Foo {
459         spam$0: 0,
460     }
461 }
462 "#,
463         );
464     }
465
466     #[test]
467     fn goto_def_for_record_pat_fields() {
468         check(
469             r#"
470 //- /lib.rs
471 struct Foo {
472     spam: u32,
473 } //^^^^
474
475 fn bar(foo: Foo) -> Foo {
476     let Foo { spam$0: _, } = foo
477 }
478 "#,
479         );
480     }
481
482     #[test]
483     fn goto_def_for_record_fields_macros() {
484         check(
485             r"
486 macro_rules! m { () => { 92 };}
487 struct Foo { spam: u32 }
488            //^^^^
489
490 fn bar() -> Foo {
491     Foo { spam$0: m!() }
492 }
493 ",
494         );
495     }
496
497     #[test]
498     fn goto_for_tuple_fields() {
499         check(
500             r#"
501 struct Foo(u32);
502          //^^^
503
504 fn bar() {
505     let foo = Foo(0);
506     foo.$00;
507 }
508 "#,
509         );
510     }
511
512     #[test]
513     fn goto_def_for_ufcs_inherent_methods() {
514         check(
515             r#"
516 struct Foo;
517 impl Foo {
518     fn frobnicate() { }
519 }    //^^^^^^^^^^
520
521 fn bar(foo: &Foo) {
522     Foo::frobnicate$0();
523 }
524 "#,
525         );
526     }
527
528     #[test]
529     fn goto_def_for_ufcs_trait_methods_through_traits() {
530         check(
531             r#"
532 trait Foo {
533     fn frobnicate();
534 }    //^^^^^^^^^^
535
536 fn bar() {
537     Foo::frobnicate$0();
538 }
539 "#,
540         );
541     }
542
543     #[test]
544     fn goto_def_for_ufcs_trait_methods_through_self() {
545         check(
546             r#"
547 struct Foo;
548 trait Trait {
549     fn frobnicate();
550 }    //^^^^^^^^^^
551 impl Trait for Foo {}
552
553 fn bar() {
554     Foo::frobnicate$0();
555 }
556 "#,
557         );
558     }
559
560     #[test]
561     fn goto_definition_on_self() {
562         check(
563             r#"
564 struct Foo;
565 impl Foo {
566    //^^^
567     pub fn new() -> Self {
568         Self$0 {}
569     }
570 }
571 "#,
572         );
573         check(
574             r#"
575 struct Foo;
576 impl Foo {
577    //^^^
578     pub fn new() -> Self$0 {
579         Self {}
580     }
581 }
582 "#,
583         );
584
585         check(
586             r#"
587 enum Foo { A }
588 impl Foo {
589    //^^^
590     pub fn new() -> Self$0 {
591         Foo::A
592     }
593 }
594 "#,
595         );
596
597         check(
598             r#"
599 enum Foo { A }
600 impl Foo {
601    //^^^
602     pub fn thing(a: &Self$0) {
603     }
604 }
605 "#,
606         );
607     }
608
609     #[test]
610     fn goto_definition_on_self_in_trait_impl() {
611         check(
612             r#"
613 struct Foo;
614 trait Make {
615     fn new() -> Self;
616 }
617 impl Make for Foo {
618             //^^^
619     fn new() -> Self {
620         Self$0 {}
621     }
622 }
623 "#,
624         );
625
626         check(
627             r#"
628 struct Foo;
629 trait Make {
630     fn new() -> Self;
631 }
632 impl Make for Foo {
633             //^^^
634     fn new() -> Self$0 {
635         Self {}
636     }
637 }
638 "#,
639         );
640     }
641
642     #[test]
643     fn goto_def_when_used_on_definition_name_itself() {
644         check(
645             r#"
646 struct Foo$0 { value: u32 }
647      //^^^
648             "#,
649         );
650
651         check(
652             r#"
653 struct Foo {
654     field$0: string,
655 } //^^^^^
656 "#,
657         );
658
659         check(
660             r#"
661 fn foo_test$0() { }
662  //^^^^^^^^
663 "#,
664         );
665
666         check(
667             r#"
668 enum Foo$0 { Variant }
669    //^^^
670 "#,
671         );
672
673         check(
674             r#"
675 enum Foo {
676     Variant1,
677     Variant2$0,
678   //^^^^^^^^
679     Variant3,
680 }
681 "#,
682         );
683
684         check(
685             r#"
686 static INNER$0: &str = "";
687      //^^^^^
688 "#,
689         );
690
691         check(
692             r#"
693 const INNER$0: &str = "";
694     //^^^^^
695 "#,
696         );
697
698         check(
699             r#"
700 type Thing$0 = Option<()>;
701    //^^^^^
702 "#,
703         );
704
705         check(
706             r#"
707 trait Foo$0 { }
708     //^^^
709 "#,
710         );
711
712         check(
713             r#"
714 mod bar$0 { }
715   //^^^
716 "#,
717         );
718     }
719
720     #[test]
721     fn goto_from_macro() {
722         check(
723             r#"
724 macro_rules! id {
725     ($($tt:tt)*) => { $($tt)* }
726 }
727 fn foo() {}
728  //^^^
729 id! {
730     fn bar() {
731         fo$0o();
732     }
733 }
734 mod confuse_index { fn foo(); }
735 "#,
736         );
737     }
738
739     #[test]
740     fn goto_through_format() {
741         check(
742             r#"
743 #[macro_export]
744 macro_rules! format {
745     ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
746 }
747 #[rustc_builtin_macro]
748 #[macro_export]
749 macro_rules! format_args {
750     ($fmt:expr) => ({ /* compiler built-in */ });
751     ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
752 }
753 pub mod __export {
754     pub use crate::format_args;
755     fn foo() {} // for index confusion
756 }
757 fn foo() -> i8 {}
758  //^^^
759 fn test() {
760     format!("{}", fo$0o())
761 }
762 "#,
763         );
764     }
765
766     #[test]
767     fn goto_through_included_file() {
768         check(
769             r#"
770 //- /main.rs
771 #[rustc_builtin_macro]
772 macro_rules! include {}
773
774   include!("foo.rs");
775 //^^^^^^^^^^^^^^^^^^^
776
777 fn f() {
778     foo$0();
779 }
780
781 mod confuse_index {
782     pub fn foo() {}
783 }
784
785 //- /foo.rs
786 fn foo() {}
787         "#,
788         );
789     }
790
791     #[test]
792     fn goto_for_type_param() {
793         check(
794             r#"
795 struct Foo<T: Clone> { t: $0T }
796          //^
797 "#,
798         );
799     }
800
801     #[test]
802     fn goto_within_macro() {
803         check(
804             r#"
805 macro_rules! id {
806     ($($tt:tt)*) => ($($tt)*)
807 }
808
809 fn foo() {
810     let x = 1;
811       //^
812     id!({
813         let y = $0x;
814         let z = y;
815     });
816 }
817 "#,
818         );
819
820         check(
821             r#"
822 macro_rules! id {
823     ($($tt:tt)*) => ($($tt)*)
824 }
825
826 fn foo() {
827     let x = 1;
828     id!({
829         let y = x;
830           //^
831         let z = $0y;
832     });
833 }
834 "#,
835         );
836     }
837
838     #[test]
839     fn goto_def_in_local_fn() {
840         check(
841             r#"
842 fn main() {
843     fn foo() {
844         let x = 92;
845           //^
846         $0x;
847     }
848 }
849 "#,
850         );
851     }
852
853     #[test]
854     fn goto_def_in_local_macro() {
855         check(
856             r#"
857 fn bar() {
858     macro_rules! foo { () => { () } }
859                //^^^
860     $0foo!();
861 }
862 "#,
863         );
864     }
865
866     #[test]
867     fn goto_def_for_field_init_shorthand() {
868         check(
869             r#"
870 struct Foo { x: i32 }
871 fn main() {
872     let x = 92;
873       //^
874     Foo { x$0 };
875 }
876 "#,
877         )
878     }
879
880     #[test]
881     fn goto_def_for_enum_variant_field() {
882         check(
883             r#"
884 enum Foo {
885     Bar { x: i32 }
886 }       //^
887 fn baz(foo: Foo) {
888     match foo {
889         Foo::Bar { x$0 } => x
890     };
891 }
892 "#,
893         );
894     }
895
896     #[test]
897     fn goto_def_for_enum_variant_self_pattern_const() {
898         check(
899             r#"
900 enum Foo { Bar }
901          //^^^
902 impl Foo {
903     fn baz(self) {
904         match self { Self::Bar$0 => {} }
905     }
906 }
907 "#,
908         );
909     }
910
911     #[test]
912     fn goto_def_for_enum_variant_self_pattern_record() {
913         check(
914             r#"
915 enum Foo { Bar { val: i32 } }
916          //^^^
917 impl Foo {
918     fn baz(self) -> i32 {
919         match self { Self::Bar$0 { val } => {} }
920     }
921 }
922 "#,
923         );
924     }
925
926     #[test]
927     fn goto_def_for_enum_variant_self_expr_const() {
928         check(
929             r#"
930 enum Foo { Bar }
931          //^^^
932 impl Foo {
933     fn baz(self) { Self::Bar$0; }
934 }
935 "#,
936         );
937     }
938
939     #[test]
940     fn goto_def_for_enum_variant_self_expr_record() {
941         check(
942             r#"
943 enum Foo { Bar { val: i32 } }
944          //^^^
945 impl Foo {
946     fn baz(self) { Self::Bar$0 {val: 4}; }
947 }
948 "#,
949         );
950     }
951
952     #[test]
953     fn goto_def_for_type_alias_generic_parameter() {
954         check(
955             r#"
956 type Alias<T> = T$0;
957          //^
958 "#,
959         )
960     }
961
962     #[test]
963     fn goto_def_for_macro_container() {
964         check(
965             r#"
966 //- /lib.rs crate:main deps:foo
967 foo::module$0::mac!();
968
969 //- /foo/lib.rs crate:foo
970 pub mod module {
971       //^^^^^^
972     #[macro_export]
973     macro_rules! _mac { () => { () } }
974     pub use crate::_mac as mac;
975 }
976 "#,
977         );
978     }
979
980     #[test]
981     fn goto_def_for_assoc_ty_in_path() {
982         check(
983             r#"
984 trait Iterator {
985     type Item;
986        //^^^^
987 }
988
989 fn f() -> impl Iterator<Item$0 = u8> {}
990 "#,
991         );
992     }
993
994     #[test]
995     fn unknown_assoc_ty() {
996         check_unresolved(
997             r#"
998 trait Iterator { type Item; }
999 fn f() -> impl Iterator<Invalid$0 = u8> {}
1000 "#,
1001         )
1002     }
1003
1004     #[test]
1005     fn goto_def_for_assoc_ty_in_path_multiple() {
1006         check(
1007             r#"
1008 trait Iterator {
1009     type A;
1010        //^
1011     type B;
1012 }
1013
1014 fn f() -> impl Iterator<A$0 = u8, B = ()> {}
1015 "#,
1016         );
1017         check(
1018             r#"
1019 trait Iterator {
1020     type A;
1021     type B;
1022        //^
1023 }
1024
1025 fn f() -> impl Iterator<A = u8, B$0 = ()> {}
1026 "#,
1027         );
1028     }
1029
1030     #[test]
1031     fn goto_def_for_assoc_ty_ufcs() {
1032         check(
1033             r#"
1034 trait Iterator {
1035     type Item;
1036        //^^^^
1037 }
1038
1039 fn g() -> <() as Iterator<Item$0 = ()>>::Item {}
1040 "#,
1041         );
1042     }
1043
1044     #[test]
1045     fn goto_def_for_assoc_ty_ufcs_multiple() {
1046         check(
1047             r#"
1048 trait Iterator {
1049     type A;
1050        //^
1051     type B;
1052 }
1053
1054 fn g() -> <() as Iterator<A$0 = (), B = u8>>::B {}
1055 "#,
1056         );
1057         check(
1058             r#"
1059 trait Iterator {
1060     type A;
1061     type B;
1062        //^
1063 }
1064
1065 fn g() -> <() as Iterator<A = (), B$0 = u8>>::A {}
1066 "#,
1067         );
1068     }
1069
1070     #[test]
1071     fn goto_self_param_ty_specified() {
1072         check(
1073             r#"
1074 struct Foo {}
1075
1076 impl Foo {
1077     fn bar(self: &Foo) {
1078          //^^^^
1079         let foo = sel$0f;
1080     }
1081 }"#,
1082         )
1083     }
1084
1085     #[test]
1086     fn goto_self_param_on_decl() {
1087         check(
1088             r#"
1089 struct Foo {}
1090
1091 impl Foo {
1092     fn bar(&self$0) {
1093           //^^^^
1094     }
1095 }"#,
1096         )
1097     }
1098
1099     #[test]
1100     fn goto_lifetime_param_on_decl() {
1101         check(
1102             r#"
1103 fn foo<'foobar$0>(_: &'foobar ()) {
1104      //^^^^^^^
1105 }"#,
1106         )
1107     }
1108
1109     #[test]
1110     fn goto_lifetime_param_decl() {
1111         check(
1112             r#"
1113 fn foo<'foobar>(_: &'foobar$0 ()) {
1114      //^^^^^^^
1115 }"#,
1116         )
1117     }
1118
1119     #[test]
1120     fn goto_lifetime_param_decl_nested() {
1121         check(
1122             r#"
1123 fn foo<'foobar>(_: &'foobar ()) {
1124     fn foo<'foobar>(_: &'foobar$0 ()) {}
1125          //^^^^^^^
1126 }"#,
1127         )
1128     }
1129
1130     #[test]
1131     #[ignore] // requires the HIR to somehow track these hrtb lifetimes
1132     fn goto_lifetime_hrtb() {
1133         check(
1134             r#"trait Foo<T> {}
1135 fn foo<T>() where for<'a> T: Foo<&'a$0 (u8, u16)>, {}
1136                     //^^
1137 "#,
1138         );
1139         check(
1140             r#"trait Foo<T> {}
1141 fn foo<T>() where for<'a$0> T: Foo<&'a (u8, u16)>, {}
1142                     //^^
1143 "#,
1144         );
1145     }
1146
1147     #[test]
1148     #[ignore] // requires ForTypes to be implemented
1149     fn goto_lifetime_hrtb_for_type() {
1150         check(
1151             r#"trait Foo<T> {}
1152 fn foo<T>() where T: for<'a> Foo<&'a$0 (u8, u16)>, {}
1153                        //^^
1154 "#,
1155         );
1156     }
1157
1158     #[test]
1159     fn goto_label() {
1160         check(
1161             r#"
1162 fn foo<'foo>(_: &'foo ()) {
1163     'foo: {
1164   //^^^^
1165         'bar: loop {
1166             break 'foo$0;
1167         }
1168     }
1169 }"#,
1170         )
1171     }
1172
1173     #[test]
1174     fn goto_def_for_intra_doc_link_same_file() {
1175         check(
1176             r#"
1177 /// Blah, [`bar`](bar) .. [`foo`](foo$0) has [`bar`](bar)
1178 pub fn bar() { }
1179
1180 /// You might want to see [`std::fs::read()`] too.
1181 pub fn foo() { }
1182      //^^^
1183
1184 }"#,
1185         )
1186     }
1187
1188     #[test]
1189     fn goto_def_for_intra_doc_link_inner() {
1190         check(
1191             r#"
1192 //- /main.rs
1193 mod m;
1194 struct S;
1195      //^
1196
1197 //- /m.rs
1198 //! [`super::S$0`]
1199 "#,
1200         )
1201     }
1202
1203     #[test]
1204     fn goto_incomplete_field() {
1205         check(
1206             r#"
1207 struct A { a: u32 }
1208          //^
1209 fn foo() { A { a$0: }; }
1210 "#,
1211         )
1212     }
1213
1214     #[test]
1215     fn goto_proc_macro() {
1216         check(
1217             r#"
1218 //- /main.rs crate:main deps:mac
1219 use mac::fn_macro;
1220
1221 fn_macro$0!();
1222
1223 //- /mac.rs crate:mac
1224 #[proc_macro]
1225 fn fn_macro() {}
1226  //^^^^^^^^
1227             "#,
1228         )
1229     }
1230
1231     #[test]
1232     fn goto_intra_doc_links() {
1233         check(
1234             r#"
1235
1236 pub mod theitem {
1237     /// This is the item. Cool!
1238     pub struct TheItem;
1239              //^^^^^^^
1240 }
1241
1242 /// Gives you a [`TheItem$0`].
1243 ///
1244 /// [`TheItem`]: theitem::TheItem
1245 pub fn gimme() -> theitem::TheItem {
1246     theitem::TheItem
1247 }
1248 "#,
1249         );
1250     }
1251
1252     #[test]
1253     fn goto_ident_from_pat_macro() {
1254         check(
1255             r#"
1256 macro_rules! pat {
1257     ($name:ident) => { Enum::Variant1($name) }
1258 }
1259
1260 enum Enum {
1261     Variant1(u8),
1262     Variant2,
1263 }
1264
1265 fn f(e: Enum) {
1266     match e {
1267         pat!(bind) => {
1268            //^^^^
1269             bind$0
1270         }
1271         Enum::Variant2 => {}
1272     }
1273 }
1274 "#,
1275         );
1276     }
1277
1278     #[test]
1279     fn goto_include() {
1280         check(
1281             r#"
1282 //- /main.rs
1283 fn main() {
1284     let str = include_str!("foo.txt$0");
1285 }
1286 //- /foo.txt
1287 // empty
1288 //^ file
1289 "#,
1290         );
1291     }
1292
1293     #[test]
1294     fn goto_def_of_trait_impl_fn() {
1295         check(
1296             r#"
1297 trait Twait {
1298     fn a();
1299     // ^
1300 }
1301
1302 struct Stwuct;
1303
1304 impl Twait for Stwuct {
1305     fn a$0();
1306 }
1307 "#,
1308         );
1309     }
1310 }