@@ -26,23 +26,19 @@ pub(crate) fn complete_dot(
26
26
item. add_to ( acc, ctx. db ) ;
27
27
}
28
28
29
+ let is_field_access = matches ! ( dot_access. kind, DotAccessKind :: Field { .. } ) ;
30
+
31
+ complete_fields (
32
+ acc,
33
+ ctx,
34
+ receiver_ty,
35
+ |acc, field, ty| acc. add_field ( ctx, dot_access, None , field, & ty) ,
36
+ |acc, field, ty| acc. add_tuple_field ( ctx, None , field, & ty) ,
37
+ is_field_access,
38
+ ) ;
39
+
29
40
if let DotAccessKind :: Method { .. } = dot_access. kind {
30
41
cov_mark:: hit!( test_no_struct_field_completion_for_method_call) ;
31
- complete_fn_fields (
32
- acc,
33
- ctx,
34
- receiver_ty,
35
- |acc, field, ty| acc. add_field ( ctx, dot_access, None , field, & ty) ,
36
- |acc, field, ty| acc. add_tuple_field ( ctx, None , field, & ty) ,
37
- ) ;
38
- } else {
39
- complete_fields (
40
- acc,
41
- ctx,
42
- receiver_ty,
43
- |acc, field, ty| acc. add_field ( ctx, dot_access, None , field, & ty) ,
44
- |acc, field, ty| acc. add_tuple_field ( ctx, None , field, & ty) ,
45
- ) ;
46
42
}
47
43
complete_methods ( ctx, receiver_ty, |func| acc. add_method ( ctx, dot_access, func, None , None ) ) ;
48
44
}
@@ -89,6 +85,7 @@ pub(crate) fn complete_undotted_self(
89
85
)
90
86
} ,
91
87
|acc, field, ty| acc. add_tuple_field ( ctx, Some ( hir:: known:: SELF_PARAM ) , field, & ty) ,
88
+ true ,
92
89
) ;
93
90
complete_methods ( ctx, & ty, |func| {
94
91
acc. add_method (
@@ -111,18 +108,23 @@ fn complete_fields(
111
108
receiver : & hir:: Type ,
112
109
mut named_field : impl FnMut ( & mut Completions , hir:: Field , hir:: Type ) ,
113
110
mut tuple_index : impl FnMut ( & mut Completions , usize , hir:: Type ) ,
111
+ is_field_access : bool ,
114
112
) {
115
113
let mut seen_names = FxHashSet :: default ( ) ;
116
114
for receiver in receiver. autoderef ( ctx. db ) {
117
115
for ( field, ty) in receiver. fields ( ctx. db ) {
118
- if seen_names. insert ( field. name ( ctx. db ) ) {
116
+ if seen_names. insert ( field. name ( ctx. db ) )
117
+ && ( is_field_access || ty. is_fn ( ) || ty. is_closure ( ) )
118
+ {
119
119
named_field ( acc, field, ty) ;
120
120
}
121
121
}
122
122
for ( i, ty) in receiver. tuple_fields ( ctx. db ) . into_iter ( ) . enumerate ( ) {
123
123
// Tuples are always the last type in a deref chain, so just check if the name is
124
124
// already seen without inserting into the hashset.
125
- if !seen_names. contains ( & hir:: Name :: new_tuple_field ( i) ) {
125
+ if !seen_names. contains ( & hir:: Name :: new_tuple_field ( i) )
126
+ && ( is_field_access || ty. is_fn ( ) || ty. is_closure ( ) )
127
+ {
126
128
// Tuple fields are always public (tuple struct fields are handled above).
127
129
tuple_index ( acc, i, ty) ;
128
130
}
@@ -151,33 +153,6 @@ fn complete_methods(
151
153
) ;
152
154
}
153
155
154
- fn complete_fn_fields (
155
- acc : & mut Completions ,
156
- ctx : & CompletionContext < ' _ > ,
157
- receiver : & hir:: Type ,
158
- mut named_field : impl FnMut ( & mut Completions , hir:: Field , hir:: Type ) ,
159
- mut tuple_index : impl FnMut ( & mut Completions , usize , hir:: Type ) ,
160
- ) {
161
- let mut seen_names = FxHashSet :: default ( ) ;
162
- for receiver in receiver. autoderef ( ctx. db ) {
163
- for ( field, ty) in receiver. fields ( ctx. db ) {
164
- if seen_names. insert ( field. name ( ctx. db ) ) && ( ty. is_fn ( ) || ty. is_closure ( ) ) {
165
- named_field ( acc, field, ty) ;
166
- }
167
- }
168
- for ( i, ty) in receiver. tuple_fields ( ctx. db ) . into_iter ( ) . enumerate ( ) {
169
- // Tuples are always the last type in a deref chain, so just check if the name is
170
- // already seen without inserting into the hashset.
171
- if !seen_names. contains ( & hir:: Name :: new_tuple_field ( i) )
172
- && ( ty. is_fn ( ) || ty. is_closure ( ) )
173
- {
174
- // Tuple fields are always public (tuple struct fields are handled above).
175
- tuple_index ( acc, i, ty) ;
176
- }
177
- }
178
- }
179
- }
180
-
181
156
#[ cfg( test) ]
182
157
mod tests {
183
158
use expect_test:: { expect, Expect } ;
0 commit comments