diff options
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r-- | crates/ide_completion/src/context.rs | 65 | ||||
-rw-r--r-- | crates/ide_completion/src/render.rs | 75 |
2 files changed, 72 insertions, 68 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 4814bd64d..f0da98739 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -388,14 +388,19 @@ impl<'a> CompletionContext<'a> { | |||
388 | (ty, name) | 388 | (ty, name) |
389 | }, | 389 | }, |
390 | ast::ArgList(_it) => { | 390 | ast::ArgList(_it) => { |
391 | cov_mark::hit!(expected_type_fn_param_with_leading_char); | 391 | cov_mark::hit!(expected_type_fn_param); |
392 | cov_mark::hit!(expected_type_fn_param_without_leading_char); | ||
393 | ActiveParameter::at_token( | 392 | ActiveParameter::at_token( |
394 | &self.sema, | 393 | &self.sema, |
395 | self.token.clone(), | 394 | self.token.clone(), |
396 | ).map(|ap| { | 395 | ).map(|ap| { |
397 | let name = ap.ident().map(NameOrNameRef::Name); | 396 | let name = ap.ident().map(NameOrNameRef::Name); |
398 | (Some(ap.ty), name) | 397 | let ty = if has_ref(&self.token) { |
398 | cov_mark::hit!(expected_type_fn_param_ref); | ||
399 | ap.ty.remove_ref() | ||
400 | } else { | ||
401 | Some(ap.ty) | ||
402 | }; | ||
403 | (ty, name) | ||
399 | }) | 404 | }) |
400 | .unwrap_or((None, None)) | 405 | .unwrap_or((None, None)) |
401 | }, | 406 | }, |
@@ -700,6 +705,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> { | |||
700 | use_tree.path().zip(Some(true)) | 705 | use_tree.path().zip(Some(true)) |
701 | } | 706 | } |
702 | 707 | ||
708 | fn has_ref(token: &SyntaxToken) -> bool { | ||
709 | let mut token = token.clone(); | ||
710 | for skip in [WHITESPACE, IDENT, T![mut]] { | ||
711 | if token.kind() == skip { | ||
712 | token = match token.prev_token() { | ||
713 | Some(it) => it, | ||
714 | None => return false, | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | token.kind() == T![&] | ||
719 | } | ||
720 | |||
703 | #[cfg(test)] | 721 | #[cfg(test)] |
704 | mod tests { | 722 | mod tests { |
705 | use expect_test::{expect, Expect}; | 723 | use expect_test::{expect, Expect}; |
@@ -772,14 +790,18 @@ fn foo() { | |||
772 | } | 790 | } |
773 | 791 | ||
774 | #[test] | 792 | #[test] |
775 | fn expected_type_fn_param_without_leading_char() { | 793 | fn expected_type_fn_param() { |
776 | cov_mark::check!(expected_type_fn_param_without_leading_char); | 794 | cov_mark::check!(expected_type_fn_param); |
777 | check_expected_type_and_name( | 795 | check_expected_type_and_name( |
778 | r#" | 796 | r#" |
779 | fn foo() { | 797 | fn foo() { bar($0); } |
780 | bar($0); | 798 | fn bar(x: u32) {} |
781 | } | 799 | "#, |
782 | 800 | expect![[r#"ty: u32, name: x"#]], | |
801 | ); | ||
802 | check_expected_type_and_name( | ||
803 | r#" | ||
804 | fn foo() { bar(c$0); } | ||
783 | fn bar(x: u32) {} | 805 | fn bar(x: u32) {} |
784 | "#, | 806 | "#, |
785 | expect![[r#"ty: u32, name: x"#]], | 807 | expect![[r#"ty: u32, name: x"#]], |
@@ -787,18 +809,29 @@ fn bar(x: u32) {} | |||
787 | } | 809 | } |
788 | 810 | ||
789 | #[test] | 811 | #[test] |
790 | fn expected_type_fn_param_with_leading_char() { | 812 | fn expected_type_fn_param_ref() { |
791 | cov_mark::check!(expected_type_fn_param_with_leading_char); | 813 | cov_mark::check!(expected_type_fn_param_ref); |
792 | check_expected_type_and_name( | 814 | check_expected_type_and_name( |
793 | r#" | 815 | r#" |
794 | fn foo() { | 816 | fn foo() { bar(&$0); } |
795 | bar(c$0); | 817 | fn bar(x: &u32) {} |
796 | } | ||
797 | |||
798 | fn bar(x: u32) {} | ||
799 | "#, | 818 | "#, |
800 | expect![[r#"ty: u32, name: x"#]], | 819 | expect![[r#"ty: u32, name: x"#]], |
801 | ); | 820 | ); |
821 | check_expected_type_and_name( | ||
822 | r#" | ||
823 | fn foo() { bar(&mut $0); } | ||
824 | fn bar(x: &mut u32) {} | ||
825 | "#, | ||
826 | expect![[r#"ty: u32, name: x"#]], | ||
827 | ); | ||
828 | check_expected_type_and_name( | ||
829 | r#" | ||
830 | fn foo() { bar(&c$0); } | ||
831 | fn bar(x: &u32) {} | ||
832 | "#, | ||
833 | expect![[r#"ty: u32, name: x"#]], | ||
834 | ); | ||
802 | } | 835 | } |
803 | 836 | ||
804 | #[test] | 837 | #[test] |
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 9bec03e17..1a9b6212a 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs | |||
@@ -1057,7 +1057,7 @@ fn f() { | |||
1057 | #[test] | 1057 | #[test] |
1058 | fn suggest_ref_mut() { | 1058 | fn suggest_ref_mut() { |
1059 | cov_mark::check!(suggest_ref); | 1059 | cov_mark::check!(suggest_ref); |
1060 | check( | 1060 | check_relevance( |
1061 | r#" | 1061 | r#" |
1062 | struct S; | 1062 | struct S; |
1063 | fn foo(s: &mut S) {} | 1063 | fn foo(s: &mut S) {} |
@@ -1067,58 +1067,29 @@ fn main() { | |||
1067 | } | 1067 | } |
1068 | "#, | 1068 | "#, |
1069 | expect![[r#" | 1069 | expect![[r#" |
1070 | [ | 1070 | lc s [name+local] |
1071 | CompletionItem { | 1071 | lc &mut s [type+name+local] |
1072 | label: "S", | 1072 | st S [] |
1073 | source_range: 70..70, | 1073 | fn main() [] |
1074 | delete: 70..70, | 1074 | fn foo(…) [] |
1075 | insert: "S", | ||
1076 | kind: SymbolKind( | ||
1077 | Struct, | ||
1078 | ), | ||
1079 | }, | ||
1080 | CompletionItem { | ||
1081 | label: "foo(…)", | ||
1082 | source_range: 70..70, | ||
1083 | delete: 70..70, | ||
1084 | insert: "foo(${1:&mut s})$0", | ||
1085 | kind: SymbolKind( | ||
1086 | Function, | ||
1087 | ), | ||
1088 | lookup: "foo", | ||
1089 | detail: "fn(&mut S)", | ||
1090 | trigger_call_info: true, | ||
1091 | }, | ||
1092 | CompletionItem { | ||
1093 | label: "main()", | ||
1094 | source_range: 70..70, | ||
1095 | delete: 70..70, | ||
1096 | insert: "main()$0", | ||
1097 | kind: SymbolKind( | ||
1098 | Function, | ||
1099 | ), | ||
1100 | lookup: "main", | ||
1101 | detail: "fn()", | ||
1102 | }, | ||
1103 | CompletionItem { | ||
1104 | label: "s", | ||
1105 | source_range: 70..70, | ||
1106 | delete: 70..70, | ||
1107 | insert: "s", | ||
1108 | kind: SymbolKind( | ||
1109 | Local, | ||
1110 | ), | ||
1111 | detail: "S", | ||
1112 | relevance: CompletionRelevance { | ||
1113 | exact_name_match: true, | ||
1114 | type_match: None, | ||
1115 | is_local: true, | ||
1116 | }, | ||
1117 | ref_match: "&mut ", | ||
1118 | }, | ||
1119 | ] | ||
1120 | "#]], | 1075 | "#]], |
1121 | ) | 1076 | ); |
1077 | check_relevance( | ||
1078 | r#" | ||
1079 | struct S; | ||
1080 | fn foo(s: &mut S) {} | ||
1081 | fn main() { | ||
1082 | let mut s = S; | ||
1083 | foo(&mut $0); | ||
1084 | } | ||
1085 | "#, | ||
1086 | expect![[r#" | ||
1087 | lc s [type+name+local] | ||
1088 | st S [] | ||
1089 | fn main() [] | ||
1090 | fn foo(…) [] | ||
1091 | "#]], | ||
1092 | ); | ||
1122 | } | 1093 | } |
1123 | 1094 | ||
1124 | #[test] | 1095 | #[test] |