]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / ide / src / goto_definition.rs
1 use std::mem::discriminant;
2
3 use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
4 use hir::{AsAssocItem, AssocItem, 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 // For outline modules, this will navigate to the source file of the module.
19 //
20 // |===
21 // | Editor | Shortcut
22 //
23 // | VS Code | kbd:[F12]
24 // |===
25 //
26 // image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[]
27 pub(crate) fn goto_definition(
28 db: &RootDatabase,
29 position: FilePosition,
30 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
31 let sema = &Semantics::new(db);
32 let file = sema.parse(position.file_id).syntax().clone();
33 let original_token =
34 pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
35 IDENT
36 | INT_NUMBER
37 | LIFETIME_IDENT
38 | T![self]
39 | T![super]
40 | T![crate]
41 | T![Self]
42 | COMMENT => 4,
43 // index and prefix ops
44 T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
45 kind if kind.is_keyword() => 2,
46 T!['('] | T![')'] => 2,
47 kind if kind.is_trivia() => 0,
48 _ => 1,
49 })?;
50 if let Some(doc_comment) = token_as_doc_comment(&original_token) {
51 return doc_comment.get_definition_with_descend_at(
52 sema,
53 position.offset,
54 |def, _, link_range| {
55 let nav = def.try_to_nav(db)?;
56 Some(RangeInfo::new(link_range, vec![nav]))
57 },
58 );
59 }
60 let navs = sema
61 .descend_into_macros(original_token.clone())
62 .into_iter()
63 .filter_map(|token| {
64 let parent = token.parent()?;
65 if let Some(tt) = ast::TokenTree::cast(parent) {
66 if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), position.file_id)
67 {
68 return Some(vec![x]);
69 }
70 }
71 Some(
72 IdentClass::classify_token(sema, &token)?
73 .definitions()
74 .into_iter()
75 .flat_map(|def| {
76 try_filter_trait_item_definition(sema, &def)
77 .unwrap_or_else(|| def_to_nav(sema.db, def))
78 })
79 .collect(),
80 )
81 })
82 .flatten()
83 .unique()
84 .collect::<Vec<NavigationTarget>>();
85
86 Some(RangeInfo::new(original_token.text_range(), navs))
87 }
88
89 fn try_lookup_include_path(
90 sema: &Semantics<'_, RootDatabase>,
91 tt: ast::TokenTree,
92 token: SyntaxToken,
93 file_id: FileId,
94 ) -> Option<NavigationTarget> {
95 let token = ast::String::cast(token)?;
96 let path = token.value()?.into_owned();
97 let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?;
98 let name = macro_call.path()?.segment()?.name_ref()?;
99 if !matches!(&*name.text(), "include" | "include_str" | "include_bytes") {
100 return None;
101 }
102
103 // Ignore non-built-in macros to account for shadowing
104 if let Some(it) = sema.resolve_macro_call(&macro_call) {
105 if !matches!(it.kind(sema.db), hir::MacroKind::BuiltIn) {
106 return None;
107 }
108 }
109
110 let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?;
111 let size = sema.db.file_text(file_id).len().try_into().ok()?;
112 Some(NavigationTarget {
113 file_id,
114 full_range: TextRange::new(0.into(), size),
115 name: path.into(),
116 focus_range: None,
117 kind: None,
118 container_name: None,
119 description: None,
120 docs: None,
121 })
122 }
123 /// finds the trait definition of an impl'd item, except function
124 /// e.g.
125 /// ```rust
126 /// trait A { type a; }
127 /// struct S;
128 /// impl A for S { type a = i32; } // <-- on this associate type, will get the location of a in the trait
129 /// ```
130 fn try_filter_trait_item_definition(
131 sema: &Semantics<'_, RootDatabase>,
132 def: &Definition,
133 ) -> Option<Vec<NavigationTarget>> {
134 let db = sema.db;
135 let assoc = def.as_assoc_item(db)?;
136 match assoc {
137 AssocItem::Function(..) => None,
138 AssocItem::Const(..) | AssocItem::TypeAlias(..) => {
139 let imp = match assoc.container(db) {
140 hir::AssocItemContainer::Impl(imp) => imp,
141 _ => return None,
142 };
143 let trait_ = imp.trait_(db)?;
144 let name = def.name(db)?;
145 let discri_value = discriminant(&assoc);
146 trait_
147 .items(db)
148 .iter()
149 .filter(|itm| discriminant(*itm) == discri_value)
150 .find_map(|itm| (itm.name(db)? == name).then(|| itm.try_to_nav(db)).flatten())
151 .map(|it| vec![it])
152 }
153 }
154 }
155
156 fn def_to_nav(db: &RootDatabase, def: Definition) -> Vec<NavigationTarget> {
157 def.try_to_nav(db).map(|it| vec![it]).unwrap_or_default()
158 }
159
160 #[cfg(test)]
161 mod tests {
162 use ide_db::base_db::FileRange;
163 use itertools::Itertools;
164
165 use crate::fixture;
166
167 #[track_caller]
168 fn check(ra_fixture: &str) {
169 let (analysis, position, expected) = fixture::annotations(ra_fixture);
170 let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
171
172 let cmp = |&FileRange { file_id, range }: &_| (file_id, range.start());
173 let navs = navs
174 .into_iter()
175 .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
176 .sorted_by_key(cmp)
177 .collect::<Vec<_>>();
178 let expected = expected
179 .into_iter()
180 .map(|(FileRange { file_id, range }, _)| FileRange { file_id, range })
181 .sorted_by_key(cmp)
182 .collect::<Vec<_>>();
183 assert_eq!(expected, navs);
184 }
185
186 fn check_unresolved(ra_fixture: &str) {
187 let (analysis, position) = fixture::position(ra_fixture);
188 let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
189
190 assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {navs:?}")
191 }
192
193 #[test]
194 fn goto_def_if_items_same_name() {
195 check(
196 r#"
197 trait Trait {
198 type A;
199 const A: i32;
200 //^
201 }
202
203 struct T;
204 impl Trait for T {
205 type A = i32;
206 const A$0: i32 = -9;
207 }"#,
208 );
209 }
210 #[test]
211 fn goto_def_in_mac_call_in_attr_invoc() {
212 check(
213 r#"
214 //- proc_macros: identity
215 pub struct Struct {
216 // ^^^^^^
217 field: i32,
218 }
219
220 macro_rules! identity {
221 ($($tt:tt)*) => {$($tt)*};
222 }
223
224 #[proc_macros::identity]
225 fn function() {
226 identity!(Struct$0 { field: 0 });
227 }
228
229 "#,
230 )
231 }
232
233 #[test]
234 fn goto_def_for_extern_crate() {
235 check(
236 r#"
237 //- /main.rs crate:main deps:std
238 extern crate std$0;
239 //- /std/lib.rs crate:std
240 // empty
241 //^file
242 "#,
243 )
244 }
245
246 #[test]
247 fn goto_def_for_renamed_extern_crate() {
248 check(
249 r#"
250 //- /main.rs crate:main deps:std
251 extern crate std as abc$0;
252 //- /std/lib.rs crate:std
253 // empty
254 //^file
255 "#,
256 )
257 }
258
259 #[test]
260 fn goto_def_in_items() {
261 check(
262 r#"
263 struct Foo;
264 //^^^
265 enum E { X(Foo$0) }
266 "#,
267 );
268 }
269
270 #[test]
271 fn goto_def_at_start_of_item() {
272 check(
273 r#"
274 struct Foo;
275 //^^^
276 enum E { X($0Foo) }
277 "#,
278 );
279 }
280
281 #[test]
282 fn goto_definition_resolves_correct_name() {
283 check(
284 r#"
285 //- /lib.rs
286 use a::Foo;
287 mod a;
288 mod b;
289 enum E { X(Foo$0) }
290
291 //- /a.rs
292 pub struct Foo;
293 //^^^
294 //- /b.rs
295 pub struct Foo;
296 "#,
297 );
298 }
299
300 #[test]
301 fn goto_def_for_module_declaration() {
302 check(
303 r#"
304 //- /lib.rs
305 mod $0foo;
306
307 //- /foo.rs
308 // empty
309 //^file
310 "#,
311 );
312
313 check(
314 r#"
315 //- /lib.rs
316 mod $0foo;
317
318 //- /foo/mod.rs
319 // empty
320 //^file
321 "#,
322 );
323 }
324
325 #[test]
326 fn goto_def_for_macros() {
327 check(
328 r#"
329 macro_rules! foo { () => { () } }
330 //^^^
331 fn bar() {
332 $0foo!();
333 }
334 "#,
335 );
336 }
337
338 #[test]
339 fn goto_def_for_macros_from_other_crates() {
340 check(
341 r#"
342 //- /lib.rs crate:main deps:foo
343 use foo::foo;
344 fn bar() {
345 $0foo!();
346 }
347
348 //- /foo/lib.rs crate:foo
349 #[macro_export]
350 macro_rules! foo { () => { () } }
351 //^^^
352 "#,
353 );
354 }
355
356 #[test]
357 fn goto_def_for_macros_in_use_tree() {
358 check(
359 r#"
360 //- /lib.rs crate:main deps:foo
361 use foo::foo$0;
362
363 //- /foo/lib.rs crate:foo
364 #[macro_export]
365 macro_rules! foo { () => { () } }
366 //^^^
367 "#,
368 );
369 }
370
371 #[test]
372 fn goto_def_for_macro_defined_fn_with_arg() {
373 check(
374 r#"
375 //- /lib.rs
376 macro_rules! define_fn {
377 ($name:ident) => (fn $name() {})
378 }
379
380 define_fn!(foo);
381 //^^^
382
383 fn bar() {
384 $0foo();
385 }
386 "#,
387 );
388 }
389
390 #[test]
391 fn goto_def_for_macro_defined_fn_no_arg() {
392 check(
393 r#"
394 //- /lib.rs
395 macro_rules! define_fn {
396 () => (fn foo() {})
397 }
398
399 define_fn!();
400 //^^^^^^^^^^^^^
401
402 fn bar() {
403 $0foo();
404 }
405 "#,
406 );
407 }
408
409 #[test]
410 fn goto_definition_works_for_macro_inside_pattern() {
411 check(
412 r#"
413 //- /lib.rs
414 macro_rules! foo {() => {0}}
415 //^^^
416
417 fn bar() {
418 match (0,1) {
419 ($0foo!(), _) => {}
420 }
421 }
422 "#,
423 );
424 }
425
426 #[test]
427 fn goto_definition_works_for_macro_inside_match_arm_lhs() {
428 check(
429 r#"
430 //- /lib.rs
431 macro_rules! foo {() => {0}}
432 //^^^
433 fn bar() {
434 match 0 {
435 $0foo!() => {}
436 }
437 }
438 "#,
439 );
440 }
441
442 #[test]
443 fn goto_def_for_use_alias() {
444 check(
445 r#"
446 //- /lib.rs crate:main deps:foo
447 use foo as bar$0;
448
449 //- /foo/lib.rs crate:foo
450 // empty
451 //^file
452 "#,
453 );
454 }
455
456 #[test]
457 fn goto_def_for_use_alias_foo_macro() {
458 check(
459 r#"
460 //- /lib.rs crate:main deps:foo
461 use foo::foo as bar$0;
462
463 //- /foo/lib.rs crate:foo
464 #[macro_export]
465 macro_rules! foo { () => { () } }
466 //^^^
467 "#,
468 );
469 }
470
471 #[test]
472 fn goto_def_for_methods() {
473 check(
474 r#"
475 struct Foo;
476 impl Foo {
477 fn frobnicate(&self) { }
478 //^^^^^^^^^^
479 }
480
481 fn bar(foo: &Foo) {
482 foo.frobnicate$0();
483 }
484 "#,
485 );
486 }
487
488 #[test]
489 fn goto_def_for_fields() {
490 check(
491 r#"
492 struct Foo {
493 spam: u32,
494 } //^^^^
495
496 fn bar(foo: &Foo) {
497 foo.spam$0;
498 }
499 "#,
500 );
501 }
502
503 #[test]
504 fn goto_def_for_record_fields() {
505 check(
506 r#"
507 //- /lib.rs
508 struct Foo {
509 spam: u32,
510 } //^^^^
511
512 fn bar() -> Foo {
513 Foo {
514 spam$0: 0,
515 }
516 }
517 "#,
518 );
519 }
520
521 #[test]
522 fn goto_def_for_record_pat_fields() {
523 check(
524 r#"
525 //- /lib.rs
526 struct Foo {
527 spam: u32,
528 } //^^^^
529
530 fn bar(foo: Foo) -> Foo {
531 let Foo { spam$0: _, } = foo
532 }
533 "#,
534 );
535 }
536
537 #[test]
538 fn goto_def_for_record_fields_macros() {
539 check(
540 r"
541 macro_rules! m { () => { 92 };}
542 struct Foo { spam: u32 }
543 //^^^^
544
545 fn bar() -> Foo {
546 Foo { spam$0: m!() }
547 }
548 ",
549 );
550 }
551
552 #[test]
553 fn goto_for_tuple_fields() {
554 check(
555 r#"
556 struct Foo(u32);
557 //^^^
558
559 fn bar() {
560 let foo = Foo(0);
561 foo.$00;
562 }
563 "#,
564 );
565 }
566
567 #[test]
568 fn goto_def_for_ufcs_inherent_methods() {
569 check(
570 r#"
571 struct Foo;
572 impl Foo {
573 fn frobnicate() { }
574 } //^^^^^^^^^^
575
576 fn bar(foo: &Foo) {
577 Foo::frobnicate$0();
578 }
579 "#,
580 );
581 }
582
583 #[test]
584 fn goto_def_for_ufcs_trait_methods_through_traits() {
585 check(
586 r#"
587 trait Foo {
588 fn frobnicate();
589 } //^^^^^^^^^^
590
591 fn bar() {
592 Foo::frobnicate$0();
593 }
594 "#,
595 );
596 }
597
598 #[test]
599 fn goto_def_for_ufcs_trait_methods_through_self() {
600 check(
601 r#"
602 struct Foo;
603 trait Trait {
604 fn frobnicate();
605 } //^^^^^^^^^^
606 impl Trait for Foo {}
607
608 fn bar() {
609 Foo::frobnicate$0();
610 }
611 "#,
612 );
613 }
614
615 #[test]
616 fn goto_definition_on_self() {
617 check(
618 r#"
619 struct Foo;
620 impl Foo {
621 //^^^
622 pub fn new() -> Self {
623 Self$0 {}
624 }
625 }
626 "#,
627 );
628 check(
629 r#"
630 struct Foo;
631 impl Foo {
632 //^^^
633 pub fn new() -> Self$0 {
634 Self {}
635 }
636 }
637 "#,
638 );
639
640 check(
641 r#"
642 enum Foo { A }
643 impl Foo {
644 //^^^
645 pub fn new() -> Self$0 {
646 Foo::A
647 }
648 }
649 "#,
650 );
651
652 check(
653 r#"
654 enum Foo { A }
655 impl Foo {
656 //^^^
657 pub fn thing(a: &Self$0) {
658 }
659 }
660 "#,
661 );
662 }
663
664 #[test]
665 fn goto_definition_on_self_in_trait_impl() {
666 check(
667 r#"
668 struct Foo;
669 trait Make {
670 fn new() -> Self;
671 }
672 impl Make for Foo {
673 //^^^
674 fn new() -> Self {
675 Self$0 {}
676 }
677 }
678 "#,
679 );
680
681 check(
682 r#"
683 struct Foo;
684 trait Make {
685 fn new() -> Self;
686 }
687 impl Make for Foo {
688 //^^^
689 fn new() -> Self$0 {
690 Self {}
691 }
692 }
693 "#,
694 );
695 }
696
697 #[test]
698 fn goto_def_when_used_on_definition_name_itself() {
699 check(
700 r#"
701 struct Foo$0 { value: u32 }
702 //^^^
703 "#,
704 );
705
706 check(
707 r#"
708 struct Foo {
709 field$0: string,
710 } //^^^^^
711 "#,
712 );
713
714 check(
715 r#"
716 fn foo_test$0() { }
717 //^^^^^^^^
718 "#,
719 );
720
721 check(
722 r#"
723 enum Foo$0 { Variant }
724 //^^^
725 "#,
726 );
727
728 check(
729 r#"
730 enum Foo {
731 Variant1,
732 Variant2$0,
733 //^^^^^^^^
734 Variant3,
735 }
736 "#,
737 );
738
739 check(
740 r#"
741 static INNER$0: &str = "";
742 //^^^^^
743 "#,
744 );
745
746 check(
747 r#"
748 const INNER$0: &str = "";
749 //^^^^^
750 "#,
751 );
752
753 check(
754 r#"
755 type Thing$0 = Option<()>;
756 //^^^^^
757 "#,
758 );
759
760 check(
761 r#"
762 trait Foo$0 { }
763 //^^^
764 "#,
765 );
766
767 check(
768 r#"
769 trait Foo$0 = ;
770 //^^^
771 "#,
772 );
773
774 check(
775 r#"
776 mod bar$0 { }
777 //^^^
778 "#,
779 );
780 }
781
782 #[test]
783 fn goto_from_macro() {
784 check(
785 r#"
786 macro_rules! id {
787 ($($tt:tt)*) => { $($tt)* }
788 }
789 fn foo() {}
790 //^^^
791 id! {
792 fn bar() {
793 fo$0o();
794 }
795 }
796 mod confuse_index { fn foo(); }
797 "#,
798 );
799 }
800
801 #[test]
802 fn goto_through_format() {
803 check(
804 r#"
805 #[macro_export]
806 macro_rules! format {
807 ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
808 }
809 #[rustc_builtin_macro]
810 #[macro_export]
811 macro_rules! format_args {
812 ($fmt:expr) => ({ /* compiler built-in */ });
813 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
814 }
815 pub mod __export {
816 pub use crate::format_args;
817 fn foo() {} // for index confusion
818 }
819 fn foo() -> i8 {}
820 //^^^
821 fn test() {
822 format!("{}", fo$0o())
823 }
824 "#,
825 );
826 }
827
828 #[test]
829 fn goto_through_included_file() {
830 check(
831 r#"
832 //- /main.rs
833 #[rustc_builtin_macro]
834 macro_rules! include {}
835
836 include!("foo.rs");
837 //^^^^^^^^^^^^^^^^^^^
838
839 fn f() {
840 foo$0();
841 }
842
843 mod confuse_index {
844 pub fn foo() {}
845 }
846
847 //- /foo.rs
848 fn foo() {}
849 "#,
850 );
851 }
852
853 #[test]
854 fn goto_for_type_param() {
855 check(
856 r#"
857 struct Foo<T: Clone> { t: $0T }
858 //^
859 "#,
860 );
861 }
862
863 #[test]
864 fn goto_within_macro() {
865 check(
866 r#"
867 macro_rules! id {
868 ($($tt:tt)*) => ($($tt)*)
869 }
870
871 fn foo() {
872 let x = 1;
873 //^
874 id!({
875 let y = $0x;
876 let z = y;
877 });
878 }
879 "#,
880 );
881
882 check(
883 r#"
884 macro_rules! id {
885 ($($tt:tt)*) => ($($tt)*)
886 }
887
888 fn foo() {
889 let x = 1;
890 id!({
891 let y = x;
892 //^
893 let z = $0y;
894 });
895 }
896 "#,
897 );
898 }
899
900 #[test]
901 fn goto_def_in_local_fn() {
902 check(
903 r#"
904 fn main() {
905 fn foo() {
906 let x = 92;
907 //^
908 $0x;
909 }
910 }
911 "#,
912 );
913 }
914
915 #[test]
916 fn goto_def_in_local_macro() {
917 check(
918 r#"
919 fn bar() {
920 macro_rules! foo { () => { () } }
921 //^^^
922 $0foo!();
923 }
924 "#,
925 );
926 }
927
928 #[test]
929 fn goto_def_for_field_init_shorthand() {
930 check(
931 r#"
932 struct Foo { x: i32 }
933 //^
934 fn main() {
935 let x = 92;
936 //^
937 Foo { x$0 };
938 }
939 "#,
940 )
941 }
942
943 #[test]
944 fn goto_def_for_enum_variant_field() {
945 check(
946 r#"
947 enum Foo {
948 Bar { x: i32 }
949 //^
950 }
951 fn baz(foo: Foo) {
952 match foo {
953 Foo::Bar { x$0 } => x
954 //^
955 };
956 }
957 "#,
958 );
959 }
960
961 #[test]
962 fn goto_def_for_enum_variant_self_pattern_const() {
963 check(
964 r#"
965 enum Foo { Bar }
966 //^^^
967 impl Foo {
968 fn baz(self) {
969 match self { Self::Bar$0 => {} }
970 }
971 }
972 "#,
973 );
974 }
975
976 #[test]
977 fn goto_def_for_enum_variant_self_pattern_record() {
978 check(
979 r#"
980 enum Foo { Bar { val: i32 } }
981 //^^^
982 impl Foo {
983 fn baz(self) -> i32 {
984 match self { Self::Bar$0 { val } => {} }
985 }
986 }
987 "#,
988 );
989 }
990
991 #[test]
992 fn goto_def_for_enum_variant_self_expr_const() {
993 check(
994 r#"
995 enum Foo { Bar }
996 //^^^
997 impl Foo {
998 fn baz(self) { Self::Bar$0; }
999 }
1000 "#,
1001 );
1002 }
1003
1004 #[test]
1005 fn goto_def_for_enum_variant_self_expr_record() {
1006 check(
1007 r#"
1008 enum Foo { Bar { val: i32 } }
1009 //^^^
1010 impl Foo {
1011 fn baz(self) { Self::Bar$0 {val: 4}; }
1012 }
1013 "#,
1014 );
1015 }
1016
1017 #[test]
1018 fn goto_def_for_type_alias_generic_parameter() {
1019 check(
1020 r#"
1021 type Alias<T> = T$0;
1022 //^
1023 "#,
1024 )
1025 }
1026
1027 #[test]
1028 fn goto_def_for_macro_container() {
1029 check(
1030 r#"
1031 //- /lib.rs crate:main deps:foo
1032 foo::module$0::mac!();
1033
1034 //- /foo/lib.rs crate:foo
1035 pub mod module {
1036 //^^^^^^
1037 #[macro_export]
1038 macro_rules! _mac { () => { () } }
1039 pub use crate::_mac as mac;
1040 }
1041 "#,
1042 );
1043 }
1044
1045 #[test]
1046 fn goto_def_for_assoc_ty_in_path() {
1047 check(
1048 r#"
1049 trait Iterator {
1050 type Item;
1051 //^^^^
1052 }
1053
1054 fn f() -> impl Iterator<Item$0 = u8> {}
1055 "#,
1056 );
1057 }
1058
1059 #[test]
1060 fn goto_def_for_super_assoc_ty_in_path() {
1061 check(
1062 r#"
1063 trait Super {
1064 type Item;
1065 //^^^^
1066 }
1067
1068 trait Sub: Super {}
1069
1070 fn f() -> impl Sub<Item$0 = u8> {}
1071 "#,
1072 );
1073 }
1074
1075 #[test]
1076 fn goto_def_for_module_declaration_in_path_if_types_and_values_same_name() {
1077 check(
1078 r#"
1079 mod bar {
1080 pub struct Foo {}
1081 //^^^
1082 pub fn Foo() {}
1083 }
1084
1085 fn baz() {
1086 let _foo_enum: bar::Foo$0 = bar::Foo {};
1087 }
1088 "#,
1089 )
1090 }
1091
1092 #[test]
1093 fn unknown_assoc_ty() {
1094 check_unresolved(
1095 r#"
1096 trait Iterator { type Item; }
1097 fn f() -> impl Iterator<Invalid$0 = u8> {}
1098 "#,
1099 )
1100 }
1101
1102 #[test]
1103 fn goto_def_for_assoc_ty_in_path_multiple() {
1104 check(
1105 r#"
1106 trait Iterator {
1107 type A;
1108 //^
1109 type B;
1110 }
1111
1112 fn f() -> impl Iterator<A$0 = u8, B = ()> {}
1113 "#,
1114 );
1115 check(
1116 r#"
1117 trait Iterator {
1118 type A;
1119 type B;
1120 //^
1121 }
1122
1123 fn f() -> impl Iterator<A = u8, B$0 = ()> {}
1124 "#,
1125 );
1126 }
1127
1128 #[test]
1129 fn goto_def_for_assoc_ty_ufcs() {
1130 check(
1131 r#"
1132 trait Iterator {
1133 type Item;
1134 //^^^^
1135 }
1136
1137 fn g() -> <() as Iterator<Item$0 = ()>>::Item {}
1138 "#,
1139 );
1140 }
1141
1142 #[test]
1143 fn goto_def_for_assoc_ty_ufcs_multiple() {
1144 check(
1145 r#"
1146 trait Iterator {
1147 type A;
1148 //^
1149 type B;
1150 }
1151
1152 fn g() -> <() as Iterator<A$0 = (), B = u8>>::B {}
1153 "#,
1154 );
1155 check(
1156 r#"
1157 trait Iterator {
1158 type A;
1159 type B;
1160 //^
1161 }
1162
1163 fn g() -> <() as Iterator<A = (), B$0 = u8>>::A {}
1164 "#,
1165 );
1166 }
1167
1168 #[test]
1169 fn goto_self_param_ty_specified() {
1170 check(
1171 r#"
1172 struct Foo {}
1173
1174 impl Foo {
1175 fn bar(self: &Foo) {
1176 //^^^^
1177 let foo = sel$0f;
1178 }
1179 }"#,
1180 )
1181 }
1182
1183 #[test]
1184 fn goto_self_param_on_decl() {
1185 check(
1186 r#"
1187 struct Foo {}
1188
1189 impl Foo {
1190 fn bar(&self$0) {
1191 //^^^^
1192 }
1193 }"#,
1194 )
1195 }
1196
1197 #[test]
1198 fn goto_lifetime_param_on_decl() {
1199 check(
1200 r#"
1201 fn foo<'foobar$0>(_: &'foobar ()) {
1202 //^^^^^^^
1203 }"#,
1204 )
1205 }
1206
1207 #[test]
1208 fn goto_lifetime_param_decl() {
1209 check(
1210 r#"
1211 fn foo<'foobar>(_: &'foobar$0 ()) {
1212 //^^^^^^^
1213 }"#,
1214 )
1215 }
1216
1217 #[test]
1218 fn goto_lifetime_param_decl_nested() {
1219 check(
1220 r#"
1221 fn foo<'foobar>(_: &'foobar ()) {
1222 fn foo<'foobar>(_: &'foobar$0 ()) {}
1223 //^^^^^^^
1224 }"#,
1225 )
1226 }
1227
1228 #[test]
1229 fn goto_lifetime_hrtb() {
1230 // FIXME: requires the HIR to somehow track these hrtb lifetimes
1231 check_unresolved(
1232 r#"
1233 trait Foo<T> {}
1234 fn foo<T>() where for<'a> T: Foo<&'a$0 (u8, u16)>, {}
1235 //^^
1236 "#,
1237 );
1238 check_unresolved(
1239 r#"
1240 trait Foo<T> {}
1241 fn foo<T>() where for<'a$0> T: Foo<&'a (u8, u16)>, {}
1242 //^^
1243 "#,
1244 );
1245 }
1246
1247 #[test]
1248 fn goto_lifetime_hrtb_for_type() {
1249 // FIXME: requires ForTypes to be implemented
1250 check_unresolved(
1251 r#"trait Foo<T> {}
1252 fn foo<T>() where T: for<'a> Foo<&'a$0 (u8, u16)>, {}
1253 //^^
1254 "#,
1255 );
1256 }
1257
1258 #[test]
1259 fn goto_label() {
1260 check(
1261 r#"
1262 fn foo<'foo>(_: &'foo ()) {
1263 'foo: {
1264 //^^^^
1265 'bar: loop {
1266 break 'foo$0;
1267 }
1268 }
1269 }"#,
1270 )
1271 }
1272
1273 #[test]
1274 fn goto_def_for_intra_doc_link_same_file() {
1275 check(
1276 r#"
1277 /// Blah, [`bar`](bar) .. [`foo`](foo$0) has [`bar`](bar)
1278 pub fn bar() { }
1279
1280 /// You might want to see [`std::fs::read()`] too.
1281 pub fn foo() { }
1282 //^^^
1283
1284 }"#,
1285 )
1286 }
1287
1288 #[test]
1289 fn goto_def_for_intra_doc_link_inner() {
1290 check(
1291 r#"
1292 //- /main.rs
1293 mod m;
1294 struct S;
1295 //^
1296
1297 //- /m.rs
1298 //! [`super::S$0`]
1299 "#,
1300 )
1301 }
1302
1303 #[test]
1304 fn goto_incomplete_field() {
1305 check(
1306 r#"
1307 struct A { a: u32 }
1308 //^
1309 fn foo() { A { a$0: }; }
1310 "#,
1311 )
1312 }
1313
1314 #[test]
1315 fn goto_proc_macro() {
1316 check(
1317 r#"
1318 //- /main.rs crate:main deps:mac
1319 use mac::fn_macro;
1320
1321 fn_macro$0!();
1322
1323 //- /mac.rs crate:mac
1324 #![crate_type="proc-macro"]
1325 #[proc_macro]
1326 fn fn_macro() {}
1327 //^^^^^^^^
1328 "#,
1329 )
1330 }
1331
1332 #[test]
1333 fn goto_intra_doc_links() {
1334 check(
1335 r#"
1336
1337 pub mod theitem {
1338 /// This is the item. Cool!
1339 pub struct TheItem;
1340 //^^^^^^^
1341 }
1342
1343 /// Gives you a [`TheItem$0`].
1344 ///
1345 /// [`TheItem`]: theitem::TheItem
1346 pub fn gimme() -> theitem::TheItem {
1347 theitem::TheItem
1348 }
1349 "#,
1350 );
1351 }
1352
1353 #[test]
1354 fn goto_ident_from_pat_macro() {
1355 check(
1356 r#"
1357 macro_rules! pat {
1358 ($name:ident) => { Enum::Variant1($name) }
1359 }
1360
1361 enum Enum {
1362 Variant1(u8),
1363 Variant2,
1364 }
1365
1366 fn f(e: Enum) {
1367 match e {
1368 pat!(bind) => {
1369 //^^^^
1370 bind$0
1371 }
1372 Enum::Variant2 => {}
1373 }
1374 }
1375 "#,
1376 );
1377 }
1378
1379 #[test]
1380 fn goto_include() {
1381 check(
1382 r#"
1383 //- /main.rs
1384
1385 #[rustc_builtin_macro]
1386 macro_rules! include_str {}
1387
1388 fn main() {
1389 let str = include_str!("foo.txt$0");
1390 }
1391 //- /foo.txt
1392 // empty
1393 //^file
1394 "#,
1395 );
1396 }
1397
1398 #[test]
1399 fn goto_doc_include_str() {
1400 check(
1401 r#"
1402 //- /main.rs
1403 #[rustc_builtin_macro]
1404 macro_rules! include_str {}
1405
1406 #[doc = include_str!("docs.md$0")]
1407 struct Item;
1408
1409 //- /docs.md
1410 // docs
1411 //^file
1412 "#,
1413 );
1414 }
1415
1416 #[test]
1417 fn goto_shadow_include() {
1418 check(
1419 r#"
1420 //- /main.rs
1421 macro_rules! include {
1422 ("included.rs") => {}
1423 }
1424
1425 include!("included.rs$0");
1426
1427 //- /included.rs
1428 // empty
1429 "#,
1430 );
1431 }
1432
1433 mod goto_impl_of_trait_fn {
1434 use super::check;
1435 #[test]
1436 fn cursor_on_impl() {
1437 check(
1438 r#"
1439 trait Twait {
1440 fn a();
1441 }
1442
1443 struct Stwuct;
1444
1445 impl Twait for Stwuct {
1446 fn a$0();
1447 //^
1448 }
1449 "#,
1450 );
1451 }
1452 #[test]
1453 fn method_call() {
1454 check(
1455 r#"
1456 trait Twait {
1457 fn a(&self);
1458 }
1459
1460 struct Stwuct;
1461
1462 impl Twait for Stwuct {
1463 fn a(&self){};
1464 //^
1465 }
1466 fn f() {
1467 let s = Stwuct;
1468 s.a$0();
1469 }
1470 "#,
1471 );
1472 }
1473 #[test]
1474 fn path_call() {
1475 check(
1476 r#"
1477 trait Twait {
1478 fn a(&self);
1479 }
1480
1481 struct Stwuct;
1482
1483 impl Twait for Stwuct {
1484 fn a(&self){};
1485 //^
1486 }
1487 fn f() {
1488 let s = Stwuct;
1489 Stwuct::a$0(&s);
1490 }
1491 "#,
1492 );
1493 }
1494 #[test]
1495 fn where_clause_can_work() {
1496 check(
1497 r#"
1498 trait G {
1499 fn g(&self);
1500 }
1501 trait Bound{}
1502 trait EA{}
1503 struct Gen<T>(T);
1504 impl <T:EA> G for Gen<T> {
1505 fn g(&self) {
1506 }
1507 }
1508 impl <T> G for Gen<T>
1509 where T : Bound
1510 {
1511 fn g(&self){
1512 //^
1513 }
1514 }
1515 struct A;
1516 impl Bound for A{}
1517 fn f() {
1518 let gen = Gen::<A>(A);
1519 gen.g$0();
1520 }
1521 "#,
1522 );
1523 }
1524 #[test]
1525 fn wc_case_is_ok() {
1526 check(
1527 r#"
1528 trait G {
1529 fn g(&self);
1530 }
1531 trait BParent{}
1532 trait Bound: BParent{}
1533 struct Gen<T>(T);
1534 impl <T> G for Gen<T>
1535 where T : Bound
1536 {
1537 fn g(&self){
1538 //^
1539 }
1540 }
1541 struct A;
1542 impl Bound for A{}
1543 fn f() {
1544 let gen = Gen::<A>(A);
1545 gen.g$0();
1546 }
1547 "#,
1548 );
1549 }
1550
1551 #[test]
1552 fn method_call_defaulted() {
1553 check(
1554 r#"
1555 trait Twait {
1556 fn a(&self) {}
1557 //^
1558 }
1559
1560 struct Stwuct;
1561
1562 impl Twait for Stwuct {
1563 }
1564 fn f() {
1565 let s = Stwuct;
1566 s.a$0();
1567 }
1568 "#,
1569 );
1570 }
1571
1572 #[test]
1573 fn method_call_on_generic() {
1574 check(
1575 r#"
1576 trait Twait {
1577 fn a(&self) {}
1578 //^
1579 }
1580
1581 fn f<T: Twait>(s: T) {
1582 s.a$0();
1583 }
1584 "#,
1585 );
1586 }
1587 }
1588
1589 #[test]
1590 fn goto_def_of_trait_impl_const() {
1591 check(
1592 r#"
1593 trait Twait {
1594 const NOMS: bool;
1595 // ^^^^
1596 }
1597
1598 struct Stwuct;
1599
1600 impl Twait for Stwuct {
1601 const NOMS$0: bool = true;
1602 }
1603 "#,
1604 );
1605 }
1606
1607 #[test]
1608 fn goto_def_of_trait_impl_type_alias() {
1609 check(
1610 r#"
1611 trait Twait {
1612 type IsBad;
1613 // ^^^^^
1614 }
1615
1616 struct Stwuct;
1617
1618 impl Twait for Stwuct {
1619 type IsBad$0 = !;
1620 }
1621 "#,
1622 );
1623 }
1624
1625 #[test]
1626 fn goto_def_derive_input() {
1627 check(
1628 r#"
1629 //- minicore:derive
1630 #[rustc_builtin_macro]
1631 pub macro Copy {}
1632 // ^^^^
1633 #[derive(Copy$0)]
1634 struct Foo;
1635 "#,
1636 );
1637 check(
1638 r#"
1639 //- minicore:derive
1640 #[rustc_builtin_macro]
1641 pub macro Copy {}
1642 // ^^^^
1643 #[cfg_attr(feature = "false", derive)]
1644 #[derive(Copy$0)]
1645 struct Foo;
1646 "#,
1647 );
1648 check(
1649 r#"
1650 //- minicore:derive
1651 mod foo {
1652 #[rustc_builtin_macro]
1653 pub macro Copy {}
1654 // ^^^^
1655 }
1656 #[derive(foo::Copy$0)]
1657 struct Foo;
1658 "#,
1659 );
1660 check(
1661 r#"
1662 //- minicore:derive
1663 mod foo {
1664 // ^^^
1665 #[rustc_builtin_macro]
1666 pub macro Copy {}
1667 }
1668 #[derive(foo$0::Copy)]
1669 struct Foo;
1670 "#,
1671 );
1672 }
1673
1674 #[test]
1675 fn goto_def_in_macro_multi() {
1676 check(
1677 r#"
1678 struct Foo {
1679 foo: ()
1680 //^^^
1681 }
1682 macro_rules! foo {
1683 ($ident:ident) => {
1684 fn $ident(Foo { $ident }: Foo) {}
1685 }
1686 }
1687 foo!(foo$0);
1688 //^^^
1689 //^^^
1690 "#,
1691 );
1692 check(
1693 r#"
1694 fn bar() {}
1695 //^^^
1696 struct bar;
1697 //^^^
1698 macro_rules! foo {
1699 ($ident:ident) => {
1700 fn foo() {
1701 let _: $ident = $ident;
1702 }
1703 }
1704 }
1705
1706 foo!(bar$0);
1707 "#,
1708 );
1709 }
1710
1711 #[test]
1712 fn goto_await_poll() {
1713 check(
1714 r#"
1715 //- minicore: future
1716
1717 struct MyFut;
1718
1719 impl core::future::Future for MyFut {
1720 type Output = ();
1721
1722 fn poll(
1723 //^^^^
1724 self: std::pin::Pin<&mut Self>,
1725 cx: &mut std::task::Context<'_>
1726 ) -> std::task::Poll<Self::Output>
1727 {
1728 ()
1729 }
1730 }
1731
1732 fn f() {
1733 MyFut.await$0;
1734 }
1735 "#,
1736 );
1737 }
1738
1739 #[test]
1740 fn goto_await_into_future_poll() {
1741 check(
1742 r#"
1743 //- minicore: future
1744
1745 struct Futurable;
1746
1747 impl core::future::IntoFuture for Futurable {
1748 type IntoFuture = MyFut;
1749 }
1750
1751 struct MyFut;
1752
1753 impl core::future::Future for MyFut {
1754 type Output = ();
1755
1756 fn poll(
1757 //^^^^
1758 self: std::pin::Pin<&mut Self>,
1759 cx: &mut std::task::Context<'_>
1760 ) -> std::task::Poll<Self::Output>
1761 {
1762 ()
1763 }
1764 }
1765
1766 fn f() {
1767 Futurable.await$0;
1768 }
1769 "#,
1770 );
1771 }
1772
1773 #[test]
1774 fn goto_try_op() {
1775 check(
1776 r#"
1777 //- minicore: try
1778
1779 struct Struct;
1780
1781 impl core::ops::Try for Struct {
1782 fn branch(
1783 //^^^^^^
1784 self
1785 ) {}
1786 }
1787
1788 fn f() {
1789 Struct?$0;
1790 }
1791 "#,
1792 );
1793 }
1794
1795 #[test]
1796 fn goto_index_op() {
1797 check(
1798 r#"
1799 //- minicore: index
1800
1801 struct Struct;
1802
1803 impl core::ops::Index<usize> for Struct {
1804 fn index(
1805 //^^^^^
1806 self
1807 ) {}
1808 }
1809
1810 fn f() {
1811 Struct[0]$0;
1812 }
1813 "#,
1814 );
1815 }
1816
1817 #[test]
1818 fn goto_prefix_op() {
1819 check(
1820 r#"
1821 //- minicore: deref
1822
1823 struct Struct;
1824
1825 impl core::ops::Deref for Struct {
1826 fn deref(
1827 //^^^^^
1828 self
1829 ) {}
1830 }
1831
1832 fn f() {
1833 $0*Struct;
1834 }
1835 "#,
1836 );
1837 }
1838
1839 #[test]
1840 fn goto_bin_op() {
1841 check(
1842 r#"
1843 //- minicore: add
1844
1845 struct Struct;
1846
1847 impl core::ops::Add for Struct {
1848 fn add(
1849 //^^^
1850 self
1851 ) {}
1852 }
1853
1854 fn f() {
1855 Struct +$0 Struct;
1856 }
1857 "#,
1858 );
1859 }
1860
1861 #[test]
1862 fn goto_bin_op_multiple_impl() {
1863 check(
1864 r#"
1865 //- minicore: add
1866 struct S;
1867 impl core::ops::Add for S {
1868 fn add(
1869 //^^^
1870 ) {}
1871 }
1872 impl core::ops::Add<usize> for S {
1873 fn add(
1874 ) {}
1875 }
1876
1877 fn f() {
1878 S +$0 S
1879 }
1880 "#,
1881 );
1882
1883 check(
1884 r#"
1885 //- minicore: add
1886 struct S;
1887 impl core::ops::Add for S {
1888 fn add(
1889 ) {}
1890 }
1891 impl core::ops::Add<usize> for S {
1892 fn add(
1893 //^^^
1894 ) {}
1895 }
1896
1897 fn f() {
1898 S +$0 0usize
1899 }
1900 "#,
1901 );
1902 }
1903
1904 #[test]
1905 fn path_call_multiple_trait_impl() {
1906 check(
1907 r#"
1908 trait Trait<T> {
1909 fn f(_: T);
1910 }
1911 impl Trait<i32> for usize {
1912 fn f(_: i32) {}
1913 //^
1914 }
1915 impl Trait<i64> for usize {
1916 fn f(_: i64) {}
1917 }
1918 fn main() {
1919 usize::f$0(0i32);
1920 }
1921 "#,
1922 );
1923
1924 check(
1925 r#"
1926 trait Trait<T> {
1927 fn f(_: T);
1928 }
1929 impl Trait<i32> for usize {
1930 fn f(_: i32) {}
1931 }
1932 impl Trait<i64> for usize {
1933 fn f(_: i64) {}
1934 //^
1935 }
1936 fn main() {
1937 usize::f$0(0i64);
1938 }
1939 "#,
1940 )
1941 }
1942
1943 #[test]
1944 fn query_impls_in_nearest_block() {
1945 check(
1946 r#"
1947 struct S1;
1948 impl S1 {
1949 fn e() -> () {}
1950 }
1951 fn f1() {
1952 struct S1;
1953 impl S1 {
1954 fn e() -> () {}
1955 //^
1956 }
1957 fn f2() {
1958 fn f3() {
1959 S1::e$0();
1960 }
1961 }
1962 }
1963 "#,
1964 );
1965
1966 check(
1967 r#"
1968 struct S1;
1969 impl S1 {
1970 fn e() -> () {}
1971 }
1972 fn f1() {
1973 struct S1;
1974 impl S1 {
1975 fn e() -> () {}
1976 //^
1977 }
1978 fn f2() {
1979 struct S2;
1980 S1::e$0();
1981 }
1982 }
1983 fn f12() {
1984 struct S1;
1985 impl S1 {
1986 fn e() -> () {}
1987 }
1988 }
1989 "#,
1990 );
1991
1992 check(
1993 r#"
1994 struct S1;
1995 impl S1 {
1996 fn e() -> () {}
1997 //^
1998 }
1999 fn f2() {
2000 struct S2;
2001 S1::e$0();
2002 }
2003 "#,
2004 );
2005 }
2006 }