@@ -86,36 +86,46 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt
86
86
token = token. prev_token ( ) ?;
87
87
}
88
88
89
- let ( kind, trigger, impl_def_offset) = token. ancestors ( ) . find_map ( |p| match p. kind ( ) {
90
- // `const` can be a modifier of an item, so the `const` token may be inside another item syntax node.
91
- // Eg. `impl .. { const <|> fn bar() .. }`
92
- SyntaxKind :: FN | SyntaxKind :: TYPE_ALIAS | SyntaxKind :: CONST
93
- if token. kind ( ) == SyntaxKind :: CONST_KW =>
94
- {
95
- Some ( ( ImplCompletionKind :: Const , p, 2 ) )
96
- }
97
- SyntaxKind :: FN => Some ( ( ImplCompletionKind :: Fn , p, 2 ) ) ,
98
- SyntaxKind :: TYPE_ALIAS => Some ( ( ImplCompletionKind :: TypeAlias , p, 2 ) ) ,
99
- SyntaxKind :: CONST => Some ( ( ImplCompletionKind :: Const , p, 2 ) ) ,
100
- // `impl .. { const <|> }` is parsed as:
101
- // IMPL
102
- // ASSOC_ITEM_LIST
103
- // ERROR
104
- // CONST_KW <- token
105
- // WHITESPACE <- ctx.token
106
- SyntaxKind :: ERROR
107
- if p. first_token ( ) . map_or ( false , |t| t. kind ( ) == SyntaxKind :: CONST_KW ) =>
108
- {
109
- Some ( ( ImplCompletionKind :: Const , p, 2 ) )
110
- }
111
- SyntaxKind :: NAME_REF => Some ( ( ImplCompletionKind :: All , p, 5 ) ) ,
112
- _ => None ,
113
- } ) ?;
89
+ let impl_item_offset = match token. kind ( ) {
90
+ // `impl .. { const <|> }`
91
+ // ERROR 0
92
+ // CONST_KW <- *
93
+ SyntaxKind :: CONST_KW => 0 ,
94
+ // `impl .. { fn/type <|> }`
95
+ // FN/TYPE_ALIAS 0
96
+ // FN_KW <- *
97
+ SyntaxKind :: FN_KW | SyntaxKind :: TYPE_KW => 0 ,
98
+ // `impl .. { fn/type/const foo<|> }`
99
+ // FN/TYPE_ALIAS/CONST 1
100
+ // NAME 0
101
+ // IDENT <- *
102
+ SyntaxKind :: IDENT if token. parent ( ) . kind ( ) == SyntaxKind :: NAME => 1 ,
103
+ // `impl .. { foo<|> }`
104
+ // MACRO_CALL 3
105
+ // PATH 2
106
+ // PATH_SEGMENT 1
107
+ // NAME_REF 0
108
+ // IDENT <- *
109
+ SyntaxKind :: IDENT if token. parent ( ) . kind ( ) == SyntaxKind :: NAME_REF => 3 ,
110
+ _ => return None ,
111
+ } ;
114
112
115
- let impl_def = ( 0 ..impl_def_offset - 1 )
116
- . try_fold ( trigger. parent ( ) ?, |t, _| t. parent ( ) )
117
- . and_then ( ast:: Impl :: cast) ?;
118
- Some ( ( kind, trigger, impl_def) )
113
+ let impl_item = token. ancestors ( ) . nth ( impl_item_offset) ?;
114
+ // Must directly belong to an impl block.
115
+ // IMPL
116
+ // ASSOC_ITEM_LIST
117
+ // <item>
118
+ let impl_def = ast:: Impl :: cast ( impl_item. parent ( ) ?. parent ( ) ?) ?;
119
+ let kind = match impl_item. kind ( ) {
120
+ // `impl ... { const <|> fn/type/const }`
121
+ _ if token. kind ( ) == SyntaxKind :: CONST_KW => ImplCompletionKind :: Const ,
122
+ SyntaxKind :: CONST | SyntaxKind :: ERROR => ImplCompletionKind :: Const ,
123
+ SyntaxKind :: TYPE_ALIAS => ImplCompletionKind :: TypeAlias ,
124
+ SyntaxKind :: FN => ImplCompletionKind :: Fn ,
125
+ SyntaxKind :: MACRO_CALL => ImplCompletionKind :: All ,
126
+ _ => return None ,
127
+ } ;
128
+ Some ( ( kind, impl_item, impl_def) )
119
129
}
120
130
121
131
fn add_function_impl (
@@ -261,19 +271,191 @@ ta type TestType = \n\
261
271
}
262
272
263
273
#[ test]
264
- fn no_nested_fn_completions ( ) {
274
+ fn no_completion_inside_fn ( ) {
265
275
check (
266
276
r"
267
- trait Test {
268
- fn test();
269
- fn test2();
277
+ trait Test { fn test(); fn test2(); }
278
+ struct T;
279
+
280
+ impl Test for T {
281
+ fn test() {
282
+ t<|>
283
+ }
284
+ }
285
+ " ,
286
+ expect ! [ [ "" ] ] ,
287
+ ) ;
288
+
289
+ check (
290
+ r"
291
+ trait Test { fn test(); fn test2(); }
292
+ struct T;
293
+
294
+ impl Test for T {
295
+ fn test() {
296
+ fn t<|>
297
+ }
270
298
}
299
+ " ,
300
+ expect ! [ [ "" ] ] ,
301
+ ) ;
302
+
303
+ check (
304
+ r"
305
+ trait Test { fn test(); fn test2(); }
271
306
struct T;
272
307
273
308
impl Test for T {
274
309
fn test() {
310
+ fn <|>
311
+ }
312
+ }
313
+ " ,
314
+ expect ! [ [ "" ] ] ,
315
+ ) ;
316
+
317
+ // https://github.com/rust-analyzer/rust-analyzer/pull/5976#issuecomment-692332191
318
+ check (
319
+ r"
320
+ trait Test { fn test(); fn test2(); }
321
+ struct T;
322
+
323
+ impl Test for T {
324
+ fn test() {
325
+ foo.<|>
326
+ }
327
+ }
328
+ " ,
329
+ expect ! [ [ "" ] ] ,
330
+ ) ;
331
+
332
+ check (
333
+ r"
334
+ trait Test { fn test(_: i32); fn test2(); }
335
+ struct T;
336
+
337
+ impl Test for T {
338
+ fn test(t<|>)
339
+ }
340
+ " ,
341
+ expect ! [ [ "" ] ] ,
342
+ ) ;
343
+
344
+ check (
345
+ r"
346
+ trait Test { fn test(_: fn()); fn test2(); }
347
+ struct T;
348
+
349
+ impl Test for T {
350
+ fn test(f: fn <|>)
351
+ }
352
+ " ,
353
+ expect ! [ [ "" ] ] ,
354
+ ) ;
355
+ }
356
+
357
+ #[ test]
358
+ fn no_completion_inside_const ( ) {
359
+ check (
360
+ r"
361
+ trait Test { const TEST: fn(); const TEST2: u32; type Test; fn test(); }
362
+ struct T;
363
+
364
+ impl Test for T {
365
+ const TEST: fn <|>
366
+ }
367
+ " ,
368
+ expect ! [ [ "" ] ] ,
369
+ ) ;
370
+
371
+ check (
372
+ r"
373
+ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
374
+ struct T;
375
+
376
+ impl Test for T {
377
+ const TEST: T<|>
378
+ }
379
+ " ,
380
+ expect ! [ [ "" ] ] ,
381
+ ) ;
382
+
383
+ check (
384
+ r"
385
+ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
386
+ struct T;
387
+
388
+ impl Test for T {
389
+ const TEST: u32 = f<|>
390
+ }
391
+ " ,
392
+ expect ! [ [ "" ] ] ,
393
+ ) ;
394
+
395
+ check (
396
+ r"
397
+ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
398
+ struct T;
399
+
400
+ impl Test for T {
401
+ const TEST: u32 = {
275
402
t<|>
403
+ };
404
+ }
405
+ " ,
406
+ expect ! [ [ "" ] ] ,
407
+ ) ;
408
+
409
+ check (
410
+ r"
411
+ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
412
+ struct T;
413
+
414
+ impl Test for T {
415
+ const TEST: u32 = {
416
+ fn <|>
417
+ };
418
+ }
419
+ " ,
420
+ expect ! [ [ "" ] ] ,
421
+ ) ;
422
+
423
+ check (
424
+ r"
425
+ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
426
+ struct T;
427
+
428
+ impl Test for T {
429
+ const TEST: u32 = {
430
+ fn t<|>
431
+ };
432
+ }
433
+ " ,
434
+ expect ! [ [ "" ] ] ,
435
+ ) ;
276
436
}
437
+
438
+ #[ test]
439
+ fn no_completion_inside_type ( ) {
440
+ check (
441
+ r"
442
+ trait Test { type Test; type Test2; fn test(); }
443
+ struct T;
444
+
445
+ impl Test for T {
446
+ type Test = T<|>;
447
+ }
448
+ " ,
449
+ expect ! [ [ "" ] ] ,
450
+ ) ;
451
+
452
+ check (
453
+ r"
454
+ trait Test { type Test; type Test2; fn test(); }
455
+ struct T;
456
+
457
+ impl Test for T {
458
+ type Test = fn <|>;
277
459
}
278
460
" ,
279
461
expect ! [ [ "" ] ] ,
0 commit comments