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 <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2020-04-25 20:30:50 +00:00 committed by GitHub
commit fe99a29ad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 1 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!(
@ -1179,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"