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/inlay_hints.rs217
1 files changed, 125 insertions, 92 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index a484dfdeb..b42aa1523 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{HirDisplay, SourceAnalyzer, SourceBinder}; 3use hir::{Adt, HirDisplay, SourceAnalyzer, SourceBinder, Type};
4use once_cell::unsync::Lazy; 4use once_cell::unsync::Lazy;
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_prof::profile; 6use ra_prof::profile;
@@ -57,12 +57,10 @@ fn get_inlay_hints(
57 get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it)); 57 get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it));
58 }, 58 },
59 ast::BindPat(it) => { 59 ast::BindPat(it) => {
60 if should_not_display_type_hint(&it) { 60 let pat = ast::Pat::from(it.clone());
61 return None;
62 }
63 let pat = ast::Pat::from(it);
64 let ty = analyzer.type_of_pat(db, &pat)?; 61 let ty = analyzer.type_of_pat(db, &pat)?;
65 if ty.is_unknown() { 62
63 if should_not_display_type_hint(db, &it, &ty) {
66 return None; 64 return None;
67 } 65 }
68 66
@@ -80,7 +78,24 @@ fn get_inlay_hints(
80 Some(()) 78 Some(())
81} 79}
82 80
83fn should_not_display_type_hint(bind_pat: &ast::BindPat) -> bool { 81fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ty: &Type) -> bool {
82 if let Some(Adt::Enum(enum_data)) = pat_ty.as_adt() {
83 let pat_text = bind_pat.syntax().to_string();
84 enum_data
85 .variants(db)
86 .into_iter()
87 .map(|variant| variant.name(db).to_string())
88 .any(|enum_name| enum_name == pat_text)
89 } else {
90 false
91 }
92}
93
94fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ty: &Type) -> bool {
95 if pat_ty.is_unknown() {
96 return true;
97 }
98
84 for node in bind_pat.syntax().ancestors() { 99 for node in bind_pat.syntax().ancestors() {
85 match_ast! { 100 match_ast! {
86 match node { 101 match node {
@@ -90,6 +105,17 @@ fn should_not_display_type_hint(bind_pat: &ast::BindPat) -> bool {
90 ast::Param(it) => { 105 ast::Param(it) => {
91 return it.ascribed_type().is_some() 106 return it.ascribed_type().is_some()
92 }, 107 },
108 ast::MatchArm(_it) => {
109 return pat_is_enum_variant(db, bind_pat, pat_ty);
110 },
111 ast::IfExpr(it) => {
112 return it.condition().and_then(|condition| condition.pat()).is_some()
113 && pat_is_enum_variant(db, bind_pat, pat_ty);
114 },
115 ast::WhileExpr(it) => {
116 return it.condition().and_then(|condition| condition.pat()).is_some()
117 && pat_is_enum_variant(db, bind_pat, pat_ty);
118 },
93 _ => (), 119 _ => (),
94 } 120 }
95 } 121 }
@@ -119,13 +145,12 @@ fn get_param_name_hints(
119 } else { 145 } else {
120 0 146 0
121 }; 147 };
122 let parameters = fn_signature.parameter_names.iter().skip(n_params_to_skip); 148 let hints = fn_signature
123 149 .parameter_names
124 let hints = parameters 150 .iter()
151 .skip(n_params_to_skip)
125 .zip(args) 152 .zip(args)
126 .filter(|(param, arg)| { 153 .filter(|(param, arg)| should_show_param_hint(&fn_signature, param, &arg))
127 should_show_param_hint(&fn_signature, param, &arg.syntax().to_string())
128 })
129 .map(|(param_name, arg)| InlayHint { 154 .map(|(param_name, arg)| InlayHint {
130 range: arg.syntax().text_range(), 155 range: arg.syntax().text_range(),
131 kind: InlayKind::ParameterHint, 156 kind: InlayKind::ParameterHint,
@@ -139,8 +164,9 @@ fn get_param_name_hints(
139fn should_show_param_hint( 164fn should_show_param_hint(
140 fn_signature: &FunctionSignature, 165 fn_signature: &FunctionSignature,
141 param_name: &str, 166 param_name: &str,
142 argument_string: &str, 167 argument: &ast::Expr,
143) -> bool { 168) -> bool {
169 let argument_string = argument.syntax().to_string();
144 if param_name.is_empty() || argument_string.ends_with(param_name) { 170 if param_name.is_empty() || argument_string.ends_with(param_name) {
145 return false; 171 return false;
146 } 172 }
@@ -440,75 +466,77 @@ struct Test {
440 b: u8, 466 b: u8,
441} 467}
442 468
469use CustomOption::*;
470
443fn main() { 471fn main() {
444 let test = CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 }); 472 let test = Some(Test { a: Some(3), b: 1 });
445 if let CustomOption::None = &test {}; 473 if let None = &test {};
446 if let test = &test {}; 474 if let test = &test {};
447 if let CustomOption::Some(test) = &test {}; 475 if let Some(test) = &test {};
448 if let CustomOption::Some(Test { a, b }) = &test {}; 476 if let Some(Test { a, b }) = &test {};
449 if let CustomOption::Some(Test { a: x, b: y }) = &test {}; 477 if let Some(Test { a: x, b: y }) = &test {};
450 if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; 478 if let Some(Test { a: Some(x), b: y }) = &test {};
451 if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; 479 if let Some(Test { a: None, b: y }) = &test {};
452 if let CustomOption::Some(Test { b: y, .. }) = &test {}; 480 if let Some(Test { b: y, .. }) = &test {};
453 481
454 if test == CustomOption::None {} 482 if test == None {}
455}"#, 483}"#,
456 ); 484 );
457 485
458 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 486 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
459 [ 487 [
460 InlayHint { 488 InlayHint {
461 range: [166; 170), 489 range: [188; 192),
462 kind: TypeHint, 490 kind: TypeHint,
463 label: "CustomOption<Test>", 491 label: "CustomOption<Test>",
464 }, 492 },
465 InlayHint { 493 InlayHint {
466 range: [287; 291), 494 range: [267; 271),
467 kind: TypeHint, 495 kind: TypeHint,
468 label: "&CustomOption<Test>", 496 label: "&CustomOption<Test>",
469 }, 497 },
470 InlayHint { 498 InlayHint {
471 range: [334; 338), 499 range: [300; 304),
472 kind: TypeHint, 500 kind: TypeHint,
473 label: "&Test", 501 label: "&Test",
474 }, 502 },
475 InlayHint { 503 InlayHint {
476 range: [389; 390), 504 range: [341; 342),
477 kind: TypeHint, 505 kind: TypeHint,
478 label: "&CustomOption<u32>", 506 label: "&CustomOption<u32>",
479 }, 507 },
480 InlayHint { 508 InlayHint {
481 range: [392; 393), 509 range: [344; 345),
482 kind: TypeHint, 510 kind: TypeHint,
483 label: "&u8", 511 label: "&u8",
484 }, 512 },
485 InlayHint { 513 InlayHint {
486 range: [449; 450), 514 range: [387; 388),
487 kind: TypeHint, 515 kind: TypeHint,
488 label: "&CustomOption<u32>", 516 label: "&CustomOption<u32>",
489 }, 517 },
490 InlayHint { 518 InlayHint {
491 range: [455; 456), 519 range: [393; 394),
492 kind: TypeHint, 520 kind: TypeHint,
493 label: "&u8", 521 label: "&u8",
494 }, 522 },
495 InlayHint { 523 InlayHint {
496 range: [531; 532), 524 range: [441; 442),
497 kind: TypeHint, 525 kind: TypeHint,
498 label: "&u32", 526 label: "&u32",
499 }, 527 },
500 InlayHint { 528 InlayHint {
501 range: [538; 539), 529 range: [448; 449),
502 kind: TypeHint, 530 kind: TypeHint,
503 label: "&u8", 531 label: "&u8",
504 }, 532 },
505 InlayHint { 533 InlayHint {
506 range: [618; 619), 534 range: [500; 501),
507 kind: TypeHint, 535 kind: TypeHint,
508 label: "&u8", 536 label: "&u8",
509 }, 537 },
510 InlayHint { 538 InlayHint {
511 range: [675; 676), 539 range: [543; 544),
512 kind: TypeHint, 540 kind: TypeHint,
513 label: "&u8", 541 label: "&u8",
514 }, 542 },
@@ -533,75 +561,77 @@ struct Test {
533 b: u8, 561 b: u8,
534} 562}
535 563
564use CustomOption::*;
565
536fn main() { 566fn main() {
537 let test = CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 }); 567 let test = Some(Test { a: Some(3), b: 1 });
538 while let CustomOption::None = &test {}; 568 while let None = &test {};
539 while let test = &test {}; 569 while let test = &test {};
540 while let CustomOption::Some(test) = &test {}; 570 while let Some(test) = &test {};
541 while let CustomOption::Some(Test { a, b }) = &test {}; 571 while let Some(Test { a, b }) = &test {};
542 while let CustomOption::Some(Test { a: x, b: y }) = &test {}; 572 while let Some(Test { a: x, b: y }) = &test {};
543 while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; 573 while let Some(Test { a: Some(x), b: y }) = &test {};
544 while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; 574 while let Some(Test { a: None, b: y }) = &test {};
545 while let CustomOption::Some(Test { b: y, .. }) = &test {}; 575 while let Some(Test { b: y, .. }) = &test {};
546 576
547 while test == CustomOption::None {} 577 while test == None {}
548}"#, 578}"#,
549 ); 579 );
550 580
551 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 581 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
552 [ 582 [
553 InlayHint { 583 InlayHint {
554 range: [166; 170), 584 range: [188; 192),
555 kind: TypeHint, 585 kind: TypeHint,
556 label: "CustomOption<Test>", 586 label: "CustomOption<Test>",
557 }, 587 },
558 InlayHint { 588 InlayHint {
559 range: [293; 297), 589 range: [273; 277),
560 kind: TypeHint, 590 kind: TypeHint,
561 label: "&CustomOption<Test>", 591 label: "&CustomOption<Test>",
562 }, 592 },
563 InlayHint { 593 InlayHint {
564 range: [343; 347), 594 range: [309; 313),
565 kind: TypeHint, 595 kind: TypeHint,
566 label: "&Test", 596 label: "&Test",
567 }, 597 },
568 InlayHint { 598 InlayHint {
569 range: [401; 402), 599 range: [353; 354),
570 kind: TypeHint, 600 kind: TypeHint,
571 label: "&CustomOption<u32>", 601 label: "&CustomOption<u32>",
572 }, 602 },
573 InlayHint { 603 InlayHint {
574 range: [404; 405), 604 range: [356; 357),
575 kind: TypeHint, 605 kind: TypeHint,
576 label: "&u8", 606 label: "&u8",
577 }, 607 },
578 InlayHint { 608 InlayHint {
579 range: [464; 465), 609 range: [402; 403),
580 kind: TypeHint, 610 kind: TypeHint,
581 label: "&CustomOption<u32>", 611 label: "&CustomOption<u32>",
582 }, 612 },
583 InlayHint { 613 InlayHint {
584 range: [470; 471), 614 range: [408; 409),
585 kind: TypeHint, 615 kind: TypeHint,
586 label: "&u8", 616 label: "&u8",
587 }, 617 },
588 InlayHint { 618 InlayHint {
589 range: [549; 550), 619 range: [459; 460),
590 kind: TypeHint, 620 kind: TypeHint,
591 label: "&u32", 621 label: "&u32",
592 }, 622 },
593 InlayHint { 623 InlayHint {
594 range: [556; 557), 624 range: [466; 467),
595 kind: TypeHint, 625 kind: TypeHint,
596 label: "&u8", 626 label: "&u8",
597 }, 627 },
598 InlayHint { 628 InlayHint {
599 range: [639; 640), 629 range: [521; 522),
600 kind: TypeHint, 630 kind: TypeHint,
601 label: "&u8", 631 label: "&u8",
602 }, 632 },
603 InlayHint { 633 InlayHint {
604 range: [699; 700), 634 range: [567; 568),
605 kind: TypeHint, 635 kind: TypeHint,
606 label: "&u8", 636 label: "&u8",
607 }, 637 },
@@ -626,16 +656,18 @@ struct Test {
626 b: u8, 656 b: u8,
627} 657}
628 658
659use CustomOption::*;
660
629fn main() { 661fn main() {
630 match CustomOption::Some(Test { a: CustomOption::Some(3), b: 1 }) { 662 match Some(Test { a: Some(3), b: 1 }) {
631 CustomOption::None => (), 663 None => (),
632 test => (), 664 test => (),
633 CustomOption::Some(test) => (), 665 Some(test) => (),
634 CustomOption::Some(Test { a, b }) => (), 666 Some(Test { a, b }) => (),
635 CustomOption::Some(Test { a: x, b: y }) => (), 667 Some(Test { a: x, b: y }) => (),
636 CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) => (), 668 Some(Test { a: Some(x), b: y }) => (),
637 CustomOption::Some(Test { a: CustomOption::None, b: y }) => (), 669 Some(Test { a: None, b: y }) => (),
638 CustomOption::Some(Test { b: y, .. }) => (), 670 Some(Test { b: y, .. }) => (),
639 _ => {} 671 _ => {}
640 } 672 }
641}"#, 673}"#,
@@ -644,52 +676,52 @@ fn main() {
644 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 676 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
645 [ 677 [
646 InlayHint { 678 InlayHint {
647 range: [272; 276), 679 range: [252; 256),
648 kind: TypeHint, 680 kind: TypeHint,
649 label: "CustomOption<Test>", 681 label: "CustomOption<Test>",
650 }, 682 },
651 InlayHint { 683 InlayHint {
652 range: [311; 315), 684 range: [277; 281),
653 kind: TypeHint, 685 kind: TypeHint,
654 label: "Test", 686 label: "Test",
655 }, 687 },
656 InlayHint { 688 InlayHint {
657 range: [358; 359), 689 range: [310; 311),
658 kind: TypeHint, 690 kind: TypeHint,
659 label: "CustomOption<u32>", 691 label: "CustomOption<u32>",
660 }, 692 },
661 InlayHint { 693 InlayHint {
662 range: [361; 362), 694 range: [313; 314),
663 kind: TypeHint, 695 kind: TypeHint,
664 label: "u8", 696 label: "u8",
665 }, 697 },
666 InlayHint { 698 InlayHint {
667 range: [410; 411), 699 range: [348; 349),
668 kind: TypeHint, 700 kind: TypeHint,
669 label: "CustomOption<u32>", 701 label: "CustomOption<u32>",
670 }, 702 },
671 InlayHint { 703 InlayHint {
672 range: [416; 417), 704 range: [354; 355),
673 kind: TypeHint, 705 kind: TypeHint,
674 label: "u8", 706 label: "u8",
675 }, 707 },
676 InlayHint { 708 InlayHint {
677 range: [484; 485), 709 range: [394; 395),
678 kind: TypeHint, 710 kind: TypeHint,
679 label: "u32", 711 label: "u32",
680 }, 712 },
681 InlayHint { 713 InlayHint {
682 range: [491; 492), 714 range: [401; 402),
683 kind: TypeHint, 715 kind: TypeHint,
684 label: "u8", 716 label: "u8",
685 }, 717 },
686 InlayHint { 718 InlayHint {
687 range: [563; 564), 719 range: [445; 446),
688 kind: TypeHint, 720 kind: TypeHint,
689 label: "u8", 721 label: "u8",
690 }, 722 },
691 InlayHint { 723 InlayHint {
692 range: [612; 613), 724 range: [480; 481),
693 kind: TypeHint, 725 kind: TypeHint,
694 label: "u8", 726 label: "u8",
695 }, 727 },
@@ -743,6 +775,7 @@ enum CustomOption<T> {
743 None, 775 None,
744 Some(T), 776 Some(T),
745} 777}
778use CustomOption::*;
746 779
747struct FileId {} 780struct FileId {}
748struct SmolStr {} 781struct SmolStr {}
@@ -791,11 +824,11 @@ fn main() {
791 Test::from_syntax( 824 Test::from_syntax(
792 FileId {}, 825 FileId {},
793 "impl".into(), 826 "impl".into(),
794 CustomOption::None, 827 None,
795 TextRange {}, 828 TextRange {},
796 SyntaxKind {}, 829 SyntaxKind {},
797 CustomOption::None, 830 None,
798 CustomOption::None, 831 None,
799 ); 832 );
800}"#, 833}"#,
801 ); 834 );
@@ -803,77 +836,77 @@ fn main() {
803 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 836 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
804 [ 837 [
805 InlayHint { 838 InlayHint {
806 range: [777; 788), 839 range: [798; 809),
807 kind: TypeHint, 840 kind: TypeHint,
808 label: "i32", 841 label: "i32",
809 }, 842 },
810 InlayHint { 843 InlayHint {
811 range: [821; 822), 844 range: [842; 843),
812 kind: ParameterHint, 845 kind: ParameterHint,
813 label: "foo", 846 label: "foo",
814 }, 847 },
815 InlayHint { 848 InlayHint {
816 range: [824; 825), 849 range: [845; 846),
817 kind: ParameterHint, 850 kind: ParameterHint,
818 label: "bar", 851 label: "bar",
819 }, 852 },
820 InlayHint { 853 InlayHint {
821 range: [827; 834), 854 range: [848; 855),
822 kind: ParameterHint, 855 kind: ParameterHint,
823 label: "msg", 856 label: "msg",
824 }, 857 },
825 InlayHint { 858 InlayHint {
826 range: [839; 850), 859 range: [860; 871),
827 kind: ParameterHint, 860 kind: ParameterHint,
828 label: "last", 861 label: "last",
829 }, 862 },
830 InlayHint { 863 InlayHint {
831 range: [893; 896), 864 range: [914; 917),
832 kind: ParameterHint, 865 kind: ParameterHint,
833 label: "param", 866 label: "param",
834 }, 867 },
835 InlayHint { 868 InlayHint {
836 range: [916; 918), 869 range: [937; 939),
837 kind: ParameterHint, 870 kind: ParameterHint,
838 label: "&self", 871 label: "&self",
839 }, 872 },
840 InlayHint { 873 InlayHint {
841 range: [920; 924), 874 range: [941; 945),
842 kind: ParameterHint, 875 kind: ParameterHint,
843 label: "param", 876 label: "param",
844 }, 877 },
845 InlayHint { 878 InlayHint {
846 range: [959; 968), 879 range: [980; 989),
847 kind: ParameterHint, 880 kind: ParameterHint,
848 label: "file_id", 881 label: "file_id",
849 }, 882 },
850 InlayHint { 883 InlayHint {
851 range: [978; 991), 884 range: [999; 1012),
852 kind: ParameterHint, 885 kind: ParameterHint,
853 label: "name", 886 label: "name",
854 }, 887 },
855 InlayHint { 888 InlayHint {
856 range: [1001; 1019), 889 range: [1022; 1026),
857 kind: ParameterHint, 890 kind: ParameterHint,
858 label: "focus_range", 891 label: "focus_range",
859 }, 892 },
860 InlayHint { 893 InlayHint {
861 range: [1029; 1041), 894 range: [1036; 1048),
862 kind: ParameterHint, 895 kind: ParameterHint,
863 label: "full_range", 896 label: "full_range",
864 }, 897 },
865 InlayHint { 898 InlayHint {
866 range: [1051; 1064), 899 range: [1058; 1071),
867 kind: ParameterHint, 900 kind: ParameterHint,
868 label: "kind", 901 label: "kind",
869 }, 902 },
870 InlayHint { 903 InlayHint {
871 range: [1074; 1092), 904 range: [1081; 1085),
872 kind: ParameterHint, 905 kind: ParameterHint,
873 label: "docs", 906 label: "docs",
874 }, 907 },
875 InlayHint { 908 InlayHint {
876 range: [1102; 1120), 909 range: [1095; 1099),
877 kind: ParameterHint, 910 kind: ParameterHint,
878 label: "description", 911 label: "description",
879 }, 912 },