diff options
Diffstat (limited to 'crates/ide_completion/src/completions')
5 files changed, 136 insertions, 12 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index d3392100d..7f76e357e 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs | |||
@@ -69,7 +69,7 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib | |||
69 | } | 69 | } |
70 | 70 | ||
71 | if is_inner || !attr_completion.prefer_inner { | 71 | if is_inner || !attr_completion.prefer_inner { |
72 | acc.add(item.build()); | 72 | item.add_to(acc); |
73 | } | 73 | } |
74 | }; | 74 | }; |
75 | 75 | ||
@@ -96,7 +96,7 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib | |||
96 | if let Some(docs) = mac.docs(ctx.sema.db) { | 96 | if let Some(docs) = mac.docs(ctx.sema.db) { |
97 | item.documentation(docs); | 97 | item.documentation(docs); |
98 | } | 98 | } |
99 | acc.add(item.build()); | 99 | item.add_to(acc); |
100 | } | 100 | } |
101 | } | 101 | } |
102 | }); | 102 | }); |
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index 7bf47bf75..c010cbbca 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs | |||
@@ -90,7 +90,6 @@ | |||
90 | //! Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding | 90 | //! Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding |
91 | //! capability enabled. | 91 | //! capability enabled. |
92 | 92 | ||
93 | use hir::ModPath; | ||
94 | use ide_db::helpers::{ | 93 | use ide_db::helpers::{ |
95 | import_assets::{ImportAssets, ImportCandidate}, | 94 | import_assets::{ImportAssets, ImportCandidate}, |
96 | insert_use::ImportScope, | 95 | insert_use::ImportScope, |
@@ -208,7 +207,7 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs | |||
208 | } | 207 | } |
209 | 208 | ||
210 | fn compute_fuzzy_completion_order_key( | 209 | fn compute_fuzzy_completion_order_key( |
211 | proposed_mod_path: &ModPath, | 210 | proposed_mod_path: &hir::ModPath, |
212 | user_input_lowercased: &str, | 211 | user_input_lowercased: &str, |
213 | ) -> usize { | 212 | ) -> usize { |
214 | cov_mark::hit!(certain_fuzzy_order_test); | 213 | cov_mark::hit!(certain_fuzzy_order_test); |
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index 8a728c67e..1daa8595a 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs | |||
@@ -39,7 +39,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
39 | | hir::ModuleDef::Module(..) => refutable, | 39 | | hir::ModuleDef::Module(..) => refutable, |
40 | _ => false, | 40 | _ => false, |
41 | }, | 41 | }, |
42 | hir::ScopeDef::MacroDef(_) => true, | 42 | hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(), |
43 | hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() { | 43 | hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() { |
44 | Some(hir::Adt::Struct(strukt)) => { | 44 | Some(hir::Adt::Struct(strukt)) => { |
45 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); | 45 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); |
@@ -102,6 +102,28 @@ fn foo() { | |||
102 | } | 102 | } |
103 | 103 | ||
104 | #[test] | 104 | #[test] |
105 | fn does_not_complete_non_fn_macros() { | ||
106 | check( | ||
107 | r#" | ||
108 | macro_rules! m { ($e:expr) => { $e } } | ||
109 | enum E { X } | ||
110 | |||
111 | #[rustc_builtin_macro] | ||
112 | macro Clone {} | ||
113 | |||
114 | fn foo() { | ||
115 | match E::X { $0 } | ||
116 | } | ||
117 | "#, | ||
118 | expect![[r#" | ||
119 | ev E::X () | ||
120 | en E | ||
121 | ma m!(…) macro_rules! m | ||
122 | "#]], | ||
123 | ); | ||
124 | } | ||
125 | |||
126 | #[test] | ||
105 | fn completes_in_simple_macro_call() { | 127 | fn completes_in_simple_macro_call() { |
106 | check( | 128 | check( |
107 | r#" | 129 | r#" |
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index d58745fb4..0b0a81410 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs | |||
@@ -26,7 +26,9 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
26 | let module_scope = module.scope(ctx.db, context_module); | 26 | let module_scope = module.scope(ctx.db, context_module); |
27 | for (name, def) in module_scope { | 27 | for (name, def) in module_scope { |
28 | if let hir::ScopeDef::MacroDef(macro_def) = def { | 28 | if let hir::ScopeDef::MacroDef(macro_def) = def { |
29 | acc.add_macro(ctx, Some(name.clone()), macro_def); | 29 | if macro_def.is_fn_like() { |
30 | acc.add_macro(ctx, Some(name.clone()), macro_def); | ||
31 | } | ||
30 | } | 32 | } |
31 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { | 33 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { |
32 | acc.add_resolution(ctx, name, &def); | 34 | acc.add_resolution(ctx, name, &def); |
@@ -58,6 +60,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
58 | } | 60 | } |
59 | } | 61 | } |
60 | 62 | ||
63 | if let hir::ScopeDef::MacroDef(macro_def) = def { | ||
64 | if !macro_def.is_fn_like() { | ||
65 | // Don't suggest attribute macros and derives. | ||
66 | continue; | ||
67 | } | ||
68 | } | ||
69 | |||
61 | acc.add_resolution(ctx, name, &def); | 70 | acc.add_resolution(ctx, name, &def); |
62 | } | 71 | } |
63 | } | 72 | } |
@@ -199,6 +208,36 @@ mod tests { | |||
199 | } | 208 | } |
200 | 209 | ||
201 | #[test] | 210 | #[test] |
211 | fn dont_complete_values_in_type_pos() { | ||
212 | check( | ||
213 | r#" | ||
214 | const FOO: () = (); | ||
215 | static BAR: () = (); | ||
216 | struct Baz; | ||
217 | fn foo() { | ||
218 | let _: self::$0; | ||
219 | } | ||
220 | "#, | ||
221 | expect![[r#" | ||
222 | st Baz | ||
223 | "#]], | ||
224 | ); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn dont_complete_enum_variants_in_type_pos() { | ||
229 | check( | ||
230 | r#" | ||
231 | enum Foo { Bar } | ||
232 | fn foo() { | ||
233 | let _: Foo::$0; | ||
234 | } | ||
235 | "#, | ||
236 | expect![[r#""#]], | ||
237 | ); | ||
238 | } | ||
239 | |||
240 | #[test] | ||
202 | fn dont_complete_current_use_in_braces_with_glob() { | 241 | fn dont_complete_current_use_in_braces_with_glob() { |
203 | check( | 242 | check( |
204 | r#" | 243 | r#" |
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 8b22933e0..1f6c4069f 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs | |||
@@ -13,7 +13,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
13 | // only show macros in {Assoc}ItemList | 13 | // only show macros in {Assoc}ItemList |
14 | ctx.scope.process_all_names(&mut |name, res| { | 14 | ctx.scope.process_all_names(&mut |name, res| { |
15 | if let hir::ScopeDef::MacroDef(mac) = res { | 15 | if let hir::ScopeDef::MacroDef(mac) = res { |
16 | acc.add_macro(ctx, Some(name.clone()), mac); | 16 | if mac.is_fn_like() { |
17 | acc.add_macro(ctx, Some(name.clone()), mac); | ||
18 | } | ||
17 | } | 19 | } |
18 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { | 20 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { |
19 | acc.add_resolution(ctx, name, &res); | 21 | acc.add_resolution(ctx, name, &res); |
@@ -46,7 +48,13 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
46 | cov_mark::hit!(skip_lifetime_completion); | 48 | cov_mark::hit!(skip_lifetime_completion); |
47 | return; | 49 | return; |
48 | } | 50 | } |
49 | acc.add_resolution(ctx, name, &res); | 51 | let add_resolution = match res { |
52 | ScopeDef::MacroDef(mac) => mac.is_fn_like(), | ||
53 | _ => true, | ||
54 | }; | ||
55 | if add_resolution { | ||
56 | acc.add_resolution(ctx, name, &res); | ||
57 | } | ||
50 | }); | 58 | }); |
51 | } | 59 | } |
52 | 60 | ||
@@ -69,6 +77,28 @@ mod tests { | |||
69 | } | 77 | } |
70 | 78 | ||
71 | #[test] | 79 | #[test] |
80 | fn dont_complete_values_in_type_pos() { | ||
81 | check( | ||
82 | r#" | ||
83 | const FOO: () = (); | ||
84 | static BAR: () = (); | ||
85 | enum Foo { | ||
86 | Bar | ||
87 | } | ||
88 | struct Baz; | ||
89 | fn foo() { | ||
90 | let local = (); | ||
91 | let _: $0; | ||
92 | } | ||
93 | "#, | ||
94 | expect![[r#" | ||
95 | en Foo | ||
96 | st Baz | ||
97 | "#]], | ||
98 | ); | ||
99 | } | ||
100 | |||
101 | #[test] | ||
72 | fn only_completes_modules_in_import() { | 102 | fn only_completes_modules_in_import() { |
73 | cov_mark::check!(only_completes_modules_in_import); | 103 | cov_mark::check!(only_completes_modules_in_import); |
74 | check( | 104 | check( |
@@ -339,7 +369,6 @@ fn x() -> $0 | |||
339 | "#, | 369 | "#, |
340 | expect![[r#" | 370 | expect![[r#" |
341 | st Foo | 371 | st Foo |
342 | fn x() fn() | ||
343 | "#]], | 372 | "#]], |
344 | ); | 373 | ); |
345 | } | 374 | } |
@@ -391,7 +420,6 @@ pub mod prelude { | |||
391 | } | 420 | } |
392 | "#, | 421 | "#, |
393 | expect![[r#" | 422 | expect![[r#" |
394 | fn foo() fn() | ||
395 | md std | 423 | md std |
396 | st Option | 424 | st Option |
397 | "#]], | 425 | "#]], |
@@ -427,6 +455,44 @@ mod macros { | |||
427 | } | 455 | } |
428 | 456 | ||
429 | #[test] | 457 | #[test] |
458 | fn does_not_complete_non_fn_macros() { | ||
459 | check( | ||
460 | r#" | ||
461 | #[rustc_builtin_macro] | ||
462 | pub macro Clone {} | ||
463 | |||
464 | fn f() {$0} | ||
465 | "#, | ||
466 | expect![[r#" | ||
467 | fn f() fn() | ||
468 | "#]], | ||
469 | ); | ||
470 | check( | ||
471 | r#" | ||
472 | #[rustc_builtin_macro] | ||
473 | pub macro Clone {} | ||
474 | |||
475 | struct S; | ||
476 | impl S { | ||
477 | $0 | ||
478 | } | ||
479 | "#, | ||
480 | expect![[r#""#]], | ||
481 | ); | ||
482 | check( | ||
483 | r#" | ||
484 | mod m { | ||
485 | #[rustc_builtin_macro] | ||
486 | pub macro Clone {} | ||
487 | } | ||
488 | |||
489 | fn f() {m::$0} | ||
490 | "#, | ||
491 | expect![[r#""#]], | ||
492 | ); | ||
493 | } | ||
494 | |||
495 | #[test] | ||
430 | fn completes_std_prelude_if_core_is_defined() { | 496 | fn completes_std_prelude_if_core_is_defined() { |
431 | check( | 497 | check( |
432 | r#" | 498 | r#" |
@@ -448,7 +514,6 @@ pub mod prelude { | |||
448 | } | 514 | } |
449 | "#, | 515 | "#, |
450 | expect![[r#" | 516 | expect![[r#" |
451 | fn foo() fn() | ||
452 | md std | 517 | md std |
453 | md core | 518 | md core |
454 | st String | 519 | st String |
@@ -509,7 +574,6 @@ macro_rules! foo { () => {} } | |||
509 | fn main() { let x: $0 } | 574 | fn main() { let x: $0 } |
510 | "#, | 575 | "#, |
511 | expect![[r#" | 576 | expect![[r#" |
512 | fn main() fn() | ||
513 | ma foo!(…) macro_rules! foo | 577 | ma foo!(…) macro_rules! foo |
514 | "#]], | 578 | "#]], |
515 | ); | 579 | ); |