@@ -86,36 +86,46 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt
8686 token = token. prev_token ( ) ?;
8787 }
8888
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+ } ;
114112
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) )
119129}
120130
121131fn add_function_impl (
@@ -261,19 +271,191 @@ ta type TestType = \n\
261271 }
262272
263273 #[ test]
264- fn no_nested_fn_completions ( ) {
274+ fn no_completion_inside_fn ( ) {
265275 check (
266276 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+ }
270298}
299+ " ,
300+ expect ! [ [ "" ] ] ,
301+ ) ;
302+
303+ check (
304+ r"
305+ trait Test { fn test(); fn test2(); }
271306struct T;
272307
273308impl Test for T {
274309 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 = {
275402 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+ ) ;
276436 }
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 <|>;
277459}
278460" ,
279461 expect ! [ [ "" ] ] ,
0 commit comments