aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-25 21:30:50 +0100
committerGitHub <[email protected]>2020-04-25 21:30:50 +0100
commitfe99a29ad1226dd3f6801ea4bdb575506324be07 (patch)
tree4294c94e11a4ac689c13e2a3699d3c1aad8c94a3
parent45832b990c7f291abe578dff3c460f4a1232f024 (diff)
parent5a355ff52bc3f05e13a1c675290781da68289bc4 (diff)
Merge #4146
4146: Don't add call parens when an fn type is expected r=matklad a=jonas-schievink This is pretty useful when dealing with callback- or fn-pointer-heavy FFI code, as I have recently. Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r--crates/ra_hir/src/code_model.rs7
-rw-r--r--crates/ra_ide/src/completion/presentation.rs58
2 files changed, 64 insertions, 1 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3f645a1dd..fb788736d 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1136,6 +1136,13 @@ impl Type {
1136 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) 1136 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. }))
1137 } 1137 }
1138 1138
1139 pub fn is_fn(&self) -> bool {
1140 matches!(&self.ty.value,
1141 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) |
1142 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. })
1143 )
1144 }
1145
1139 pub fn contains_unknown(&self) -> bool { 1146 pub fn contains_unknown(&self) -> bool {
1140 return go(&self.ty.value); 1147 return go(&self.ty.value);
1141 1148
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 7633cd7fd..f5b074461 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -349,6 +349,14 @@ impl Builder {
349 if ctx.use_item_syntax.is_some() || ctx.is_call { 349 if ctx.use_item_syntax.is_some() || ctx.is_call {
350 return self; 350 return self;
351 } 351 }
352
353 // Don't add parentheses if the expected type is some function reference.
354 if let Some(ty) = ctx.expected_type_of(&ctx.token.parent()) {
355 if ty.is_fn() {
356 return self;
357 }
358 }
359
352 let cap = match ctx.config.snippet_cap { 360 let cap = match ctx.config.snippet_cap {
353 Some(it) => it, 361 Some(it) => it,
354 None => return self, 362 None => return self,
@@ -749,6 +757,54 @@ mod tests {
749 } 757 }
750 758
751 #[test] 759 #[test]
760 fn no_call_parens_if_fn_ptr_needed() {
761 assert_debug_snapshot!(
762 do_reference_completion(
763 r"
764 fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8) {}
765
766 struct ManualVtable {
767 method: fn(u8, u8, u8, u8, u8),
768 }
769
770 fn main() -> ManualVtable {
771 ManualVtable {
772 method: some<|>
773 }
774 }
775 "
776 ),
777 @r###"
778 [
779 CompletionItem {
780 label: "ManualVtable",
781 source_range: 295..299,
782 delete: 295..299,
783 insert: "ManualVtable",
784 kind: Struct,
785 },
786 CompletionItem {
787 label: "main",
788 source_range: 295..299,
789 delete: 295..299,
790 insert: "main",
791 kind: Function,
792 detail: "fn main() -> ManualVtable",
793 },
794 CompletionItem {
795 label: "somefn",
796 source_range: 295..299,
797 delete: 295..299,
798 insert: "somefn",
799 kind: Function,
800 detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)",
801 },
802 ]
803 "###
804 );
805 }
806
807 #[test]
752 fn arg_snippets_for_method_call() { 808 fn arg_snippets_for_method_call() {
753 assert_debug_snapshot!( 809 assert_debug_snapshot!(
754 do_reference_completion( 810 do_reference_completion(
@@ -1179,7 +1235,7 @@ mod tests {
1179 1235
1180 #[test] 1236 #[test]
1181 fn test_struct_field_completion_in_record_lit() { 1237 fn test_struct_field_completion_in_record_lit() {
1182 covers!(test_struct_field_completion_in_func_call); 1238 covers!(test_struct_field_completion_in_record_lit);
1183 assert_debug_snapshot!( 1239 assert_debug_snapshot!(
1184 do_reference_completion( 1240 do_reference_completion(
1185 r" 1241 r"