diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/hover.rs | 3197 |
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 | }; |
13 | use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; | 13 | use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; |
14 | 14 | ||
15 | use crate::{ | 15 | use 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)] |
371 | mod tests { | 371 | mod 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#" |
411 | pub fn foo() -> u32 { 1 } | 405 | pub 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> { | 424 | struct Scan<A, B, C> { a: A, b: B, c: C } |
428 | a: A, | 425 | struct Iter<I> { inner: I } |
429 | b: B, | 426 | enum Option<T> { Some(T), None } |
430 | c: C, | ||
431 | } | ||
432 | |||
433 | struct FakeIter<I> { | ||
434 | inner: I, | ||
435 | } | ||
436 | 427 | ||
437 | struct OtherStruct<T> { | 428 | struct OtherStruct<T> { i: T } |
438 | i: T, | ||
439 | } | ||
440 | 429 | ||
441 | enum FakeOption<T> { | 430 | fn 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() { | 434 | fn 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 | 457 | pub fn foo() -> u32 { 1 } |
467 | pub fn foo() -> u32 { 1 } | ||
468 | 458 | ||
469 | fn main() { | 459 | fn 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 } | 473 | pub fn foo() -> u32 { 1 } |
481 | 474 | ||
482 | //- /b.rs | 475 | //- /b.rs |
483 | pub fn foo() -> &str { "" } | 476 | pub fn foo() -> &str { "" } |
484 | 477 | ||
485 | //- /c.rs | 478 | //- /c.rs |
486 | pub fn foo(a: u32, b: u32) {} | 479 | pub fn foo(a: u32, b: u32) {} |
487 | 480 | ||
488 | //- /main.rs | 481 | //- /main.rs |
489 | mod a; | 482 | mod a; |
490 | mod b; | 483 | mod b; |
491 | mod c; | 484 | mod c; |
492 | 485 | ||
493 | fn main() { | 486 | fn 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 | 501 | pub 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() { | 503 | fn 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 | 518 | pub fn foo<|>(a: u32, b: u32) -> u32 {} |
521 | pub fn foo<|>(a: u32, b: u32) -> u32 {} | ||
522 | 519 | ||
523 | fn main() { | 520 | fn 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 | 536 | struct Foo { field_a: u32 } |
536 | struct Foo { | ||
537 | field_a: u32, | ||
538 | } | ||
539 | 537 | ||
540 | fn main() { | 538 | fn 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 | 557 | struct Foo { field_a<|>: u32 } |
553 | struct Foo { | ||
554 | field_a<|>: u32, | ||
555 | } | ||
556 | 558 | ||
557 | fn main() { | 559 | fn 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 | 602 | struct Test<K, T = u8> { k: K, t: T } |
591 | struct Test<K, T = u8> { | ||
592 | k: K, | ||
593 | t: T, | ||
594 | } | ||
595 | 603 | ||
596 | fn main() { | 604 | fn 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) } | 620 | enum Option<T> { Some(T) } |
608 | use Option::Some; | 621 | use Option::Some; |
609 | 622 | ||
610 | fn main() { | 623 | fn 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) } | 639 | enum Option<T> { Some(T) } |
621 | use Option::Some; | 640 | use Option::Some; |
622 | 641 | ||
623 | fn main() { | 642 | fn 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 | 657 | enum 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: |
643 | Option | 664 | ```rust |
644 | ``` | 665 | Option |
645 | 666 | ``` | |
646 | ```rust | 667 | |
647 | None | 668 | ```rust |
648 | ``` | 669 | None |
649 | ___ | 670 | ``` |
650 | 671 | ___ | |
651 | The 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 | 679 | enum Option<T> { |
659 | enum Option<T> { | 680 | /// The Some variant |
660 | /// The Some variant | 681 | Some(T) |
661 | Some(T) | 682 | } |
662 | } | 683 | fn 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: |
668 | Option | 689 | ```rust |
669 | ``` | 690 | Option |
670 | 691 | ``` | |
671 | ```rust | 692 | |
672 | Some | 693 | ```rust |
673 | ``` | 694 | Some |
674 | ___ | 695 | ``` |
675 | 696 | ___ | |
676 | The 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; }; }"#, |
700 | fn 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 } | 759 | struct Thing { x: u32 } |
719 | 760 | ||
720 | impl Thing { | 761 | impl Thing { |
721 | fn new() -> Thing { | 762 | fn new() -> Thing { Thing { x: 0 } } |
722 | Thing { x: 0 } | 763 | } |
723 | } | ||
724 | } | ||
725 | 764 | ||
726 | fn main() { | 765 | fn 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 { | 780 | mod 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() { | 788 | fn 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; | 807 | struct X; |
766 | impl X { | 808 | impl X { |
767 | const C: u32 = 1; | 809 | const C: u32 = 1; |
768 | } | 810 | } |
769 | 811 | ||
770 | fn main() { | 812 | fn 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 } | 833 | struct Thing { x: u32 } |
788 | impl Thing { | 834 | impl 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() {} | 890 | fn x() {} |
845 | 891 | ||
846 | fn y() { | 892 | fn 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 { | 910 | macro_rules! foo { () => {} } |
861 | () => {} | ||
862 | } | ||
863 | 911 | ||
864 | fn f() { | 912 | fn 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 | 938 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } |
889 | macro_rules! id { | 939 | fn foo() {} |
890 | ($($tt:tt)*) => { $($tt)* } | 940 | id! { |
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 | 957 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } |
910 | macro_rules! id { | 958 | fn 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 | 973 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } |
928 | macro_rules! id_deep { | 974 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } |
929 | ($($tt:tt)*) => { $($tt)* } | 975 | fn 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 | 990 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } |
949 | macro_rules! id_deep { | 991 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } |
950 | ($($tt:tt)*) => { $($tt)* } | 992 | fn bar() -> u32 { 0 } |
951 | } | 993 | fn 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 | 1008 | macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } } |
973 | macro_rules! arr { | 1009 | fn 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] | 1028 | macro_rules! assert {} |
993 | macro_rules! assert {} | ||
994 | 1029 | ||
995 | fn bar() -> bool { true } | 1030 | fn bar() -> bool { true } |
996 | fn foo() { | 1031 | fn 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 | 1063 | fn foo() { } |
1027 | fn foo() { | ||
1028 | } | ||
1029 | 1064 | ||
1030 | fn bar() { | 1065 | fn 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 | 1133 | use self::m<|>y::Bar; |
1080 | use self::m<|>y::Bar; | 1134 | mod my { pub struct Bar; } |
1081 | |||
1082 | mod my { | ||
1083 | pub struct Bar; | ||
1084 | } | ||
1085 | 1135 | ||
1086 | fn my() {} | 1136 | fn 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 | 1152 | struct Bar; |
1098 | struct Bar; | ||
1099 | 1153 | ||
1100 | fn foo() { | 1154 | fn 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"] | 1173 | struct Bar; |
1114 | struct Bar; | ||
1115 | 1174 | ||
1116 | fn foo() { | 1175 | fn 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"] | 1196 | struct Bar; |
1132 | struct Bar; | ||
1133 | 1197 | ||
1134 | fn foo() { | 1198 | fn 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 | 1222 | macro_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!(); | 1232 | bar!(); |
1160 | 1233 | ||
1161 | fn foo() { | 1234 | fn 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 | 1258 | macro_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!(); | 1268 | bar!(); |
1188 | 1269 | ||
1189 | fn foo() { | 1270 | fn 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 } | 1369 | fn 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 | 1409 | mod 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 | 1447 | struct S{ f1: u32 } |
1445 | struct Arg(u32); | 1448 | |
1446 | struct S<T>{ f1: T } | 1449 | fn 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", | 1485 | struct Arg(u32); |
1461 | nav: NavigationTarget { | 1486 | struct S<T>{ f1: T } |
1462 | file_id: FileId( | 1487 | |
1463 | 1, | 1488 | fn 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 | 1543 | struct Arg(u32); |
1508 | struct A(u32); | 1544 | struct S<T>{ f1: T } |
1509 | struct B(u32); | ||
1510 | mod M { | ||
1511 | pub struct C(u32); | ||
1512 | } | ||
1513 | 1545 | ||
1514 | fn main() { | 1546 | fn 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", | 1601 | struct A(u32); |
1527 | nav: NavigationTarget { | 1602 | struct B(u32); |
1528 | file_id: FileId( | 1603 | mod M { |
1529 | 1, | 1604 | pub struct C(u32); |
1530 | ), | 1605 | } |
1531 | full_range: 0..14, | 1606 | |
1532 | name: "A", | 1607 | fn 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 | 1681 | trait Foo {} |
1593 | trait Foo {} | 1682 | fn foo() -> impl Foo {} |
1594 | |||
1595 | fn foo() -> impl Foo {} | ||
1596 | 1683 | ||
1597 | fn main() { | 1684 | fn 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 | 1720 | trait Foo<T> {} |
1638 | trait Foo<T> {} | 1721 | struct S; |
1639 | struct S; | 1722 | fn foo() -> impl Foo<S> {} |
1640 | |||
1641 | fn foo() -> impl Foo<S> {} | ||
1642 | 1723 | ||
1643 | fn main() { | 1724 | fn 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 | 1779 | trait Foo {} |
1703 | trait Foo {} | 1780 | trait Bar {} |
1704 | trait Bar {} | 1781 | fn foo() -> impl Foo + Bar {} |
1705 | |||
1706 | fn foo() -> impl Foo + Bar {} | ||
1707 | 1782 | ||
1708 | fn main() { | 1783 | fn 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 | 1838 | trait Foo<T> {} |
1768 | trait Foo<T> {} | 1839 | trait Bar<T> {} |
1769 | trait Bar<T> {} | 1840 | struct S1 {} |
1770 | struct S1 {} | 1841 | struct S2 {} |
1771 | struct S2 {} | 1842 | |
1772 | 1843 | fn foo() -> impl Foo<S1> + Bar<S2> {} | |
1773 | fn foo() -> impl Foo<S1> + Bar<S2> {} | 1844 | |
1774 | 1845 | fn 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 | 1938 | trait Foo {} |
1873 | trait Foo {} | 1939 | fn 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 | 1975 | trait Foo {} |
1913 | trait Foo {} | 1976 | trait Bar<T> {} |
1914 | trait Bar<T> {} | 1977 | struct S{} |
1915 | struct S{} | 1978 | |
1916 | 1979 | fn 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 | 2053 | trait Foo<T> {} |
1994 | trait Foo<T> {} | 2054 | struct S {} |
1995 | struct S {} | 2055 | fn 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 | 2110 | trait Foo {} |
2054 | trait Foo {} | 2111 | struct S; |
2055 | struct S; | 2112 | impl Foo for S {} |
2056 | impl Foo for S {} | ||
2057 | |||
2058 | struct B<T>{} | ||
2059 | 2113 | ||
2060 | fn foo() -> B<dyn Foo> {} | 2114 | struct B<T>{} |
2115 | fn foo() -> B<dyn Foo> {} | ||
2061 | 2116 | ||
2062 | fn main() { | 2117 | fn 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 | 2172 | trait Foo {} |
2122 | trait Foo {} | 2173 | fn 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 | 2209 | trait Foo<T> {} |
2162 | trait Foo<T> {} | 2210 | struct S {} |
2163 | struct S {} | 2211 | fn 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 | 2266 | trait ImplTrait<T> {} |
2222 | trait ImplTrait<T> {} | 2267 | trait DynTrait<T> {} |
2223 | trait DynTrait<T> {} | 2268 | struct B<T> {} |
2224 | struct B<T> {} | 2269 | struct S {} |
2225 | struct S {} | 2270 | |
2226 | 2271 | fn 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 | 2364 | trait 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{} | 2369 | struct Bar{} |
2329 | struct S{} | 2370 | struct S{} |
2330 | 2371 | ||
2331 | impl Foo for S{ | 2372 | impl Foo for S { type Item = Bar; } |
2332 | type Item = Bar; | ||
2333 | } | ||
2334 | 2373 | ||
2335 | fn test() -> impl Foo { | 2374 | fn test() -> impl Foo { S {} } |
2336 | S{} | ||
2337 | } | ||
2338 | 2375 | ||
2339 | fn main() { | 2376 | fn 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 | } |