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