aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-06-08 16:31:47 +0100
committerJonas Schievink <[email protected]>2021-06-08 16:31:47 +0100
commitee374ff1ee7ad1af6bc0624f98b2028cef6ed4a8 (patch)
tree8adfe5094cbeca97cecdb78d24857441a10003e6
parent16e142cd395f264ba5c6c3814ece92431415c089 (diff)
fix: don't complete derive macros as fn-like macros
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/ide_completion/src/completions/pattern.rs24
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs11
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs50
4 files changed, 88 insertions, 4 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index c2b68a853..b5209546c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1351,6 +1351,13 @@ impl MacroDef {
1351 MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro, 1351 MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro,
1352 } 1352 }
1353 } 1353 }
1354
1355 pub fn is_fn_like(&self) -> bool {
1356 match self.kind() {
1357 MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
1358 MacroKind::Attr | MacroKind::Derive => false,
1359 }
1360 }
1354} 1361}
1355 1362
1356/// Invariant: `inner.as_assoc_item(db).is_some()` 1363/// Invariant: `inner.as_assoc_item(db).is_some()`
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#"
108macro_rules! m { ($e:expr) => { $e } }
109enum E { X }
110
111#[rustc_builtin_macro]
112macro Clone {}
113
114fn 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..4dfdc5ced 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 }
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index 8b22933e0..52f40d496 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
@@ -427,6 +435,44 @@ mod macros {
427 } 435 }
428 436
429 #[test] 437 #[test]
438 fn does_not_complete_non_fn_macros() {
439 check(
440 r#"
441#[rustc_builtin_macro]
442pub macro Clone {}
443
444fn f() {$0}
445"#,
446 expect![[r#"
447 fn f() fn()
448 "#]],
449 );
450 check(
451 r#"
452#[rustc_builtin_macro]
453pub macro Clone {}
454
455struct S;
456impl S {
457 $0
458}
459"#,
460 expect![[r#""#]],
461 );
462 check(
463 r#"
464mod m {
465 #[rustc_builtin_macro]
466 pub macro Clone {}
467}
468
469fn f() {m::$0}
470"#,
471 expect![[r#""#]],
472 );
473 }
474
475 #[test]
430 fn completes_std_prelude_if_core_is_defined() { 476 fn completes_std_prelude_if_core_is_defined() {
431 check( 477 check(
432 r#" 478 r#"