aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/hover.rs3197
1 files changed, 1615 insertions, 1582 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 933e9b714..a18c43003 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -10,7 +10,7 @@ use ra_ide_db::{
10 defs::{classify_name, classify_name_ref, Definition}, 10 defs::{classify_name, classify_name_ref, Definition},
11 RootDatabase, 11 RootDatabase,
12}; 12};
13use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; 13use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
14 14
15use crate::{ 15use crate::{
16 display::{ 16 display::{
@@ -360,7 +360,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
360 fn priority(n: &SyntaxToken) -> usize { 360 fn priority(n: &SyntaxToken) -> usize {
361 match n.kind() { 361 match n.kind() {
362 IDENT | INT_NUMBER => 3, 362 IDENT | INT_NUMBER => 3,
363 L_PAREN | R_PAREN => 2, 363 T!['('] | T![')'] => 2,
364 kind if kind.is_trivia() => 0, 364 kind if kind.is_trivia() => 0,
365 _ => 1, 365 _ => 1,
366 } 366 }
@@ -369,44 +369,38 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
369 369
370#[cfg(test)] 370#[cfg(test)]
371mod tests { 371mod tests {
372 use super::*; 372 use expect::{expect, Expect};
373 use insta::assert_debug_snapshot;
374
375 use ra_db::FileLoader; 373 use ra_db::FileLoader;
376 use ra_syntax::TextRange;
377 374
378 use crate::mock_analysis::analysis_and_position; 375 use crate::mock_analysis::analysis_and_position;
379 376
380 fn trim_markup(s: &str) -> &str { 377 use super::*;
381 s.trim_start_matches("```rust\n").trim_end_matches("\n```")
382 }
383 378
384 fn assert_impl_action(action: &HoverAction, position: u32) { 379 fn check_hover_no_result(ra_fixture: &str) {
385 let offset = match action { 380 let (analysis, position) = analysis_and_position(ra_fixture);
386 HoverAction::Implementaion(pos) => pos.offset, 381 assert!(analysis.hover(position).unwrap().is_none());
387 it => panic!("Unexpected hover action: {:#?}", it),
388 };
389 assert_eq!(offset, position.into());
390 } 382 }
391 383
392 fn check_hover_result(ra_fixture: &str, expected: &str) -> (String, Vec<HoverAction>) { 384 fn check(ra_fixture: &str, expect: Expect) {
393 let (analysis, position) = analysis_and_position(ra_fixture); 385 let (analysis, position) = analysis_and_position(ra_fixture);
394 let hover = analysis.hover(position).unwrap().unwrap(); 386 let hover = analysis.hover(position).unwrap().unwrap();
395 let actual = trim_markup(hover.info.markup.as_str());
396 assert_eq!(expected, actual);
397 387
398 let content = analysis.db.file_text(position.file_id); 388 let content = analysis.db.file_text(position.file_id);
399 (content[hover.range].to_string(), hover.info.actions.clone()) 389 let hovered_element = &content[hover.range];
390
391 let actual = format!("{}:\n{}\n", hovered_element, hover.info.markup);
392 expect.assert_eq(&actual)
400 } 393 }
401 394
402 fn check_hover_no_result(ra_fixture: &str) { 395 fn check_actions(ra_fixture: &str, expect: Expect) {
403 let (analysis, position) = analysis_and_position(ra_fixture); 396 let (analysis, position) = analysis_and_position(ra_fixture);
404 assert!(analysis.hover(position).unwrap().is_none()); 397 let hover = analysis.hover(position).unwrap().unwrap();
398 expect.assert_debug_eq(&hover.info.actions)
405 } 399 }
406 400
407 #[test] 401 #[test]
408 fn hover_shows_type_of_an_expression() { 402 fn hover_shows_type_of_an_expression() {
409 let (analysis, position) = analysis_and_position( 403 check(
410 r#" 404 r#"
411pub fn foo() -> u32 { 1 } 405pub fn foo() -> u32 { 1 }
412 406
@@ -414,600 +408,643 @@ fn main() {
414 let foo_test = foo()<|>; 408 let foo_test = foo()<|>;
415} 409}
416"#, 410"#,
411 expect![[r#"
412 foo():
413 ```rust
414 u32
415 ```
416 "#]],
417 ); 417 );
418 let hover = analysis.hover(position).unwrap().unwrap();
419 assert_eq!(hover.range, TextRange::new(58.into(), 63.into()));
420 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("u32"));
421 } 418 }
422 419
423 #[test] 420 #[test]
424 fn hover_shows_long_type_of_an_expression() { 421 fn hover_shows_long_type_of_an_expression() {
425 check_hover_result(r#" 422 check(
426 //- /main.rs 423 r#"
427 struct Scan<A, B, C> { 424struct Scan<A, B, C> { a: A, b: B, c: C }
428 a: A, 425struct Iter<I> { inner: I }
429 b: B, 426enum Option<T> { Some(T), None }
430 c: C,
431 }
432
433 struct FakeIter<I> {
434 inner: I,
435 }
436 427
437 struct OtherStruct<T> { 428struct OtherStruct<T> { i: T }
438 i: T,
439 }
440 429
441 enum FakeOption<T> { 430fn scan<A, B, C>(a: A, b: B, c: C) -> Iter<Scan<OtherStruct<A>, B, C>> {
442 Some(T), 431 Iter { inner: Scan { a, b, c } }
443 None, 432}
444 }
445
446 fn scan<A, B, C>(a: A, b: B, c: C) -> FakeIter<Scan<OtherStruct<A>, B, C>> {
447 FakeIter { inner: Scan { a, b, c } }
448 }
449 433
450 fn main() { 434fn main() {
451 let num: i32 = 55; 435 let num: i32 = 55;
452 let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> FakeOption<u32> { 436 let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> Option<u32> {
453 FakeOption::Some(*memo + value) 437 Option::Some(*memo + value)
454 }; 438 };
455 let number = 5u32; 439 let number = 5u32;
456 let mut iter<|> = scan(OtherStruct { i: num }, closure, number); 440 let mut iter<|> = scan(OtherStruct { i: num }, closure, number);
457 } 441}
458 "#, "FakeIter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> FakeOption<u32>, u32>>"); 442"#,
443 expect![[r#"
444 iter:
445 ```rust
446 Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
447 ```
448 "#]],
449 );
459 } 450 }
460 451
461 #[test] 452 #[test]
462 fn hover_shows_fn_signature() { 453 fn hover_shows_fn_signature() {
463 // Single file with result 454 // Single file with result
464 check_hover_result( 455 check(
465 r#" 456 r#"
466 //- /main.rs 457pub fn foo() -> u32 { 1 }
467 pub fn foo() -> u32 { 1 }
468 458
469 fn main() { 459fn main() { let foo_test = fo<|>o(); }
470 let foo_test = fo<|>o(); 460"#,
471 } 461 expect![[r#"
472 "#, 462 foo:
473 "pub fn foo() -> u32", 463 ```rust
464 pub fn foo() -> u32
465 ```
466 "#]],
474 ); 467 );
475 468
476 // Multiple candidates but results are ambiguous. 469 // Multiple candidates but results are ambiguous.
477 check_hover_result( 470 check(
478 r#" 471 r#"
479 //- /a.rs 472//- /a.rs
480 pub fn foo() -> u32 { 1 } 473pub fn foo() -> u32 { 1 }
481 474
482 //- /b.rs 475//- /b.rs
483 pub fn foo() -> &str { "" } 476pub fn foo() -> &str { "" }
484 477
485 //- /c.rs 478//- /c.rs
486 pub fn foo(a: u32, b: u32) {} 479pub fn foo(a: u32, b: u32) {}
487 480
488 //- /main.rs 481//- /main.rs
489 mod a; 482mod a;
490 mod b; 483mod b;
491 mod c; 484mod c;
492 485
493 fn main() { 486fn main() { let foo_test = fo<|>o(); }
494 let foo_test = fo<|>o();
495 }
496 "#, 487 "#,
497 "{unknown}", 488 expect![[r#"
489 foo:
490 ```rust
491 {unknown}
492 ```
493 "#]],
498 ); 494 );
499 } 495 }
500 496
501 #[test] 497 #[test]
502 fn hover_shows_fn_signature_with_type_params() { 498 fn hover_shows_fn_signature_with_type_params() {
503 check_hover_result( 499 check(
504 r#" 500 r#"
505 //- /main.rs 501pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { }
506 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { }
507 502
508 fn main() { 503fn main() { let foo_test = fo<|>o(); }
509 let foo_test = fo<|>o();
510 }
511 "#, 504 "#,
512 "pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str", 505 expect![[r#"
506 foo:
507 ```rust
508 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str
509 ```
510 "#]],
513 ); 511 );
514 } 512 }
515 513
516 #[test] 514 #[test]
517 fn hover_shows_fn_signature_on_fn_name() { 515 fn hover_shows_fn_signature_on_fn_name() {
518 check_hover_result( 516 check(
519 r#" 517 r#"
520 //- /main.rs 518pub fn foo<|>(a: u32, b: u32) -> u32 {}
521 pub fn foo<|>(a: u32, b: u32) -> u32 {}
522 519
523 fn main() { 520fn main() { }
524 } 521"#,
525 "#, 522 expect![[r#"
526 "pub fn foo(a: u32, b: u32) -> u32", 523 foo:
524 ```rust
525 pub fn foo(a: u32, b: u32) -> u32
526 ```
527 "#]],
527 ); 528 );
528 } 529 }
529 530
530 #[test] 531 #[test]
531 fn hover_shows_struct_field_info() { 532 fn hover_shows_struct_field_info() {
532 // Hovering over the field when instantiating 533 // Hovering over the field when instantiating
533 check_hover_result( 534 check(
534 r#" 535 r#"
535 //- /main.rs 536struct Foo { field_a: u32 }
536 struct Foo {
537 field_a: u32,
538 }
539 537
540 fn main() { 538fn main() {
541 let foo = Foo { 539 let foo = Foo { field_a<|>: 0, };
542 field_a<|>: 0, 540}
543 }; 541"#,
544 } 542 expect![[r#"
545 "#, 543 field_a:
546 "Foo\n```\n\n```rust\nfield_a: u32", 544 ```rust
545 Foo
546 ```
547
548 ```rust
549 field_a: u32
550 ```
551 "#]],
547 ); 552 );
548 553
549 // Hovering over the field in the definition 554 // Hovering over the field in the definition
550 check_hover_result( 555 check(
551 r#" 556 r#"
552 //- /main.rs 557struct Foo { field_a<|>: u32 }
553 struct Foo {
554 field_a<|>: u32,
555 }
556 558
557 fn main() { 559fn main() {
558 let foo = Foo { 560 let foo = Foo { field_a: 0 };
559 field_a: 0, 561}
560 }; 562"#,
561 } 563 expect![[r#"
562 "#, 564 field_a:
563 "Foo\n```\n\n```rust\nfield_a: u32", 565 ```rust
566 Foo
567 ```
568
569 ```rust
570 field_a: u32
571 ```
572 "#]],
564 ); 573 );
565 } 574 }
566 575
567 #[test] 576 #[test]
568 fn hover_const_static() { 577 fn hover_const_static() {
569 check_hover_result( 578 check(
570 r#" 579 r#"const foo<|>: u32 = 0;"#,
571 //- /main.rs 580 expect![[r#"
572 const foo<|>: u32 = 0; 581 foo:
573 "#, 582 ```rust
574 "const foo: u32", 583 const foo: u32
584 ```
585 "#]],
575 ); 586 );
576 587 check(
577 check_hover_result( 588 r#"static foo<|>: u32 = 0;"#,
578 r#" 589 expect![[r#"
579 //- /main.rs 590 foo:
580 static foo<|>: u32 = 0; 591 ```rust
581 "#, 592 static foo: u32
582 "static foo: u32", 593 ```
594 "#]],
583 ); 595 );
584 } 596 }
585 597
586 #[test] 598 #[test]
587 fn hover_default_generic_types() { 599 fn hover_default_generic_types() {
588 check_hover_result( 600 check(
589 r#" 601 r#"
590//- /main.rs 602struct Test<K, T = u8> { k: K, t: T }
591struct Test<K, T = u8> {
592 k: K,
593 t: T,
594}
595 603
596fn main() { 604fn main() {
597 let zz<|> = Test { t: 23u8, k: 33 }; 605 let zz<|> = Test { t: 23u8, k: 33 };
598}"#, 606}"#,
599 "Test<i32, u8>", 607 expect![[r#"
608 zz:
609 ```rust
610 Test<i32, u8>
611 ```
612 "#]],
600 ); 613 );
601 } 614 }
602 615
603 #[test] 616 #[test]
604 fn hover_some() { 617 fn hover_some() {
605 let (analysis, position) = analysis_and_position( 618 check(
606 " 619 r#"
607 enum Option<T> { Some(T) } 620enum Option<T> { Some(T) }
608 use Option::Some; 621use Option::Some;
609 622
610 fn main() { 623fn main() { So<|>me(12); }
611 So<|>me(12); 624"#,
612 } 625 expect![[r#"
613 ", 626 Some:
627 ```rust
628 Option
629 ```
630
631 ```rust
632 Some
633 ```
634 "#]],
614 ); 635 );
615 let hover = analysis.hover(position).unwrap().unwrap();
616 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Option\n```\n\n```rust\nSome"));
617 636
618 let (analysis, position) = analysis_and_position( 637 check(
619 " 638 r#"
620 enum Option<T> { Some(T) } 639enum Option<T> { Some(T) }
621 use Option::Some; 640use Option::Some;
622 641
623 fn main() { 642fn main() { let b<|>ar = Some(12); }
624 let b<|>ar = Some(12); 643"#,
625 } 644 expect![[r#"
626 ", 645 bar:
646 ```rust
647 Option<i32>
648 ```
649 "#]],
627 ); 650 );
628 let hover = analysis.hover(position).unwrap().unwrap();
629 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Option<i32>"));
630 } 651 }
631 652
632 #[test] 653 #[test]
633 fn hover_enum_variant() { 654 fn hover_enum_variant() {
634 check_hover_result( 655 check(
635 r#" 656 r#"
636 //- /main.rs 657enum Option<T> {
637 enum Option<T> { 658 /// The None variant
638 /// The None variant 659 Non<|>e
639 Non<|>e 660}
640 } 661"#,
641 "#, 662 expect![[r#"
642 " 663 None:
643Option 664 ```rust
644``` 665 Option
645 666 ```
646```rust 667
647None 668 ```rust
648``` 669 None
649___ 670 ```
650 671 ___
651The None variant 672
652 " 673 The None variant
653 .trim(), 674 "#]],
654 ); 675 );
655 676
656 check_hover_result( 677 check(
657 r#" 678 r#"
658 //- /main.rs 679enum Option<T> {
659 enum Option<T> { 680 /// The Some variant
660 /// The Some variant 681 Some(T)
661 Some(T) 682}
662 } 683fn main() {
663 fn main() { 684 let s = Option::Som<|>e(12);
664 let s = Option::Som<|>e(12); 685}
665 } 686"#,
666 "#, 687 expect![[r#"
667 " 688 Some:
668Option 689 ```rust
669``` 690 Option
670 691 ```
671```rust 692
672Some 693 ```rust
673``` 694 Some
674___ 695 ```
675 696 ___
676The Some variant 697
677 " 698 The Some variant
678 .trim(), 699 "#]],
679 ); 700 );
680 } 701 }
681 702
682 #[test] 703 #[test]
683 fn hover_for_local_variable() { 704 fn hover_for_local_variable() {
684 let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }"); 705 check(
685 let hover = analysis.hover(position).unwrap().unwrap(); 706 r#"fn func(foo: i32) { fo<|>o; }"#,
686 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 707 expect![[r#"
708 foo:
709 ```rust
710 i32
711 ```
712 "#]],
713 )
687 } 714 }
688 715
689 #[test] 716 #[test]
690 fn hover_for_local_variable_pat() { 717 fn hover_for_local_variable_pat() {
691 let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}"); 718 check(
692 let hover = analysis.hover(position).unwrap().unwrap(); 719 r#"fn func(fo<|>o: i32) {}"#,
693 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 720 expect![[r#"
721 foo:
722 ```rust
723 i32
724 ```
725 "#]],
726 )
694 } 727 }
695 728
696 #[test] 729 #[test]
697 fn hover_local_var_edge() { 730 fn hover_local_var_edge() {
698 let (analysis, position) = analysis_and_position( 731 check(
699 " 732 r#"fn func(foo: i32) { if true { <|>foo; }; }"#,
700fn func(foo: i32) { if true { <|>foo; }; } 733 expect![[r#"
701", 734 foo:
702 ); 735 ```rust
703 let hover = analysis.hover(position).unwrap().unwrap(); 736 i32
704 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 737 ```
738 "#]],
739 )
705 } 740 }
706 741
707 #[test] 742 #[test]
708 fn hover_for_param_edge() { 743 fn hover_for_param_edge() {
709 let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}"); 744 check(
710 let hover = analysis.hover(position).unwrap().unwrap(); 745 r#"fn func(<|>foo: i32) {}"#,
711 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 746 expect![[r#"
747 foo:
748 ```rust
749 i32
750 ```
751 "#]],
752 )
712 } 753 }
713 754
714 #[test] 755 #[test]
715 fn test_hover_infer_associated_method_result() { 756 fn test_hover_infer_associated_method_result() {
716 let (analysis, position) = analysis_and_position( 757 check(
717 " 758 r#"
718 struct Thing { x: u32 } 759struct Thing { x: u32 }
719 760
720 impl Thing { 761impl Thing {
721 fn new() -> Thing { 762 fn new() -> Thing { Thing { x: 0 } }
722 Thing { x: 0 } 763}
723 }
724 }
725 764
726 fn main() { 765fn main() { let foo_<|>test = Thing::new(); }
727 let foo_<|>test = Thing::new(); 766 "#,
728 } 767 expect![[r#"
729 ", 768 foo_test:
730 ); 769 ```rust
731 let hover = analysis.hover(position).unwrap().unwrap(); 770 Thing
732 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); 771 ```
772 "#]],
773 )
733 } 774 }
734 775
735 #[test] 776 #[test]
736 fn test_hover_infer_associated_method_exact() { 777 fn test_hover_infer_associated_method_exact() {
737 let (analysis, position) = analysis_and_position( 778 check(
738 " 779 r#"
739 mod wrapper { 780mod wrapper {
740 struct Thing { x: u32 } 781 struct Thing { x: u32 }
741 782
742 impl Thing { 783 impl Thing {
743 fn new() -> Thing { 784 fn new() -> Thing { Thing { x: 0 } }
744 Thing { x: 0 } 785 }
745 } 786}
746 }
747 }
748 787
749 fn main() { 788fn main() { let foo_test = wrapper::Thing::new<|>(); }
750 let foo_test = wrapper::Thing::new<|>(); 789"#,
751 } 790 expect![[r#"
752 ", 791 new:
753 ); 792 ```rust
754 let hover = analysis.hover(position).unwrap().unwrap(); 793 wrapper::Thing
755 assert_eq!( 794 ```
756 trim_markup(&hover.info.markup.as_str()), 795
757 ("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing") 796 ```rust
758 ); 797 fn new() -> Thing
798 ```
799 "#]],
800 )
759 } 801 }
760 802
761 #[test] 803 #[test]
762 fn test_hover_infer_associated_const_in_pattern() { 804 fn test_hover_infer_associated_const_in_pattern() {
763 let (analysis, position) = analysis_and_position( 805 check(
764 " 806 r#"
765 struct X; 807struct X;
766 impl X { 808impl X {
767 const C: u32 = 1; 809 const C: u32 = 1;
768 } 810}
769 811
770 fn main() { 812fn main() {
771 match 1 { 813 match 1 {
772 X::C<|> => {}, 814 X::C<|> => {},
773 2 => {}, 815 2 => {},
774 _ => {} 816 _ => {}
775 }; 817 };
776 } 818}
777 ", 819"#,
778 ); 820 expect![[r#"
779 let hover = analysis.hover(position).unwrap().unwrap(); 821 C:
780 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("const C: u32")); 822 ```rust
823 const C: u32
824 ```
825 "#]],
826 )
781 } 827 }
782 828
783 #[test] 829 #[test]
784 fn test_hover_self() { 830 fn test_hover_self() {
785 let (analysis, position) = analysis_and_position( 831 check(
786 " 832 r#"
787 struct Thing { x: u32 } 833struct Thing { x: u32 }
788 impl Thing { 834impl Thing {
789 fn new() -> Self { 835 fn new() -> Self { Self<|> { x: 0 } }
790 Self<|> { x: 0 } 836}
791 } 837"#,
792 } 838 expect![[r#"
793 ", 839 Self { x: 0 }:
794 ); 840 ```rust
795 let hover = analysis.hover(position).unwrap().unwrap(); 841 Thing
796 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); 842 ```
797 843 "#]],
798 /* FIXME: revive these tests 844 )
799 let (analysis, position) = analysis_and_position( 845 } /* FIXME: revive these tests
800 " 846 let (analysis, position) = analysis_and_position(
801 struct Thing { x: u32 } 847 "
802 impl Thing { 848 struct Thing { x: u32 }
803 fn new() -> Self<|> { 849 impl Thing {
804 Self { x: 0 } 850 fn new() -> Self<|> {
805 } 851 Self { x: 0 }
806 } 852 }
807 ", 853 }
808 ); 854 ",
809 855 );
810 let hover = analysis.hover(position).unwrap().unwrap(); 856
811 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); 857 let hover = analysis.hover(position).unwrap().unwrap();
812 858 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing"));
813 let (analysis, position) = analysis_and_position( 859
814 " 860 let (analysis, position) = analysis_and_position(
815 enum Thing { A } 861 "
816 impl Thing { 862 enum Thing { A }
817 pub fn new() -> Self<|> { 863 impl Thing {
818 Thing::A 864 pub fn new() -> Self<|> {
819 } 865 Thing::A
820 } 866 }
821 ", 867 }
822 ); 868 ",
823 let hover = analysis.hover(position).unwrap().unwrap(); 869 );
824 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); 870 let hover = analysis.hover(position).unwrap().unwrap();
825 871 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing"));
826 let (analysis, position) = analysis_and_position( 872
827 " 873 let (analysis, position) = analysis_and_position(
828 enum Thing { A } 874 "
829 impl Thing { 875 enum Thing { A }
830 pub fn thing(a: Self<|>) { 876 impl Thing {
831 } 877 pub fn thing(a: Self<|>) {
832 } 878 }
833 ", 879 }
834 ); 880 ",
835 let hover = analysis.hover(position).unwrap().unwrap(); 881 );
836 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); 882 let hover = analysis.hover(position).unwrap().unwrap();
837 */ 883 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing"));
838 } 884 */
839 885
840 #[test] 886 #[test]
841 fn test_hover_shadowing_pat() { 887 fn test_hover_shadowing_pat() {
842 let (analysis, position) = analysis_and_position( 888 check(
843 " 889 r#"
844 fn x() {} 890fn x() {}
845 891
846 fn y() { 892fn y() {
847 let x = 0i32; 893 let x = 0i32;
848 x<|>; 894 x<|>;
849 } 895}
850 ", 896"#,
851 ); 897 expect![[r#"
852 let hover = analysis.hover(position).unwrap().unwrap(); 898 x:
853 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 899 ```rust
900 i32
901 ```
902 "#]],
903 )
854 } 904 }
855 905
856 #[test] 906 #[test]
857 fn test_hover_macro_invocation() { 907 fn test_hover_macro_invocation() {
858 let (analysis, position) = analysis_and_position( 908 check(
859 " 909 r#"
860 macro_rules! foo { 910macro_rules! foo { () => {} }
861 () => {}
862 }
863 911
864 fn f() { 912fn f() { fo<|>o!(); }
865 fo<|>o!(); 913"#,
866 } 914 expect![[r#"
867 ", 915 foo:
868 ); 916 ```rust
869 let hover = analysis.hover(position).unwrap().unwrap(); 917 macro_rules! foo
870 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("macro_rules! foo")); 918 ```
919 "#]],
920 )
871 } 921 }
872 922
873 #[test] 923 #[test]
874 fn test_hover_tuple_field() { 924 fn test_hover_tuple_field() {
875 let (analysis, position) = analysis_and_position( 925 check(
876 " 926 r#"struct TS(String, i32<|>);"#,
877 struct TS(String, i32<|>); 927 expect![[r#"
878 ", 928 i32:
879 ); 929 i32
880 let hover = analysis.hover(position).unwrap().unwrap(); 930 "#]],
881 assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); 931 )
882 } 932 }
883 933
884 #[test] 934 #[test]
885 fn test_hover_through_macro() { 935 fn test_hover_through_macro() {
886 let (hover_on, _) = check_hover_result( 936 check(
887 r" 937 r#"
888 //- /lib.rs 938macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
889 macro_rules! id { 939fn foo() {}
890 ($($tt:tt)*) => { $($tt)* } 940id! {
891 } 941 fn bar() { fo<|>o(); }
892 fn foo() {} 942}
893 id! { 943"#,
894 fn bar() { 944 expect![[r#"
895 fo<|>o(); 945 foo:
896 } 946 ```rust
897 } 947 fn foo()
898 ", 948 ```
899 "fn foo()", 949 "#]],
900 ); 950 );
901
902 assert_eq!(hover_on, "foo")
903 } 951 }
904 952
905 #[test] 953 #[test]
906 fn test_hover_through_expr_in_macro() { 954 fn test_hover_through_expr_in_macro() {
907 let (hover_on, _) = check_hover_result( 955 check(
908 r" 956 r#"
909 //- /lib.rs 957macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
910 macro_rules! id { 958fn foo(bar:u32) { let a = id!(ba<|>r); }
911 ($($tt:tt)*) => { $($tt)* } 959"#,
912 } 960 expect![[r#"
913 fn foo(bar:u32) { 961 bar:
914 let a = id!(ba<|>r); 962 ```rust
915 } 963 u32
916 ", 964 ```
917 "u32", 965 "#]],
918 ); 966 );
919
920 assert_eq!(hover_on, "bar")
921 } 967 }
922 968
923 #[test] 969 #[test]
924 fn test_hover_through_expr_in_macro_recursive() { 970 fn test_hover_through_expr_in_macro_recursive() {
925 let (hover_on, _) = check_hover_result( 971 check(
926 r" 972 r#"
927 //- /lib.rs 973macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
928 macro_rules! id_deep { 974macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
929 ($($tt:tt)*) => { $($tt)* } 975fn foo(bar:u32) { let a = id!(ba<|>r); }
930 } 976"#,
931 macro_rules! id { 977 expect![[r#"
932 ($($tt:tt)*) => { id_deep!($($tt)*) } 978 bar:
933 } 979 ```rust
934 fn foo(bar:u32) { 980 u32
935 let a = id!(ba<|>r); 981 ```
936 } 982 "#]],
937 ",
938 "u32",
939 ); 983 );
940
941 assert_eq!(hover_on, "bar")
942 } 984 }
943 985
944 #[test] 986 #[test]
945 fn test_hover_through_func_in_macro_recursive() { 987 fn test_hover_through_func_in_macro_recursive() {
946 let (hover_on, _) = check_hover_result( 988 check(
947 r" 989 r#"
948 //- /lib.rs 990macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
949 macro_rules! id_deep { 991macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
950 ($($tt:tt)*) => { $($tt)* } 992fn bar() -> u32 { 0 }
951 } 993fn foo() { let a = id!([0u32, bar(<|>)] ); }
952 macro_rules! id { 994"#,
953 ($($tt:tt)*) => { id_deep!($($tt)*) } 995 expect![[r#"
954 } 996 bar():
955 fn bar() -> u32 { 997 ```rust
956 0 998 u32
957 } 999 ```
958 fn foo() { 1000 "#]],
959 let a = id!([0u32, bar(<|>)] );
960 }
961 ",
962 "u32",
963 ); 1001 );
964
965 assert_eq!(hover_on, "bar()")
966 } 1002 }
967 1003
968 #[test] 1004 #[test]
969 fn test_hover_through_literal_string_in_macro() { 1005 fn test_hover_through_literal_string_in_macro() {
970 let (hover_on, _) = check_hover_result( 1006 check(
971 r#" 1007 r#"
972 //- /lib.rs 1008macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } }
973 macro_rules! arr { 1009fn foo() {
974 ($($tt:tt)*) => { [$($tt)*)] } 1010 let mastered_for_itunes = "";
975 } 1011 let _ = arr!("Tr<|>acks", &mastered_for_itunes);
976 fn foo() { 1012}
977 let mastered_for_itunes = ""; 1013"#,
978 let _ = arr!("Tr<|>acks", &mastered_for_itunes); 1014 expect![[r#"
979 } 1015 "Tracks":
980 "#, 1016 ```rust
981 "&str", 1017 &str
1018 ```
1019 "#]],
982 ); 1020 );
983
984 assert_eq!(hover_on, "\"Tracks\"");
985 } 1021 }
986 1022
987 #[test] 1023 #[test]
988 fn test_hover_through_assert_macro() { 1024 fn test_hover_through_assert_macro() {
989 let (hover_on, _) = check_hover_result( 1025 check(
990 r" 1026 r#"
991 //- /lib.rs 1027#[rustc_builtin_macro]
992 #[rustc_builtin_macro] 1028macro_rules! assert {}
993 macro_rules! assert {}
994 1029
995 fn bar() -> bool { true } 1030fn bar() -> bool { true }
996 fn foo() { 1031fn foo() {
997 assert!(ba<|>r()); 1032 assert!(ba<|>r());
998 } 1033}
999 ", 1034"#,
1000 "fn bar() -> bool", 1035 expect![[r#"
1036 bar:
1037 ```rust
1038 fn bar() -> bool
1039 ```
1040 "#]],
1001 ); 1041 );
1002
1003 assert_eq!(hover_on, "bar");
1004 } 1042 }
1005 1043
1006 #[test] 1044 #[test]
1007 fn test_hover_through_literal_string_in_builtin_macro() { 1045 fn test_hover_through_literal_string_in_builtin_macro() {
1008 check_hover_no_result( 1046 check_hover_no_result(
1009 r#" 1047 r#"
1010 //- /lib.rs
1011 #[rustc_builtin_macro] 1048 #[rustc_builtin_macro]
1012 macro_rules! format {} 1049 macro_rules! format {}
1013 1050
@@ -1020,122 +1057,159 @@ fn func(foo: i32) { if true { <|>foo; }; }
1020 1057
1021 #[test] 1058 #[test]
1022 fn test_hover_non_ascii_space_doc() { 1059 fn test_hover_non_ascii_space_doc() {
1023 check_hover_result( 1060 check(
1024 " 1061 "
1025 //- /lib.rs 1062/// <- `\u{3000}` here
1026 /// <- `\u{3000}` here 1063fn foo() { }
1027 fn foo() {
1028 }
1029 1064
1030 fn bar() { 1065fn bar() { fo<|>o(); }
1031 fo<|>o(); 1066",
1032 } 1067 expect![[r#"
1033 ", 1068 foo:
1034 "fn foo()\n```\n___\n\n<- `\u{3000}` here", 1069 ```rust
1070 fn foo()
1071 ```
1072 ___
1073
1074 <- ` ` here
1075 "#]],
1035 ); 1076 );
1036 } 1077 }
1037 1078
1038 #[test] 1079 #[test]
1039 fn test_hover_function_show_qualifiers() { 1080 fn test_hover_function_show_qualifiers() {
1040 check_hover_result( 1081 check(
1041 r" 1082 r#"async fn foo<|>() {}"#,
1042 //- /lib.rs 1083 expect![[r#"
1043 async fn foo<|>() {} 1084 foo:
1044 ", 1085 ```rust
1045 "async fn foo()", 1086 async fn foo()
1087 ```
1088 "#]],
1046 ); 1089 );
1047 check_hover_result( 1090 check(
1048 r" 1091 r#"pub const unsafe fn foo<|>() {}"#,
1049 //- /lib.rs 1092 expect![[r#"
1050 pub const unsafe fn foo<|>() {} 1093 foo:
1051 ", 1094 ```rust
1052 "pub const unsafe fn foo()", 1095 pub const unsafe fn foo()
1096 ```
1097 "#]],
1053 ); 1098 );
1054 check_hover_result( 1099 check(
1055 r#" 1100 r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#,
1056 //- /lib.rs 1101 expect![[r#"
1057 pub(crate) async unsafe extern "C" fn foo<|>() {} 1102 foo:
1058 "#, 1103 ```rust
1059 r#"pub(crate) async unsafe extern "C" fn foo()"#, 1104 pub(crate) async unsafe extern "C" fn foo()
1105 ```
1106 "#]],
1060 ); 1107 );
1061 } 1108 }
1062 1109
1063 #[test] 1110 #[test]
1064 fn test_hover_trait_show_qualifiers() { 1111 fn test_hover_trait_show_qualifiers() {
1065 let (_, actions) = check_hover_result( 1112 check_actions(
1066 r" 1113 r"unsafe trait foo<|>() {}",
1067 //- /lib.rs 1114 expect![[r#"
1068 unsafe trait foo<|>() {} 1115 [
1069 ", 1116 Implementaion(
1070 "unsafe trait foo", 1117 FilePosition {
1118 file_id: FileId(
1119 1,
1120 ),
1121 offset: 13,
1122 },
1123 ),
1124 ]
1125 "#]],
1071 ); 1126 );
1072 assert_impl_action(&actions[0], 13);
1073 } 1127 }
1074 1128
1075 #[test] 1129 #[test]
1076 fn test_hover_mod_with_same_name_as_function() { 1130 fn test_hover_mod_with_same_name_as_function() {
1077 check_hover_result( 1131 check(
1078 r" 1132 r#"
1079 //- /lib.rs 1133use self::m<|>y::Bar;
1080 use self::m<|>y::Bar; 1134mod my { pub struct Bar; }
1081
1082 mod my {
1083 pub struct Bar;
1084 }
1085 1135
1086 fn my() {} 1136fn my() {}
1087 ", 1137"#,
1088 "mod my", 1138 expect![[r#"
1139 my:
1140 ```rust
1141 mod my
1142 ```
1143 "#]],
1089 ); 1144 );
1090 } 1145 }
1091 1146
1092 #[test] 1147 #[test]
1093 fn test_hover_struct_doc_comment() { 1148 fn test_hover_struct_doc_comment() {
1094 check_hover_result( 1149 check(
1095 r#" 1150 r#"
1096 //- /lib.rs 1151/// bar docs
1097 /// bar docs 1152struct Bar;
1098 struct Bar;
1099 1153
1100 fn foo() { 1154fn foo() { let bar = Ba<|>r; }
1101 let bar = Ba<|>r; 1155"#,
1102 } 1156 expect![[r#"
1103 "#, 1157 Bar:
1104 "struct Bar\n```\n___\n\nbar docs", 1158 ```rust
1159 struct Bar
1160 ```
1161 ___
1162
1163 bar docs
1164 "#]],
1105 ); 1165 );
1106 } 1166 }
1107 1167
1108 #[test] 1168 #[test]
1109 fn test_hover_struct_doc_attr() { 1169 fn test_hover_struct_doc_attr() {
1110 check_hover_result( 1170 check(
1111 r#" 1171 r#"
1112 //- /lib.rs 1172#[doc = "bar docs"]
1113 #[doc = "bar docs"] 1173struct Bar;
1114 struct Bar;
1115 1174
1116 fn foo() { 1175fn foo() { let bar = Ba<|>r; }
1117 let bar = Ba<|>r; 1176"#,
1118 } 1177 expect![[r#"
1119 "#, 1178 Bar:
1120 "struct Bar\n```\n___\n\nbar docs", 1179 ```rust
1180 struct Bar
1181 ```
1182 ___
1183
1184 bar docs
1185 "#]],
1121 ); 1186 );
1122 } 1187 }
1123 1188
1124 #[test] 1189 #[test]
1125 fn test_hover_struct_doc_attr_multiple_and_mixed() { 1190 fn test_hover_struct_doc_attr_multiple_and_mixed() {
1126 check_hover_result( 1191 check(
1127 r#" 1192 r#"
1128 //- /lib.rs 1193/// bar docs 0
1129 /// bar docs 0 1194#[doc = "bar docs 1"]
1130 #[doc = "bar docs 1"] 1195#[doc = "bar docs 2"]
1131 #[doc = "bar docs 2"] 1196struct Bar;
1132 struct Bar;
1133 1197
1134 fn foo() { 1198fn foo() { let bar = Ba<|>r; }
1135 let bar = Ba<|>r; 1199"#,
1136 } 1200 expect![[r#"
1137 "#, 1201 Bar:
1138 "struct Bar\n```\n___\n\nbar docs 0\n\nbar docs 1\n\nbar docs 2", 1202 ```rust
1203 struct Bar
1204 ```
1205 ___
1206
1207 bar docs 0
1208
1209 bar docs 1
1210
1211 bar docs 2
1212 "#]],
1139 ); 1213 );
1140 } 1214 }
1141 1215
@@ -1143,27 +1217,35 @@ fn func(foo: i32) { if true { <|>foo; }; }
1143 fn test_hover_macro_generated_struct_fn_doc_comment() { 1217 fn test_hover_macro_generated_struct_fn_doc_comment() {
1144 mark::check!(hover_macro_generated_struct_fn_doc_comment); 1218 mark::check!(hover_macro_generated_struct_fn_doc_comment);
1145 1219
1146 check_hover_result( 1220 check(
1147 r#" 1221 r#"
1148 //- /lib.rs 1222macro_rules! bar {
1149 macro_rules! bar { 1223 () => {
1150 () => { 1224 struct Bar;
1151 struct Bar; 1225 impl Bar {
1152 impl Bar { 1226 /// Do the foo
1153 /// Do the foo 1227 fn foo(&self) {}
1154 fn foo(&self) {} 1228 }
1155 } 1229 }
1156 } 1230}
1157 }
1158 1231
1159 bar!(); 1232bar!();
1160 1233
1161 fn foo() { 1234fn foo() { let bar = Bar; bar.fo<|>o(); }
1162 let bar = Bar; 1235"#,
1163 bar.fo<|>o(); 1236 expect![[r#"
1164 } 1237 foo:
1165 "#, 1238 ```rust
1166 "Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\n Do the foo", 1239 Bar
1240 ```
1241
1242 ```rust
1243 fn foo(&self)
1244 ```
1245 ___
1246
1247 Do the foo
1248 "#]],
1167 ); 1249 );
1168 } 1250 }
1169 1251
@@ -1171,1204 +1253,1155 @@ fn func(foo: i32) { if true { <|>foo; }; }
1171 fn test_hover_macro_generated_struct_fn_doc_attr() { 1253 fn test_hover_macro_generated_struct_fn_doc_attr() {
1172 mark::check!(hover_macro_generated_struct_fn_doc_attr); 1254 mark::check!(hover_macro_generated_struct_fn_doc_attr);
1173 1255
1174 check_hover_result( 1256 check(
1175 r#" 1257 r#"
1176 //- /lib.rs 1258macro_rules! bar {
1177 macro_rules! bar { 1259 () => {
1178 () => { 1260 struct Bar;
1179 struct Bar; 1261 impl Bar {
1180 impl Bar { 1262 #[doc = "Do the foo"]
1181 #[doc = "Do the foo"] 1263 fn foo(&self) {}
1182 fn foo(&self) {} 1264 }
1183 } 1265 }
1184 } 1266}
1185 }
1186 1267
1187 bar!(); 1268bar!();
1188 1269
1189 fn foo() { 1270fn foo() { let bar = Bar; bar.fo<|>o(); }
1190 let bar = Bar; 1271"#,
1191 bar.fo<|>o(); 1272 expect![[r#"
1192 } 1273 foo:
1193 "#, 1274 ```rust
1194 "Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo", 1275 Bar
1276 ```
1277
1278 ```rust
1279 fn foo(&self)
1280 ```
1281 ___
1282
1283 Do the foo
1284 "#]],
1195 ); 1285 );
1196 } 1286 }
1197 1287
1198 #[test] 1288 #[test]
1199 fn test_hover_trait_has_impl_action() { 1289 fn test_hover_trait_has_impl_action() {
1200 let (_, actions) = check_hover_result( 1290 check_actions(
1201 r" 1291 r#"trait foo<|>() {}"#,
1202 //- /lib.rs 1292 expect![[r#"
1203 trait foo<|>() {} 1293 [
1204 ", 1294 Implementaion(
1205 "trait foo", 1295 FilePosition {
1296 file_id: FileId(
1297 1,
1298 ),
1299 offset: 6,
1300 },
1301 ),
1302 ]
1303 "#]],
1206 ); 1304 );
1207 assert_impl_action(&actions[0], 6);
1208 } 1305 }
1209 1306
1210 #[test] 1307 #[test]
1211 fn test_hover_struct_has_impl_action() { 1308 fn test_hover_struct_has_impl_action() {
1212 let (_, actions) = check_hover_result( 1309 check_actions(
1213 r" 1310 r"struct foo<|>() {}",
1214 //- /lib.rs 1311 expect![[r#"
1215 struct foo<|>() {} 1312 [
1216 ", 1313 Implementaion(
1217 "struct foo", 1314 FilePosition {
1315 file_id: FileId(
1316 1,
1317 ),
1318 offset: 7,
1319 },
1320 ),
1321 ]
1322 "#]],
1218 ); 1323 );
1219 assert_impl_action(&actions[0], 7);
1220 } 1324 }
1221 1325
1222 #[test] 1326 #[test]
1223 fn test_hover_union_has_impl_action() { 1327 fn test_hover_union_has_impl_action() {
1224 let (_, actions) = check_hover_result( 1328 check_actions(
1225 r" 1329 r#"union foo<|>() {}"#,
1226 //- /lib.rs 1330 expect![[r#"
1227 union foo<|>() {} 1331 [
1228 ", 1332 Implementaion(
1229 "union foo", 1333 FilePosition {
1230 );
1231 assert_impl_action(&actions[0], 6);
1232 }
1233
1234 #[test]
1235 fn test_hover_enum_has_impl_action() {
1236 let (_, actions) = check_hover_result(
1237 r"
1238 //- /lib.rs
1239 enum foo<|>() {
1240 A,
1241 B
1242 }
1243 ",
1244 "enum foo",
1245 );
1246 assert_impl_action(&actions[0], 5);
1247 }
1248
1249 #[test]
1250 fn test_hover_test_has_action() {
1251 let (_, actions) = check_hover_result(
1252 r"
1253 //- /lib.rs
1254 #[test]
1255 fn foo_<|>test() {}
1256 ",
1257 "fn foo_test()",
1258 );
1259 assert_debug_snapshot!(actions,
1260 @r###"
1261 [
1262 Runnable(
1263 Runnable {
1264 nav: NavigationTarget {
1265 file_id: FileId( 1334 file_id: FileId(
1266 1, 1335 1,
1267 ), 1336 ),
1268 full_range: 0..24, 1337 offset: 6,
1269 name: "foo_test",
1270 kind: FN_DEF,
1271 focus_range: Some(
1272 11..19,
1273 ),
1274 container_name: None,
1275 description: None,
1276 docs: None,
1277 }, 1338 },
1278 kind: Test { 1339 ),
1279 test_id: Path( 1340 ]
1280 "foo_test", 1341 "#]],
1281 ), 1342 );
1282 attr: TestAttr {
1283 ignore: false,
1284 },
1285 },
1286 cfg_exprs: [],
1287 },
1288 ),
1289 ]
1290 "###);
1291 } 1343 }
1292 1344
1293 #[test] 1345 #[test]
1294 fn test_hover_test_mod_has_action() { 1346 fn test_hover_enum_has_impl_action() {
1295 let (_, actions) = check_hover_result( 1347 check_actions(
1296 r" 1348 r"enum foo<|>() { A, B }",
1297 //- /lib.rs 1349 expect![[r#"
1298 mod tests<|> { 1350 [
1299 #[test] 1351 Implementaion(
1300 fn foo_test() {} 1352 FilePosition {
1301 }
1302 ",
1303 "mod tests",
1304 );
1305 assert_debug_snapshot!(actions,
1306 @r###"
1307 [
1308 Runnable(
1309 Runnable {
1310 nav: NavigationTarget {
1311 file_id: FileId( 1353 file_id: FileId(
1312 1, 1354 1,
1313 ), 1355 ),
1314 full_range: 0..46, 1356 offset: 5,
1315 name: "tests",
1316 kind: MODULE,
1317 focus_range: Some(
1318 4..9,
1319 ),
1320 container_name: None,
1321 description: None,
1322 docs: None,
1323 },
1324 kind: TestMod {
1325 path: "tests",
1326 }, 1357 },
1327 cfg_exprs: [], 1358 ),
1328 }, 1359 ]
1329 ), 1360 "#]],
1330 ] 1361 );
1331 "###);
1332 } 1362 }
1333 1363
1334 #[test] 1364 #[test]
1335 fn test_hover_struct_has_goto_type_action() { 1365 fn test_hover_test_has_action() {
1336 let (_, actions) = check_hover_result( 1366 check_actions(
1337 r" 1367 r#"
1338 //- /main.rs 1368#[test]
1339 struct S{ f1: u32 } 1369fn foo_<|>test() {}
1340 1370"#,
1341 fn main() { 1371 expect![[r#"
1342 let s<|>t = S{ f1:0 }; 1372 [
1343 } 1373 Runnable(
1344 ", 1374 Runnable {
1345 "S",
1346 );
1347 assert_debug_snapshot!(actions,
1348 @r###"
1349 [
1350 GoToType(
1351 [
1352 HoverGotoTypeData {
1353 mod_path: "S",
1354 nav: NavigationTarget { 1375 nav: NavigationTarget {
1355 file_id: FileId( 1376 file_id: FileId(
1356 1, 1377 1,
1357 ), 1378 ),
1358 full_range: 0..19, 1379 full_range: 0..24,
1359 name: "S", 1380 name: "foo_test",
1360 kind: STRUCT_DEF, 1381 kind: FN_DEF,
1361 focus_range: Some( 1382 focus_range: Some(
1362 7..8, 1383 11..19,
1363 ), 1384 ),
1364 container_name: None, 1385 container_name: None,
1365 description: Some( 1386 description: None,
1366 "struct S",
1367 ),
1368 docs: None, 1387 docs: None,
1369 }, 1388 },
1389 kind: Test {
1390 test_id: Path(
1391 "foo_test",
1392 ),
1393 attr: TestAttr {
1394 ignore: false,
1395 },
1396 },
1397 cfg_exprs: [],
1370 }, 1398 },
1371 ], 1399 ),
1372 ), 1400 ]
1373 ] 1401 "#]],
1374 "###); 1402 );
1375 } 1403 }
1376 1404
1377 #[test] 1405 #[test]
1378 fn test_hover_generic_struct_has_goto_type_actions() { 1406 fn test_hover_test_mod_has_action() {
1379 let (_, actions) = check_hover_result( 1407 check_actions(
1380 r" 1408 r#"
1381 //- /main.rs 1409mod tests<|> {
1382 struct Arg(u32); 1410 #[test]
1383 struct S<T>{ f1: T } 1411 fn foo_test() {}
1384 1412}
1385 fn main() { 1413"#,
1386 let s<|>t = S{ f1:Arg(0) }; 1414 expect![[r#"
1387 } 1415 [
1388 ", 1416 Runnable(
1389 "S<Arg>", 1417 Runnable {
1390 );
1391 assert_debug_snapshot!(actions,
1392 @r###"
1393 [
1394 GoToType(
1395 [
1396 HoverGotoTypeData {
1397 mod_path: "S",
1398 nav: NavigationTarget { 1418 nav: NavigationTarget {
1399 file_id: FileId( 1419 file_id: FileId(
1400 1, 1420 1,
1401 ), 1421 ),
1402 full_range: 17..37, 1422 full_range: 0..46,
1403 name: "S", 1423 name: "tests",
1404 kind: STRUCT_DEF, 1424 kind: MODULE,
1405 focus_range: Some( 1425 focus_range: Some(
1406 24..25, 1426 4..9,
1407 ), 1427 ),
1408 container_name: None, 1428 container_name: None,
1409 description: Some( 1429 description: None,
1410 "struct S",
1411 ),
1412 docs: None, 1430 docs: None,
1413 }, 1431 },
1414 }, 1432 kind: TestMod {
1415 HoverGotoTypeData { 1433 path: "tests",
1416 mod_path: "Arg",
1417 nav: NavigationTarget {
1418 file_id: FileId(
1419 1,
1420 ),
1421 full_range: 0..16,
1422 name: "Arg",
1423 kind: STRUCT_DEF,
1424 focus_range: Some(
1425 7..10,
1426 ),
1427 container_name: None,
1428 description: Some(
1429 "struct Arg",
1430 ),
1431 docs: None,
1432 }, 1434 },
1435 cfg_exprs: [],
1433 }, 1436 },
1434 ], 1437 ),
1435 ), 1438 ]
1436 ] 1439 "#]],
1437 "###); 1440 );
1438 } 1441 }
1439 1442
1440 #[test] 1443 #[test]
1441 fn test_hover_generic_struct_has_flattened_goto_type_actions() { 1444 fn test_hover_struct_has_goto_type_action() {
1442 let (_, actions) = check_hover_result( 1445 check_actions(
1443 r" 1446 r#"
1444 //- /main.rs 1447struct S{ f1: u32 }
1445 struct Arg(u32); 1448
1446 struct S<T>{ f1: T } 1449fn main() { let s<|>t = S{ f1:0 }; }
1447 1450 "#,
1448 fn main() { 1451 expect![[r#"
1449 let s<|>t = S{ f1: S{ f1: Arg(0) } }; 1452 [
1450 } 1453 GoToType(
1451 ", 1454 [
1452 "S<S<Arg>>", 1455 HoverGotoTypeData {
1456 mod_path: "S",
1457 nav: NavigationTarget {
1458 file_id: FileId(
1459 1,
1460 ),
1461 full_range: 0..19,
1462 name: "S",
1463 kind: STRUCT_DEF,
1464 focus_range: Some(
1465 7..8,
1466 ),
1467 container_name: None,
1468 description: Some(
1469 "struct S",
1470 ),
1471 docs: None,
1472 },
1473 },
1474 ],
1475 ),
1476 ]
1477 "#]],
1453 ); 1478 );
1454 assert_debug_snapshot!(actions, 1479 }
1455 @r###" 1480
1456 [ 1481 #[test]
1457 GoToType( 1482 fn test_hover_generic_struct_has_goto_type_actions() {
1458 [ 1483 check_actions(
1459 HoverGotoTypeData { 1484 r#"
1460 mod_path: "S", 1485struct Arg(u32);
1461 nav: NavigationTarget { 1486struct S<T>{ f1: T }
1462 file_id: FileId( 1487
1463 1, 1488fn main() { let s<|>t = S{ f1:Arg(0) }; }
1464 ), 1489"#,
1465 full_range: 17..37, 1490 expect![[r#"
1466 name: "S", 1491 [
1467 kind: STRUCT_DEF, 1492 GoToType(
1468 focus_range: Some( 1493 [
1469 24..25, 1494 HoverGotoTypeData {
1470 ), 1495 mod_path: "S",
1471 container_name: None, 1496 nav: NavigationTarget {
1472 description: Some( 1497 file_id: FileId(
1473 "struct S", 1498 1,
1474 ), 1499 ),
1475 docs: None, 1500 full_range: 17..37,
1501 name: "S",
1502 kind: STRUCT_DEF,
1503 focus_range: Some(
1504 24..25,
1505 ),
1506 container_name: None,
1507 description: Some(
1508 "struct S",
1509 ),
1510 docs: None,
1511 },
1476 }, 1512 },
1477 }, 1513 HoverGotoTypeData {
1478 HoverGotoTypeData { 1514 mod_path: "Arg",
1479 mod_path: "Arg", 1515 nav: NavigationTarget {
1480 nav: NavigationTarget { 1516 file_id: FileId(
1481 file_id: FileId( 1517 1,
1482 1, 1518 ),
1483 ), 1519 full_range: 0..16,
1484 full_range: 0..16, 1520 name: "Arg",
1485 name: "Arg", 1521 kind: STRUCT_DEF,
1486 kind: STRUCT_DEF, 1522 focus_range: Some(
1487 focus_range: Some( 1523 7..10,
1488 7..10, 1524 ),
1489 ), 1525 container_name: None,
1490 container_name: None, 1526 description: Some(
1491 description: Some( 1527 "struct Arg",
1492 "struct Arg", 1528 ),
1493 ), 1529 docs: None,
1494 docs: None, 1530 },
1495 }, 1531 },
1496 }, 1532 ],
1497 ], 1533 ),
1498 ), 1534 ]
1499 ] 1535 "#]],
1500 "###); 1536 );
1501 } 1537 }
1502 1538
1503 #[test] 1539 #[test]
1504 fn test_hover_tuple_has_goto_type_actions() { 1540 fn test_hover_generic_struct_has_flattened_goto_type_actions() {
1505 let (_, actions) = check_hover_result( 1541 check_actions(
1506 r" 1542 r#"
1507 //- /main.rs 1543struct Arg(u32);
1508 struct A(u32); 1544struct S<T>{ f1: T }
1509 struct B(u32);
1510 mod M {
1511 pub struct C(u32);
1512 }
1513 1545
1514 fn main() { 1546fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; }
1515 let s<|>t = (A(1), B(2), M::C(3) ); 1547 "#,
1516 } 1548 expect![[r#"
1517 ", 1549 [
1518 "(A, B, C)", 1550 GoToType(
1551 [
1552 HoverGotoTypeData {
1553 mod_path: "S",
1554 nav: NavigationTarget {
1555 file_id: FileId(
1556 1,
1557 ),
1558 full_range: 17..37,
1559 name: "S",
1560 kind: STRUCT_DEF,
1561 focus_range: Some(
1562 24..25,
1563 ),
1564 container_name: None,
1565 description: Some(
1566 "struct S",
1567 ),
1568 docs: None,
1569 },
1570 },
1571 HoverGotoTypeData {
1572 mod_path: "Arg",
1573 nav: NavigationTarget {
1574 file_id: FileId(
1575 1,
1576 ),
1577 full_range: 0..16,
1578 name: "Arg",
1579 kind: STRUCT_DEF,
1580 focus_range: Some(
1581 7..10,
1582 ),
1583 container_name: None,
1584 description: Some(
1585 "struct Arg",
1586 ),
1587 docs: None,
1588 },
1589 },
1590 ],
1591 ),
1592 ]
1593 "#]],
1519 ); 1594 );
1520 assert_debug_snapshot!(actions, 1595 }
1521 @r###" 1596
1522 [ 1597 #[test]
1523 GoToType( 1598 fn test_hover_tuple_has_goto_type_actions() {
1524 [ 1599 check_actions(
1525 HoverGotoTypeData { 1600 r#"
1526 mod_path: "A", 1601struct A(u32);
1527 nav: NavigationTarget { 1602struct B(u32);
1528 file_id: FileId( 1603mod M {
1529 1, 1604 pub struct C(u32);
1530 ), 1605}
1531 full_range: 0..14, 1606
1532 name: "A", 1607fn main() { let s<|>t = (A(1), B(2), M::C(3) ); }
1533 kind: STRUCT_DEF, 1608"#,
1534 focus_range: Some( 1609 expect![[r#"
1535 7..8, 1610 [
1536 ), 1611 GoToType(
1537 container_name: None, 1612 [
1538 description: Some( 1613 HoverGotoTypeData {
1539 "struct A", 1614 mod_path: "A",
1540 ), 1615 nav: NavigationTarget {
1541 docs: None, 1616 file_id: FileId(
1617 1,
1618 ),
1619 full_range: 0..14,
1620 name: "A",
1621 kind: STRUCT_DEF,
1622 focus_range: Some(
1623 7..8,
1624 ),
1625 container_name: None,
1626 description: Some(
1627 "struct A",
1628 ),
1629 docs: None,
1630 },
1542 }, 1631 },
1543 }, 1632 HoverGotoTypeData {
1544 HoverGotoTypeData { 1633 mod_path: "B",
1545 mod_path: "B", 1634 nav: NavigationTarget {
1546 nav: NavigationTarget { 1635 file_id: FileId(
1547 file_id: FileId( 1636 1,
1548 1, 1637 ),
1549 ), 1638 full_range: 15..29,
1550 full_range: 15..29, 1639 name: "B",
1551 name: "B", 1640 kind: STRUCT_DEF,
1552 kind: STRUCT_DEF, 1641 focus_range: Some(
1553 focus_range: Some( 1642 22..23,
1554 22..23, 1643 ),
1555 ), 1644 container_name: None,
1556 container_name: None, 1645 description: Some(
1557 description: Some( 1646 "struct B",
1558 "struct B", 1647 ),
1559 ), 1648 docs: None,
1560 docs: None, 1649 },
1561 }, 1650 },
1562 }, 1651 HoverGotoTypeData {
1563 HoverGotoTypeData { 1652 mod_path: "M::C",
1564 mod_path: "M::C", 1653 nav: NavigationTarget {
1565 nav: NavigationTarget { 1654 file_id: FileId(
1566 file_id: FileId( 1655 1,
1567 1, 1656 ),
1568 ), 1657 full_range: 42..60,
1569 full_range: 42..60, 1658 name: "C",
1570 name: "C", 1659 kind: STRUCT_DEF,
1571 kind: STRUCT_DEF, 1660 focus_range: Some(
1572 focus_range: Some( 1661 53..54,
1573 53..54, 1662 ),
1574 ), 1663 container_name: None,
1575 container_name: None, 1664 description: Some(
1576 description: Some( 1665 "pub struct C",
1577 "pub struct C", 1666 ),
1578 ), 1667 docs: None,
1579 docs: None, 1668 },
1580 }, 1669 },
1581 }, 1670 ],
1582 ], 1671 ),
1583 ), 1672 ]
1584 ] 1673 "#]],
1585 "###); 1674 );
1586 } 1675 }
1587 1676
1588 #[test] 1677 #[test]
1589 fn test_hover_return_impl_trait_has_goto_type_action() { 1678 fn test_hover_return_impl_trait_has_goto_type_action() {
1590 let (_, actions) = check_hover_result( 1679 check_actions(
1591 r" 1680 r#"
1592 //- /main.rs 1681trait Foo {}
1593 trait Foo {} 1682fn foo() -> impl Foo {}
1594
1595 fn foo() -> impl Foo {}
1596 1683
1597 fn main() { 1684fn main() { let s<|>t = foo(); }
1598 let s<|>t = foo(); 1685"#,
1599 } 1686 expect![[r#"
1600 ", 1687 [
1601 "impl Foo", 1688 GoToType(
1602 ); 1689 [
1603 assert_debug_snapshot!(actions, 1690 HoverGotoTypeData {
1604 @r###" 1691 mod_path: "Foo",
1605 [ 1692 nav: NavigationTarget {
1606 GoToType( 1693 file_id: FileId(
1607 [ 1694 1,
1608 HoverGotoTypeData { 1695 ),
1609 mod_path: "Foo", 1696 full_range: 0..12,
1610 nav: NavigationTarget { 1697 name: "Foo",
1611 file_id: FileId( 1698 kind: TRAIT_DEF,
1612 1, 1699 focus_range: Some(
1613 ), 1700 6..9,
1614 full_range: 0..12, 1701 ),
1615 name: "Foo", 1702 container_name: None,
1616 kind: TRAIT_DEF, 1703 description: Some(
1617 focus_range: Some( 1704 "trait Foo",
1618 6..9, 1705 ),
1619 ), 1706 docs: None,
1620 container_name: None, 1707 },
1621 description: Some(
1622 "trait Foo",
1623 ),
1624 docs: None,
1625 }, 1708 },
1626 }, 1709 ],
1627 ], 1710 ),
1628 ), 1711 ]
1629 ] 1712 "#]],
1630 "###); 1713 );
1631 } 1714 }
1632 1715
1633 #[test] 1716 #[test]
1634 fn test_hover_generic_return_impl_trait_has_goto_type_action() { 1717 fn test_hover_generic_return_impl_trait_has_goto_type_action() {
1635 let (_, actions) = check_hover_result( 1718 check_actions(
1636 r" 1719 r#"
1637 //- /main.rs 1720trait Foo<T> {}
1638 trait Foo<T> {} 1721struct S;
1639 struct S; 1722fn foo() -> impl Foo<S> {}
1640
1641 fn foo() -> impl Foo<S> {}
1642 1723
1643 fn main() { 1724fn main() { let s<|>t = foo(); }
1644 let s<|>t = foo(); 1725"#,
1645 } 1726 expect![[r#"
1646 ", 1727 [
1647 "impl Foo<S>", 1728 GoToType(
1648 ); 1729 [
1649 assert_debug_snapshot!(actions, 1730 HoverGotoTypeData {
1650 @r###" 1731 mod_path: "Foo",
1651 [ 1732 nav: NavigationTarget {
1652 GoToType( 1733 file_id: FileId(
1653 [ 1734 1,
1654 HoverGotoTypeData { 1735 ),
1655 mod_path: "Foo", 1736 full_range: 0..15,
1656 nav: NavigationTarget { 1737 name: "Foo",
1657 file_id: FileId( 1738 kind: TRAIT_DEF,
1658 1, 1739 focus_range: Some(
1659 ), 1740 6..9,
1660 full_range: 0..15, 1741 ),
1661 name: "Foo", 1742 container_name: None,
1662 kind: TRAIT_DEF, 1743 description: Some(
1663 focus_range: Some( 1744 "trait Foo",
1664 6..9, 1745 ),
1665 ), 1746 docs: None,
1666 container_name: None, 1747 },
1667 description: Some(
1668 "trait Foo",
1669 ),
1670 docs: None,
1671 }, 1748 },
1672 }, 1749 HoverGotoTypeData {
1673 HoverGotoTypeData { 1750 mod_path: "S",
1674 mod_path: "S", 1751 nav: NavigationTarget {
1675 nav: NavigationTarget { 1752 file_id: FileId(
1676 file_id: FileId( 1753 1,
1677 1, 1754 ),
1678 ), 1755 full_range: 16..25,
1679 full_range: 16..25, 1756 name: "S",
1680 name: "S", 1757 kind: STRUCT_DEF,
1681 kind: STRUCT_DEF, 1758 focus_range: Some(
1682 focus_range: Some( 1759 23..24,
1683 23..24, 1760 ),
1684 ), 1761 container_name: None,
1685 container_name: None, 1762 description: Some(
1686 description: Some( 1763 "struct S",
1687 "struct S", 1764 ),
1688 ), 1765 docs: None,
1689 docs: None, 1766 },
1690 }, 1767 },
1691 }, 1768 ],
1692 ], 1769 ),
1693 ), 1770 ]
1694 ] 1771 "#]],
1695 "###); 1772 );
1696 } 1773 }
1697 1774
1698 #[test] 1775 #[test]
1699 fn test_hover_return_impl_traits_has_goto_type_action() { 1776 fn test_hover_return_impl_traits_has_goto_type_action() {
1700 let (_, actions) = check_hover_result( 1777 check_actions(
1701 r" 1778 r#"
1702 //- /main.rs 1779trait Foo {}
1703 trait Foo {} 1780trait Bar {}
1704 trait Bar {} 1781fn foo() -> impl Foo + Bar {}
1705
1706 fn foo() -> impl Foo + Bar {}
1707 1782
1708 fn main() { 1783fn main() { let s<|>t = foo(); }
1709 let s<|>t = foo(); 1784 "#,
1710 } 1785 expect![[r#"
1711 ", 1786 [
1712 "impl Foo + Bar", 1787 GoToType(
1713 ); 1788 [
1714 assert_debug_snapshot!(actions, 1789 HoverGotoTypeData {
1715 @r###" 1790 mod_path: "Foo",
1716 [ 1791 nav: NavigationTarget {
1717 GoToType( 1792 file_id: FileId(
1718 [ 1793 1,
1719 HoverGotoTypeData { 1794 ),
1720 mod_path: "Foo", 1795 full_range: 0..12,
1721 nav: NavigationTarget { 1796 name: "Foo",
1722 file_id: FileId( 1797 kind: TRAIT_DEF,
1723 1, 1798 focus_range: Some(
1724 ), 1799 6..9,
1725 full_range: 0..12, 1800 ),
1726 name: "Foo", 1801 container_name: None,
1727 kind: TRAIT_DEF, 1802 description: Some(
1728 focus_range: Some( 1803 "trait Foo",
1729 6..9, 1804 ),
1730 ), 1805 docs: None,
1731 container_name: None, 1806 },
1732 description: Some(
1733 "trait Foo",
1734 ),
1735 docs: None,
1736 }, 1807 },
1737 }, 1808 HoverGotoTypeData {
1738 HoverGotoTypeData { 1809 mod_path: "Bar",
1739 mod_path: "Bar", 1810 nav: NavigationTarget {
1740 nav: NavigationTarget { 1811 file_id: FileId(
1741 file_id: FileId( 1812 1,
1742 1, 1813 ),
1743 ), 1814 full_range: 13..25,
1744 full_range: 13..25, 1815 name: "Bar",
1745 name: "Bar", 1816 kind: TRAIT_DEF,
1746 kind: TRAIT_DEF, 1817 focus_range: Some(
1747 focus_range: Some( 1818 19..22,
1748 19..22, 1819 ),
1749 ), 1820 container_name: None,
1750 container_name: None, 1821 description: Some(
1751 description: Some( 1822 "trait Bar",
1752 "trait Bar", 1823 ),
1753 ), 1824 docs: None,
1754 docs: None, 1825 },
1755 }, 1826 },
1756 }, 1827 ],
1757 ], 1828 ),
1758 ), 1829 ]
1759 ] 1830 "#]],
1760 "###); 1831 );
1761 } 1832 }
1762 1833
1763 #[test] 1834 #[test]
1764 fn test_hover_generic_return_impl_traits_has_goto_type_action() { 1835 fn test_hover_generic_return_impl_traits_has_goto_type_action() {
1765 let (_, actions) = check_hover_result( 1836 check_actions(
1766 r" 1837 r#"
1767 //- /main.rs 1838trait Foo<T> {}
1768 trait Foo<T> {} 1839trait Bar<T> {}
1769 trait Bar<T> {} 1840struct S1 {}
1770 struct S1 {} 1841struct S2 {}
1771 struct S2 {} 1842
1772 1843fn foo() -> impl Foo<S1> + Bar<S2> {}
1773 fn foo() -> impl Foo<S1> + Bar<S2> {} 1844
1774 1845fn main() { let s<|>t = foo(); }
1775 fn main() { 1846"#,
1776 let s<|>t = foo(); 1847 expect![[r#"
1777 } 1848 [
1778 ", 1849 GoToType(
1779 "impl Foo<S1> + Bar<S2>", 1850 [
1780 ); 1851 HoverGotoTypeData {
1781 assert_debug_snapshot!(actions, 1852 mod_path: "Foo",
1782 @r###" 1853 nav: NavigationTarget {
1783 [ 1854 file_id: FileId(
1784 GoToType( 1855 1,
1785 [ 1856 ),
1786 HoverGotoTypeData { 1857 full_range: 0..15,
1787 mod_path: "Foo", 1858 name: "Foo",
1788 nav: NavigationTarget { 1859 kind: TRAIT_DEF,
1789 file_id: FileId( 1860 focus_range: Some(
1790 1, 1861 6..9,
1791 ), 1862 ),
1792 full_range: 0..15, 1863 container_name: None,
1793 name: "Foo", 1864 description: Some(
1794 kind: TRAIT_DEF, 1865 "trait Foo",
1795 focus_range: Some( 1866 ),
1796 6..9, 1867 docs: None,
1797 ), 1868 },
1798 container_name: None,
1799 description: Some(
1800 "trait Foo",
1801 ),
1802 docs: None,
1803 }, 1869 },
1804 }, 1870 HoverGotoTypeData {
1805 HoverGotoTypeData { 1871 mod_path: "Bar",
1806 mod_path: "Bar", 1872 nav: NavigationTarget {
1807 nav: NavigationTarget { 1873 file_id: FileId(
1808 file_id: FileId( 1874 1,
1809 1, 1875 ),
1810 ), 1876 full_range: 16..31,
1811 full_range: 16..31, 1877 name: "Bar",
1812 name: "Bar", 1878 kind: TRAIT_DEF,
1813 kind: TRAIT_DEF, 1879 focus_range: Some(
1814 focus_range: Some( 1880 22..25,
1815 22..25, 1881 ),
1816 ), 1882 container_name: None,
1817 container_name: None, 1883 description: Some(
1818 description: Some( 1884 "trait Bar",
1819 "trait Bar", 1885 ),
1820 ), 1886 docs: None,
1821 docs: None, 1887 },
1822 }, 1888 },
1823 }, 1889 HoverGotoTypeData {
1824 HoverGotoTypeData { 1890 mod_path: "S1",
1825 mod_path: "S1", 1891 nav: NavigationTarget {
1826 nav: NavigationTarget { 1892 file_id: FileId(
1827 file_id: FileId( 1893 1,
1828 1, 1894 ),
1829 ), 1895 full_range: 32..44,
1830 full_range: 32..44, 1896 name: "S1",
1831 name: "S1", 1897 kind: STRUCT_DEF,
1832 kind: STRUCT_DEF, 1898 focus_range: Some(
1833 focus_range: Some( 1899 39..41,
1834 39..41, 1900 ),
1835 ), 1901 container_name: None,
1836 container_name: None, 1902 description: Some(
1837 description: Some( 1903 "struct S1",
1838 "struct S1", 1904 ),
1839 ), 1905 docs: None,
1840 docs: None, 1906 },
1841 }, 1907 },
1842 }, 1908 HoverGotoTypeData {
1843 HoverGotoTypeData { 1909 mod_path: "S2",
1844 mod_path: "S2", 1910 nav: NavigationTarget {
1845 nav: NavigationTarget { 1911 file_id: FileId(
1846 file_id: FileId( 1912 1,
1847 1, 1913 ),
1848 ), 1914 full_range: 45..57,
1849 full_range: 45..57, 1915 name: "S2",
1850 name: "S2", 1916 kind: STRUCT_DEF,
1851 kind: STRUCT_DEF, 1917 focus_range: Some(
1852 focus_range: Some( 1918 52..54,
1853 52..54, 1919 ),
1854 ), 1920 container_name: None,
1855 container_name: None, 1921 description: Some(
1856 description: Some( 1922 "struct S2",
1857 "struct S2", 1923 ),
1858 ), 1924 docs: None,
1859 docs: None, 1925 },
1860 }, 1926 },
1861 }, 1927 ],
1862 ], 1928 ),
1863 ), 1929 ]
1864 ] 1930 "#]],
1865 "###); 1931 );
1866 } 1932 }
1867 1933
1868 #[test] 1934 #[test]
1869 fn test_hover_arg_impl_trait_has_goto_type_action() { 1935 fn test_hover_arg_impl_trait_has_goto_type_action() {
1870 let (_, actions) = check_hover_result( 1936 check_actions(
1871 r" 1937 r#"
1872 //- /lib.rs 1938trait Foo {}
1873 trait Foo {} 1939fn foo(ar<|>g: &impl Foo) {}
1874 fn foo(ar<|>g: &impl Foo) {} 1940"#,
1875 ", 1941 expect![[r#"
1876 "&impl Foo", 1942 [
1877 ); 1943 GoToType(
1878 assert_debug_snapshot!(actions, 1944 [
1879 @r###" 1945 HoverGotoTypeData {
1880 [ 1946 mod_path: "Foo",
1881 GoToType( 1947 nav: NavigationTarget {
1882 [ 1948 file_id: FileId(
1883 HoverGotoTypeData { 1949 1,
1884 mod_path: "Foo", 1950 ),
1885 nav: NavigationTarget { 1951 full_range: 0..12,
1886 file_id: FileId( 1952 name: "Foo",
1887 1, 1953 kind: TRAIT_DEF,
1888 ), 1954 focus_range: Some(
1889 full_range: 0..12, 1955 6..9,
1890 name: "Foo", 1956 ),
1891 kind: TRAIT_DEF, 1957 container_name: None,
1892 focus_range: Some( 1958 description: Some(
1893 6..9, 1959 "trait Foo",
1894 ), 1960 ),
1895 container_name: None, 1961 docs: None,
1896 description: Some( 1962 },
1897 "trait Foo",
1898 ),
1899 docs: None,
1900 }, 1963 },
1901 }, 1964 ],
1902 ], 1965 ),
1903 ), 1966 ]
1904 ] 1967 "#]],
1905 "###); 1968 );
1906 } 1969 }
1907 1970
1908 #[test] 1971 #[test]
1909 fn test_hover_arg_impl_traits_has_goto_type_action() { 1972 fn test_hover_arg_impl_traits_has_goto_type_action() {
1910 let (_, actions) = check_hover_result( 1973 check_actions(
1911 r" 1974 r#"
1912 //- /lib.rs 1975trait Foo {}
1913 trait Foo {} 1976trait Bar<T> {}
1914 trait Bar<T> {} 1977struct S{}
1915 struct S{} 1978
1916 1979fn foo(ar<|>g: &impl Foo + Bar<S>) {}
1917 fn foo(ar<|>g: &impl Foo + Bar<S>) {} 1980"#,
1918 ", 1981 expect![[r#"
1919 "&impl Foo + Bar<S>", 1982 [
1920 ); 1983 GoToType(
1921 assert_debug_snapshot!(actions, 1984 [
1922 @r###" 1985 HoverGotoTypeData {
1923 [ 1986 mod_path: "Foo",
1924 GoToType( 1987 nav: NavigationTarget {
1925 [ 1988 file_id: FileId(
1926 HoverGotoTypeData { 1989 1,
1927 mod_path: "Foo", 1990 ),
1928 nav: NavigationTarget { 1991 full_range: 0..12,
1929 file_id: FileId( 1992 name: "Foo",
1930 1, 1993 kind: TRAIT_DEF,
1931 ), 1994 focus_range: Some(
1932 full_range: 0..12, 1995 6..9,
1933 name: "Foo", 1996 ),
1934 kind: TRAIT_DEF, 1997 container_name: None,
1935 focus_range: Some( 1998 description: Some(
1936 6..9, 1999 "trait Foo",
1937 ), 2000 ),
1938 container_name: None, 2001 docs: None,
1939 description: Some( 2002 },
1940 "trait Foo",
1941 ),
1942 docs: None,
1943 }, 2003 },
1944 }, 2004 HoverGotoTypeData {
1945 HoverGotoTypeData { 2005 mod_path: "Bar",
1946 mod_path: "Bar", 2006 nav: NavigationTarget {
1947 nav: NavigationTarget { 2007 file_id: FileId(
1948 file_id: FileId( 2008 1,
1949 1, 2009 ),
1950 ), 2010 full_range: 13..28,
1951 full_range: 13..28, 2011 name: "Bar",
1952 name: "Bar", 2012 kind: TRAIT_DEF,
1953 kind: TRAIT_DEF, 2013 focus_range: Some(
1954 focus_range: Some( 2014 19..22,
1955 19..22, 2015 ),
1956 ), 2016 container_name: None,
1957 container_name: None, 2017 description: Some(
1958 description: Some( 2018 "trait Bar",
1959 "trait Bar", 2019 ),
1960 ), 2020 docs: None,
1961 docs: None, 2021 },
1962 }, 2022 },
1963 }, 2023 HoverGotoTypeData {
1964 HoverGotoTypeData { 2024 mod_path: "S",
1965 mod_path: "S", 2025 nav: NavigationTarget {
1966 nav: NavigationTarget { 2026 file_id: FileId(
1967 file_id: FileId( 2027 1,
1968 1, 2028 ),
1969 ), 2029 full_range: 29..39,
1970 full_range: 29..39, 2030 name: "S",
1971 name: "S", 2031 kind: STRUCT_DEF,
1972 kind: STRUCT_DEF, 2032 focus_range: Some(
1973 focus_range: Some( 2033 36..37,
1974 36..37, 2034 ),
1975 ), 2035 container_name: None,
1976 container_name: None, 2036 description: Some(
1977 description: Some( 2037 "struct S",
1978 "struct S", 2038 ),
1979 ), 2039 docs: None,
1980 docs: None, 2040 },
1981 }, 2041 },
1982 }, 2042 ],
1983 ], 2043 ),
1984 ), 2044 ]
1985 ] 2045 "#]],
1986 "###); 2046 );
1987 } 2047 }
1988 2048
1989 #[test] 2049 #[test]
1990 fn test_hover_arg_generic_impl_trait_has_goto_type_action() { 2050 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
1991 let (_, actions) = check_hover_result( 2051 check_actions(
1992 r" 2052 r#"
1993 //- /lib.rs 2053trait Foo<T> {}
1994 trait Foo<T> {} 2054struct S {}
1995 struct S {} 2055fn foo(ar<|>g: &impl Foo<S>) {}
1996 fn foo(ar<|>g: &impl Foo<S>) {} 2056"#,
1997 ", 2057 expect![[r#"
1998 "&impl Foo<S>", 2058 [
1999 ); 2059 GoToType(
2000 assert_debug_snapshot!(actions, 2060 [
2001 @r###" 2061 HoverGotoTypeData {
2002 [ 2062 mod_path: "Foo",
2003 GoToType( 2063 nav: NavigationTarget {
2004 [ 2064 file_id: FileId(
2005 HoverGotoTypeData { 2065 1,
2006 mod_path: "Foo", 2066 ),
2007 nav: NavigationTarget { 2067 full_range: 0..15,
2008 file_id: FileId( 2068 name: "Foo",
2009 1, 2069 kind: TRAIT_DEF,
2010 ), 2070 focus_range: Some(
2011 full_range: 0..15, 2071 6..9,
2012 name: "Foo", 2072 ),
2013 kind: TRAIT_DEF, 2073 container_name: None,
2014 focus_range: Some( 2074 description: Some(
2015 6..9, 2075 "trait Foo",
2016 ), 2076 ),
2017 container_name: None, 2077 docs: None,
2018 description: Some( 2078 },
2019 "trait Foo",
2020 ),
2021 docs: None,
2022 }, 2079 },
2023 }, 2080 HoverGotoTypeData {
2024 HoverGotoTypeData { 2081 mod_path: "S",
2025 mod_path: "S", 2082 nav: NavigationTarget {
2026 nav: NavigationTarget { 2083 file_id: FileId(
2027 file_id: FileId( 2084 1,
2028 1, 2085 ),
2029 ), 2086 full_range: 16..27,
2030 full_range: 16..27, 2087 name: "S",
2031 name: "S", 2088 kind: STRUCT_DEF,
2032 kind: STRUCT_DEF, 2089 focus_range: Some(
2033 focus_range: Some( 2090 23..24,
2034 23..24, 2091 ),
2035 ), 2092 container_name: None,
2036 container_name: None, 2093 description: Some(
2037 description: Some( 2094 "struct S",
2038 "struct S", 2095 ),
2039 ), 2096 docs: None,
2040 docs: None, 2097 },
2041 }, 2098 },
2042 }, 2099 ],
2043 ], 2100 ),
2044 ), 2101 ]
2045 ] 2102 "#]],
2046 "###); 2103 );
2047 } 2104 }
2048 2105
2049 #[test] 2106 #[test]
2050 fn test_hover_dyn_return_has_goto_type_action() { 2107 fn test_hover_dyn_return_has_goto_type_action() {
2051 let (_, actions) = check_hover_result( 2108 check_actions(
2052 r" 2109 r#"
2053 //- /main.rs 2110trait Foo {}
2054 trait Foo {} 2111struct S;
2055 struct S; 2112impl Foo for S {}
2056 impl Foo for S {}
2057
2058 struct B<T>{}
2059 2113
2060 fn foo() -> B<dyn Foo> {} 2114struct B<T>{}
2115fn foo() -> B<dyn Foo> {}
2061 2116
2062 fn main() { 2117fn main() { let s<|>t = foo(); }
2063 let s<|>t = foo(); 2118"#,
2064 } 2119 expect![[r#"
2065 ",
2066 "B<dyn Foo>",
2067 );
2068 assert_debug_snapshot!(actions,
2069 @r###"
2070 [
2071 GoToType(
2072 [ 2120 [
2073 HoverGotoTypeData { 2121 GoToType(
2074 mod_path: "B", 2122 [
2075 nav: NavigationTarget { 2123 HoverGotoTypeData {
2076 file_id: FileId( 2124 mod_path: "B",
2077 1, 2125 nav: NavigationTarget {
2078 ), 2126 file_id: FileId(
2079 full_range: 42..55, 2127 1,
2080 name: "B", 2128 ),
2081 kind: STRUCT_DEF, 2129 full_range: 42..55,
2082 focus_range: Some( 2130 name: "B",
2083 49..50, 2131 kind: STRUCT_DEF,
2084 ), 2132 focus_range: Some(
2085 container_name: None, 2133 49..50,
2086 description: Some( 2134 ),
2087 "struct B", 2135 container_name: None,
2088 ), 2136 description: Some(
2089 docs: None, 2137 "struct B",
2090 }, 2138 ),
2091 }, 2139 docs: None,
2092 HoverGotoTypeData { 2140 },
2093 mod_path: "Foo", 2141 },
2094 nav: NavigationTarget { 2142 HoverGotoTypeData {
2095 file_id: FileId( 2143 mod_path: "Foo",
2096 1, 2144 nav: NavigationTarget {
2097 ), 2145 file_id: FileId(
2098 full_range: 0..12, 2146 1,
2099 name: "Foo", 2147 ),
2100 kind: TRAIT_DEF, 2148 full_range: 0..12,
2101 focus_range: Some( 2149 name: "Foo",
2102 6..9, 2150 kind: TRAIT_DEF,
2103 ), 2151 focus_range: Some(
2104 container_name: None, 2152 6..9,
2105 description: Some( 2153 ),
2106 "trait Foo", 2154 container_name: None,
2107 ), 2155 description: Some(
2108 docs: None, 2156 "trait Foo",
2109 }, 2157 ),
2110 }, 2158 docs: None,
2111 ], 2159 },
2112 ), 2160 },
2113 ] 2161 ],
2114 "###); 2162 ),
2163 ]
2164 "#]],
2165 );
2115 } 2166 }
2116 2167
2117 #[test] 2168 #[test]
2118 fn test_hover_dyn_arg_has_goto_type_action() { 2169 fn test_hover_dyn_arg_has_goto_type_action() {
2119 let (_, actions) = check_hover_result( 2170 check_actions(
2120 r" 2171 r#"
2121 //- /lib.rs 2172trait Foo {}
2122 trait Foo {} 2173fn foo(ar<|>g: &dyn Foo) {}
2123 fn foo(ar<|>g: &dyn Foo) {} 2174"#,
2124 ", 2175 expect![[r#"
2125 "&dyn Foo", 2176 [
2126 ); 2177 GoToType(
2127 assert_debug_snapshot!(actions, 2178 [
2128 @r###" 2179 HoverGotoTypeData {
2129 [ 2180 mod_path: "Foo",
2130 GoToType( 2181 nav: NavigationTarget {
2131 [ 2182 file_id: FileId(
2132 HoverGotoTypeData { 2183 1,
2133 mod_path: "Foo", 2184 ),
2134 nav: NavigationTarget { 2185 full_range: 0..12,
2135 file_id: FileId( 2186 name: "Foo",
2136 1, 2187 kind: TRAIT_DEF,
2137 ), 2188 focus_range: Some(
2138 full_range: 0..12, 2189 6..9,
2139 name: "Foo", 2190 ),
2140 kind: TRAIT_DEF, 2191 container_name: None,
2141 focus_range: Some( 2192 description: Some(
2142 6..9, 2193 "trait Foo",
2143 ), 2194 ),
2144 container_name: None, 2195 docs: None,
2145 description: Some( 2196 },
2146 "trait Foo",
2147 ),
2148 docs: None,
2149 }, 2197 },
2150 }, 2198 ],
2151 ], 2199 ),
2152 ), 2200 ]
2153 ] 2201 "#]],
2154 "###); 2202 );
2155 } 2203 }
2156 2204
2157 #[test] 2205 #[test]
2158 fn test_hover_generic_dyn_arg_has_goto_type_action() { 2206 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2159 let (_, actions) = check_hover_result( 2207 check_actions(
2160 r" 2208 r#"
2161 //- /lib.rs 2209trait Foo<T> {}
2162 trait Foo<T> {} 2210struct S {}
2163 struct S {} 2211fn foo(ar<|>g: &dyn Foo<S>) {}
2164 fn foo(ar<|>g: &dyn Foo<S>) {} 2212"#,
2165 ", 2213 expect![[r#"
2166 "&dyn Foo<S>", 2214 [
2167 ); 2215 GoToType(
2168 assert_debug_snapshot!(actions, 2216 [
2169 @r###" 2217 HoverGotoTypeData {
2170 [ 2218 mod_path: "Foo",
2171 GoToType( 2219 nav: NavigationTarget {
2172 [ 2220 file_id: FileId(
2173 HoverGotoTypeData { 2221 1,
2174 mod_path: "Foo", 2222 ),
2175 nav: NavigationTarget { 2223 full_range: 0..15,
2176 file_id: FileId( 2224 name: "Foo",
2177 1, 2225 kind: TRAIT_DEF,
2178 ), 2226 focus_range: Some(
2179 full_range: 0..15, 2227 6..9,
2180 name: "Foo", 2228 ),
2181 kind: TRAIT_DEF, 2229 container_name: None,
2182 focus_range: Some( 2230 description: Some(
2183 6..9, 2231 "trait Foo",
2184 ), 2232 ),
2185 container_name: None, 2233 docs: None,
2186 description: Some( 2234 },
2187 "trait Foo",
2188 ),
2189 docs: None,
2190 }, 2235 },
2191 }, 2236 HoverGotoTypeData {
2192 HoverGotoTypeData { 2237 mod_path: "S",
2193 mod_path: "S", 2238 nav: NavigationTarget {
2194 nav: NavigationTarget { 2239 file_id: FileId(
2195 file_id: FileId( 2240 1,
2196 1, 2241 ),
2197 ), 2242 full_range: 16..27,
2198 full_range: 16..27, 2243 name: "S",
2199 name: "S", 2244 kind: STRUCT_DEF,
2200 kind: STRUCT_DEF, 2245 focus_range: Some(
2201 focus_range: Some( 2246 23..24,
2202 23..24, 2247 ),
2203 ), 2248 container_name: None,
2204 container_name: None, 2249 description: Some(
2205 description: Some( 2250 "struct S",
2206 "struct S", 2251 ),
2207 ), 2252 docs: None,
2208 docs: None, 2253 },
2209 }, 2254 },
2210 }, 2255 ],
2211 ], 2256 ),
2212 ), 2257 ]
2213 ] 2258 "#]],
2214 "###); 2259 );
2215 } 2260 }
2216 2261
2217 #[test] 2262 #[test]
2218 fn test_hover_goto_type_action_links_order() { 2263 fn test_hover_goto_type_action_links_order() {
2219 let (_, actions) = check_hover_result( 2264 check_actions(
2220 r" 2265 r#"
2221 //- /lib.rs 2266trait ImplTrait<T> {}
2222 trait ImplTrait<T> {} 2267trait DynTrait<T> {}
2223 trait DynTrait<T> {} 2268struct B<T> {}
2224 struct B<T> {} 2269struct S {}
2225 struct S {} 2270
2226 2271fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2227 fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} 2272 "#,
2228 ", 2273 expect![[r#"
2229 "&impl ImplTrait<B<dyn DynTrait<B<S>>>>", 2274 [
2230 ); 2275 GoToType(
2231 assert_debug_snapshot!(actions, 2276 [
2232 @r###" 2277 HoverGotoTypeData {
2233 [ 2278 mod_path: "ImplTrait",
2234 GoToType( 2279 nav: NavigationTarget {
2235 [ 2280 file_id: FileId(
2236 HoverGotoTypeData { 2281 1,
2237 mod_path: "ImplTrait", 2282 ),
2238 nav: NavigationTarget { 2283 full_range: 0..21,
2239 file_id: FileId( 2284 name: "ImplTrait",
2240 1, 2285 kind: TRAIT_DEF,
2241 ), 2286 focus_range: Some(
2242 full_range: 0..21, 2287 6..15,
2243 name: "ImplTrait", 2288 ),
2244 kind: TRAIT_DEF, 2289 container_name: None,
2245 focus_range: Some( 2290 description: Some(
2246 6..15, 2291 "trait ImplTrait",
2247 ), 2292 ),
2248 container_name: None, 2293 docs: None,
2249 description: Some( 2294 },
2250 "trait ImplTrait",
2251 ),
2252 docs: None,
2253 }, 2295 },
2254 }, 2296 HoverGotoTypeData {
2255 HoverGotoTypeData { 2297 mod_path: "B",
2256 mod_path: "B", 2298 nav: NavigationTarget {
2257 nav: NavigationTarget { 2299 file_id: FileId(
2258 file_id: FileId( 2300 1,
2259 1, 2301 ),
2260 ), 2302 full_range: 43..57,
2261 full_range: 43..57, 2303 name: "B",
2262 name: "B", 2304 kind: STRUCT_DEF,
2263 kind: STRUCT_DEF, 2305 focus_range: Some(
2264 focus_range: Some( 2306 50..51,
2265 50..51, 2307 ),
2266 ), 2308 container_name: None,
2267 container_name: None, 2309 description: Some(
2268 description: Some( 2310 "struct B",
2269 "struct B", 2311 ),
2270 ), 2312 docs: None,
2271 docs: None, 2313 },
2272 }, 2314 },
2273 }, 2315 HoverGotoTypeData {
2274 HoverGotoTypeData { 2316 mod_path: "DynTrait",
2275 mod_path: "DynTrait", 2317 nav: NavigationTarget {
2276 nav: NavigationTarget { 2318 file_id: FileId(
2277 file_id: FileId( 2319 1,
2278 1, 2320 ),
2279 ), 2321 full_range: 22..42,
2280 full_range: 22..42, 2322 name: "DynTrait",
2281 name: "DynTrait", 2323 kind: TRAIT_DEF,
2282 kind: TRAIT_DEF, 2324 focus_range: Some(
2283 focus_range: Some( 2325 28..36,
2284 28..36, 2326 ),
2285 ), 2327 container_name: None,
2286 container_name: None, 2328 description: Some(
2287 description: Some( 2329 "trait DynTrait",
2288 "trait DynTrait", 2330 ),
2289 ), 2331 docs: None,
2290 docs: None, 2332 },
2291 }, 2333 },
2292 }, 2334 HoverGotoTypeData {
2293 HoverGotoTypeData { 2335 mod_path: "S",
2294 mod_path: "S", 2336 nav: NavigationTarget {
2295 nav: NavigationTarget { 2337 file_id: FileId(
2296 file_id: FileId( 2338 1,
2297 1, 2339 ),
2298 ), 2340 full_range: 58..69,
2299 full_range: 58..69, 2341 name: "S",
2300 name: "S", 2342 kind: STRUCT_DEF,
2301 kind: STRUCT_DEF, 2343 focus_range: Some(
2302 focus_range: Some( 2344 65..66,
2303 65..66, 2345 ),
2304 ), 2346 container_name: None,
2305 container_name: None, 2347 description: Some(
2306 description: Some( 2348 "struct S",
2307 "struct S", 2349 ),
2308 ), 2350 docs: None,
2309 docs: None, 2351 },
2310 }, 2352 },
2311 }, 2353 ],
2312 ], 2354 ),
2313 ), 2355 ]
2314 ] 2356 "#]],
2315 "###); 2357 );
2316 } 2358 }
2317 2359
2318 #[test] 2360 #[test]
2319 fn test_hover_associated_type_has_goto_type_action() { 2361 fn test_hover_associated_type_has_goto_type_action() {
2320 let (_, actions) = check_hover_result( 2362 check_actions(
2321 r" 2363 r#"
2322 //- /main.rs 2364trait Foo {
2323 trait Foo { 2365 type Item;
2324 type Item; 2366 fn get(self) -> Self::Item {}
2325 fn get(self) -> Self::Item {} 2367}
2326 }
2327 2368
2328 struct Bar{} 2369struct Bar{}
2329 struct S{} 2370struct S{}
2330 2371
2331 impl Foo for S{ 2372impl Foo for S { type Item = Bar; }
2332 type Item = Bar;
2333 }
2334 2373
2335 fn test() -> impl Foo { 2374fn test() -> impl Foo { S {} }
2336 S{}
2337 }
2338 2375
2339 fn main() { 2376fn main() { let s<|>t = test().get(); }
2340 let s<|>t = test().get(); 2377"#,
2341 } 2378 expect![[r#"
2342 ", 2379 [
2343 "Foo::Item<impl Foo>", 2380 GoToType(
2344 ); 2381 [
2345 assert_debug_snapshot!(actions, 2382 HoverGotoTypeData {
2346 @r###" 2383 mod_path: "Foo",
2347 [ 2384 nav: NavigationTarget {
2348 GoToType( 2385 file_id: FileId(
2349 [ 2386 1,
2350 HoverGotoTypeData { 2387 ),
2351 mod_path: "Foo", 2388 full_range: 0..62,
2352 nav: NavigationTarget { 2389 name: "Foo",
2353 file_id: FileId( 2390 kind: TRAIT_DEF,
2354 1, 2391 focus_range: Some(
2355 ), 2392 6..9,
2356 full_range: 0..62, 2393 ),
2357 name: "Foo", 2394 container_name: None,
2358 kind: TRAIT_DEF, 2395 description: Some(
2359 focus_range: Some( 2396 "trait Foo",
2360 6..9, 2397 ),
2361 ), 2398 docs: None,
2362 container_name: None, 2399 },
2363 description: Some(
2364 "trait Foo",
2365 ),
2366 docs: None,
2367 }, 2400 },
2368 }, 2401 ],
2369 ], 2402 ),
2370 ), 2403 ]
2371 ] 2404 "#]],
2372 "###); 2405 );
2373 } 2406 }
2374} 2407}