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