From 76d6f54471b5026ff228a58f10c69256a4b931bc Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Apr 2020 21:34:38 +0200 Subject: Don't add call parens when an fn type is expected --- crates/ra_hir/src/code_model.rs | 7 ++++ crates/ra_ide/src/completion/presentation.rs | 56 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) 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 { matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) } + pub fn is_fn(&self) -> bool { + matches!(&self.ty.value, + Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) | + Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) + ) + } + pub fn contains_unknown(&self) -> bool { return go(&self.ty.value); diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 7633cd7fd..1c516d312 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -349,6 +349,14 @@ impl Builder { if ctx.use_item_syntax.is_some() || ctx.is_call { return self; } + + // Don't add parentheses if the expected type is some function reference. + if let Some(ty) = ctx.expected_type_of(&ctx.token.parent()) { + if ty.is_fn() { + return self; + } + } + let cap = match ctx.config.snippet_cap { Some(it) => it, None => return self, @@ -748,6 +756,54 @@ mod tests { ); } + #[test] + fn no_call_parens_if_fn_ptr_needed() { + assert_debug_snapshot!( + do_reference_completion( + r" + fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8) {} + + struct ManualVtable { + method: fn(u8, u8, u8, u8, u8), + } + + fn main() -> ManualVtable { + ManualVtable { + method: some<|> + } + } + " + ), + @r###" + [ + CompletionItem { + label: "ManualVtable", + source_range: 295..299, + delete: 295..299, + insert: "ManualVtable", + kind: Struct, + }, + CompletionItem { + label: "main", + source_range: 295..299, + delete: 295..299, + insert: "main", + kind: Function, + detail: "fn main() -> ManualVtable", + }, + CompletionItem { + label: "somefn", + source_range: 295..299, + delete: 295..299, + insert: "somefn", + kind: Function, + detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)", + }, + ] + "### + ); + } + #[test] fn arg_snippets_for_method_call() { assert_debug_snapshot!( -- cgit v1.2.3 From 5a355ff52bc3f05e13a1c675290781da68289bc4 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Apr 2020 22:23:56 +0200 Subject: Fix broken test --- crates/ra_ide/src/completion/presentation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 1c516d312..f5b074461 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -1235,7 +1235,7 @@ mod tests { #[test] fn test_struct_field_completion_in_record_lit() { - covers!(test_struct_field_completion_in_func_call); + covers!(test_struct_field_completion_in_record_lit); assert_debug_snapshot!( do_reference_completion( r" -- cgit v1.2.3