Don't add call parens when an fn type is expected

This commit is contained in:
Jonas Schievink 2020-04-25 21:34:38 +02:00
parent 45832b990c
commit 76d6f54471
2 changed files with 63 additions and 0 deletions

View File

@ -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);

View File

@ -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!(