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