Auto merge of #16049 - dfireBird:followup-callable-fields, r=Veykril

fix: make callable fields not complete in method access no parens case

Follow up PR for #15879

Fixes the callable field completion appearing in the method access with no parens case.
This commit is contained in:
bors 2024-01-02 10:20:31 +00:00
commit 60fe5fd98d

View File

@ -27,6 +27,8 @@ pub(crate) fn complete_dot(
} }
let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. }); let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. });
let is_method_acces_with_parens =
matches!(dot_access.kind, DotAccessKind::Method { has_parens: true });
complete_fields( complete_fields(
acc, acc,
@ -35,6 +37,7 @@ pub(crate) fn complete_dot(
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty), |acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty), |acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
is_field_access, is_field_access,
is_method_acces_with_parens,
); );
complete_methods(ctx, receiver_ty, |func| acc.add_method(ctx, dot_access, func, None, None)); complete_methods(ctx, receiver_ty, |func| acc.add_method(ctx, dot_access, func, None, None));
@ -83,6 +86,7 @@ pub(crate) fn complete_undotted_self(
}, },
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty), |acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
true, true,
false,
); );
complete_methods(ctx, &ty, |func| { complete_methods(ctx, &ty, |func| {
acc.add_method( acc.add_method(
@ -106,12 +110,14 @@ fn complete_fields(
mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type), mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type),
mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type), mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type),
is_field_access: bool, is_field_access: bool,
is_method_acess_with_parens: bool,
) { ) {
let mut seen_names = FxHashSet::default(); let mut seen_names = FxHashSet::default();
for receiver in receiver.autoderef(ctx.db) { for receiver in receiver.autoderef(ctx.db) {
for (field, ty) in receiver.fields(ctx.db) { for (field, ty) in receiver.fields(ctx.db) {
if seen_names.insert(field.name(ctx.db)) if seen_names.insert(field.name(ctx.db))
&& (is_field_access || ty.is_fn() || ty.is_closure()) && (is_field_access
|| (is_method_acess_with_parens && (ty.is_fn() || ty.is_closure())))
{ {
named_field(acc, field, ty); named_field(acc, field, ty);
} }
@ -120,7 +126,8 @@ fn complete_fields(
// Tuples are always the last type in a deref chain, so just check if the name is // Tuples are always the last type in a deref chain, so just check if the name is
// already seen without inserting into the hashset. // already seen without inserting into the hashset.
if !seen_names.contains(&hir::Name::new_tuple_field(i)) if !seen_names.contains(&hir::Name::new_tuple_field(i))
&& (is_field_access || ty.is_fn() || ty.is_closure()) && (is_field_access
|| (is_method_acess_with_parens && (ty.is_fn() || ty.is_closure())))
{ {
// Tuple fields are always public (tuple struct fields are handled above). // Tuple fields are always public (tuple struct fields are handled above).
tuple_index(acc, i, ty); tuple_index(acc, i, ty);
@ -1236,4 +1243,24 @@ fn foo() {
"#, "#,
) )
} }
#[test]
fn test_fn_field_dot_access_method_has_parens_false() {
check(
r#"
struct Foo { baz: fn() }
impl Foo {
fn bar<T>(self, t: T): T { t }
}
fn baz() {
let foo = Foo{ baz: || {} };
foo.ba$0::<>;
}
"#,
expect![[r#"
me bar() fn(self, T)
"#]],
);
}
} }