@@ -11,32 +11,38 @@ use crate::{
11
11
12
12
pub ( crate ) fn complete_expr_path ( acc : & mut Completions , ctx : & CompletionContext ) {
13
13
let _p = profile:: span ( "complete_expr_path" ) ;
14
- if ctx. is_path_disallowed ( ) {
15
- return ;
16
- }
17
14
18
- let ( is_absolute_path, qualifier, in_block_expr, in_loop_body, is_func_update, after_if_expr) =
19
- match ctx. nameref_ctx ( ) {
20
- Some ( NameRefContext {
21
- path_ctx :
22
- Some ( PathCompletionCtx {
23
- kind : PathKind :: Expr { in_block_expr, in_loop_body, after_if_expr } ,
24
- is_absolute_path,
25
- qualifier,
26
- ..
27
- } ) ,
28
- record_expr,
29
- ..
30
- } ) => (
31
- * is_absolute_path,
32
- qualifier,
33
- * in_block_expr,
34
- * in_loop_body,
35
- record_expr. as_ref ( ) . map_or ( false , |& ( _, it) | it) ,
36
- * after_if_expr,
37
- ) ,
38
- _ => return ,
39
- } ;
15
+ let (
16
+ is_absolute_path,
17
+ qualifier,
18
+ in_block_expr,
19
+ in_loop_body,
20
+ is_func_update,
21
+ after_if_expr,
22
+ wants_mut_token,
23
+ ) = match ctx. nameref_ctx ( ) {
24
+ Some ( NameRefContext {
25
+ path_ctx :
26
+ Some ( PathCompletionCtx {
27
+ kind :
28
+ PathKind :: Expr { in_block_expr, in_loop_body, after_if_expr, ref_expr_parent } ,
29
+ is_absolute_path,
30
+ qualifier,
31
+ ..
32
+ } ) ,
33
+ record_expr,
34
+ ..
35
+ } ) if ctx. qualifier_ctx . none ( ) => (
36
+ * is_absolute_path,
37
+ qualifier,
38
+ * in_block_expr,
39
+ * in_loop_body,
40
+ record_expr. as_ref ( ) . map_or ( false , |& ( _, it) | it) ,
41
+ * after_if_expr,
42
+ ref_expr_parent. as_ref ( ) . map ( |it| it. mut_token ( ) . is_none ( ) ) . unwrap_or ( false ) ,
43
+ ) ,
44
+ _ => return ,
45
+ } ;
40
46
41
47
let scope_def_applicable = |def| {
42
48
use hir:: { GenericParam :: * , ModuleDef :: * } ;
@@ -164,12 +170,43 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
164
170
None if is_absolute_path => acc. add_crate_roots ( ctx) ,
165
171
None => {
166
172
acc. add_nameref_keywords_with_colon ( ctx) ;
167
- if let Some ( hir :: Adt :: Enum ( e ) ) =
173
+ if let Some ( adt ) =
168
174
ctx. expected_type . as_ref ( ) . and_then ( |ty| ty. strip_references ( ) . as_adt ( ) )
169
175
{
170
- super :: enum_variants_with_paths ( acc, ctx, e, |acc, ctx, variant, path| {
171
- acc. add_qualified_enum_variant ( ctx, variant, path)
172
- } ) ;
176
+ let self_ty =
177
+ ( || ctx. sema . to_def ( ctx. impl_def . as_ref ( ) ?) ?. self_ty ( ctx. db ) . as_adt ( ) ) ( ) ;
178
+ let complete_self = self_ty == Some ( adt) ;
179
+
180
+ match adt {
181
+ hir:: Adt :: Struct ( strukt) => {
182
+ let path = ctx
183
+ . module
184
+ . find_use_path ( ctx. db , hir:: ModuleDef :: from ( strukt) )
185
+ . filter ( |it| it. len ( ) > 1 ) ;
186
+
187
+ acc. add_struct_literal ( ctx, strukt, path, None ) ;
188
+
189
+ if complete_self {
190
+ acc. add_struct_literal ( ctx, strukt, None , Some ( hir:: known:: SELF_TYPE ) ) ;
191
+ }
192
+ }
193
+ hir:: Adt :: Union ( un) => {
194
+ let path = ctx
195
+ . module
196
+ . find_use_path ( ctx. db , hir:: ModuleDef :: from ( un) )
197
+ . filter ( |it| it. len ( ) > 1 ) ;
198
+
199
+ acc. add_union_literal ( ctx, un, path, None ) ;
200
+ if complete_self {
201
+ acc. add_union_literal ( ctx, un, None , Some ( hir:: known:: SELF_TYPE ) ) ;
202
+ }
203
+ }
204
+ hir:: Adt :: Enum ( e) => {
205
+ super :: enum_variants_with_paths ( acc, ctx, e, |acc, ctx, variant, path| {
206
+ acc. add_qualified_enum_variant ( ctx, variant, path)
207
+ } ) ;
208
+ }
209
+ }
173
210
}
174
211
ctx. process_all_names ( & mut |name, def| {
175
212
if scope_def_applicable ( def) {
@@ -180,20 +217,18 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
180
217
if !is_func_update {
181
218
let mut add_keyword = |kw, snippet| acc. add_keyword_snippet ( ctx, kw, snippet) ;
182
219
183
- if ctx. expects_expression ( ) {
184
- if !in_block_expr {
185
- add_keyword ( "unsafe" , "unsafe {\n $0\n }" ) ;
186
- }
187
- add_keyword ( "match" , "match $1 {\n $0\n }" ) ;
188
- add_keyword ( "while" , "while $1 {\n $0\n }" ) ;
189
- add_keyword ( "while let" , "while let $1 = $2 {\n $0\n }" ) ;
190
- add_keyword ( "loop" , "loop {\n $0\n }" ) ;
191
- add_keyword ( "if" , "if $1 {\n $0\n }" ) ;
192
- add_keyword ( "if let" , "if let $1 = $2 {\n $0\n }" ) ;
193
- add_keyword ( "for" , "for $1 in $2 {\n $0\n }" ) ;
194
- add_keyword ( "true" , "true" ) ;
195
- add_keyword ( "false" , "false" ) ;
220
+ if !in_block_expr {
221
+ add_keyword ( "unsafe" , "unsafe {\n $0\n }" ) ;
196
222
}
223
+ add_keyword ( "match" , "match $1 {\n $0\n }" ) ;
224
+ add_keyword ( "while" , "while $1 {\n $0\n }" ) ;
225
+ add_keyword ( "while let" , "while let $1 = $2 {\n $0\n }" ) ;
226
+ add_keyword ( "loop" , "loop {\n $0\n }" ) ;
227
+ add_keyword ( "if" , "if $1 {\n $0\n }" ) ;
228
+ add_keyword ( "if let" , "if let $1 = $2 {\n $0\n }" ) ;
229
+ add_keyword ( "for" , "for $1 in $2 {\n $0\n }" ) ;
230
+ add_keyword ( "true" , "true" ) ;
231
+ add_keyword ( "false" , "false" ) ;
197
232
198
233
if ctx. previous_token_is ( T ! [ if ] )
199
234
|| ctx. previous_token_is ( T ! [ while ] )
@@ -207,7 +242,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
207
242
add_keyword ( "else if" , "else if $1 {\n $0\n }" ) ;
208
243
}
209
244
210
- if ctx . expects_ident_ref_expr ( ) {
245
+ if wants_mut_token {
211
246
add_keyword ( "mut" , "mut " ) ;
212
247
}
213
248
0 commit comments