diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index 613a35dcb10..53a1c8405c2 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -27,6 +27,8 @@ pub(crate) fn complete_dot( } 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( 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_tuple_field(ctx, None, field, &ty), is_field_access, + is_method_acces_with_parens, ); 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), true, + false, ); complete_methods(ctx, &ty, |func| { acc.add_method( @@ -106,12 +110,14 @@ fn complete_fields( mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type), mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type), is_field_access: bool, + is_method_acess_with_parens: bool, ) { let mut seen_names = FxHashSet::default(); for receiver in receiver.autoderef(ctx.db) { for (field, ty) in receiver.fields(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); } @@ -120,7 +126,8 @@ fn complete_fields( // Tuples are always the last type in a deref chain, so just check if the name is // already seen without inserting into the hashset. 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_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(self, t: T): T { t } +} + +fn baz() { + let foo = Foo{ baz: || {} }; + foo.ba$0::<>; +} +"#, + expect![[r#" + me bar(…) fn(self, T) + "#]], + ); + } }