Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/ide-completion/src/completions/dot.rs | 63 | ||||
| -rw-r--r-- | crates/ide-completion/src/render.rs | 4 |
2 files changed, 22 insertions, 45 deletions
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index 2f0b6988f2..e427be381b 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -26,23 +26,19 @@ pub(crate) fn complete_dot( item.add_to(acc, ctx.db); } + let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. }); + + complete_fields( + acc, + ctx, + receiver_ty, + |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, + ); + if let DotAccessKind::Method { .. } = dot_access.kind { cov_mark::hit!(test_no_struct_field_completion_for_method_call); - complete_fn_fields( - acc, - ctx, - receiver_ty, - |acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty), - |acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty), - ); - } else { - complete_fields( - acc, - ctx, - receiver_ty, - |acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty), - |acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty), - ); } complete_methods(ctx, receiver_ty, |func| acc.add_method(ctx, dot_access, func, None, None)); } @@ -89,6 +85,7 @@ pub(crate) fn complete_undotted_self( ) }, |acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty), + true, ); complete_methods(ctx, &ty, |func| { acc.add_method( @@ -111,18 +108,23 @@ fn complete_fields( receiver: &hir::Type, 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, ) { 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)) { + if seen_names.insert(field.name(ctx.db)) + && (is_field_access || ty.is_fn() || ty.is_closure()) + { named_field(acc, field, ty); } } for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { // 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)) { + if !seen_names.contains(&hir::Name::new_tuple_field(i)) + && (is_field_access || ty.is_fn() || ty.is_closure()) + { // Tuple fields are always public (tuple struct fields are handled above). tuple_index(acc, i, ty); } @@ -151,33 +153,6 @@ fn complete_methods( ); } -fn complete_fn_fields( - acc: &mut Completions, - ctx: &CompletionContext<'_>, - receiver: &hir::Type, - mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type), - mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type), -) { - 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)) && (ty.is_fn() || ty.is_closure()) { - named_field(acc, field, ty); - } - } - for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { - // 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)) - && (ty.is_fn() || ty.is_closure()) - { - // Tuple fields are always public (tuple struct fields are handled above). - tuple_index(acc, i, ty); - } - } - } -} - #[cfg(test)] mod tests { use expect_test::{expect, Expect}; diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index f733f36f5d..453ff061bc 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -148,7 +148,9 @@ pub(crate) fn render_field( .set_documentation(field.docs(db)) .set_deprecated(is_deprecated) .lookup_by(name); - if ty.is_fn() || ty.is_closure() { + + let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. }); + if !is_field_access || ty.is_fn() || ty.is_closure() { let mut builder = TextEdit::builder(); // Using TextEdit, insert '(' before the struct name and ')' before the // dot access, then comes the field name and optionally insert function |