mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
fix: don't complete derive macros as fn-like macros
This commit is contained in:
parent
16e142cd39
commit
ee374ff1ee
4 changed files with 88 additions and 4 deletions
|
@ -1351,6 +1351,13 @@ impl MacroDef {
|
|||
MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_fn_like(&self) -> bool {
|
||||
match self.kind() {
|
||||
MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
|
||||
MacroKind::Attr | MacroKind::Derive => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Invariant: `inner.as_assoc_item(db).is_some()`
|
||||
|
|
|
@ -39,7 +39,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
| hir::ModuleDef::Module(..) => refutable,
|
||||
_ => false,
|
||||
},
|
||||
hir::ScopeDef::MacroDef(_) => true,
|
||||
hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
||||
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
|
||||
Some(hir::Adt::Struct(strukt)) => {
|
||||
acc.add_struct_pat(ctx, strukt, Some(name.clone()));
|
||||
|
@ -101,6 +101,28 @@ fn foo() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_complete_non_fn_macros() {
|
||||
check(
|
||||
r#"
|
||||
macro_rules! m { ($e:expr) => { $e } }
|
||||
enum E { X }
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro Clone {}
|
||||
|
||||
fn foo() {
|
||||
match E::X { $0 }
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
ev E::X ()
|
||||
en E
|
||||
ma m!(…) macro_rules! m
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_in_simple_macro_call() {
|
||||
check(
|
||||
|
|
|
@ -26,8 +26,10 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
|||
let module_scope = module.scope(ctx.db, context_module);
|
||||
for (name, def) in module_scope {
|
||||
if let hir::ScopeDef::MacroDef(macro_def) = def {
|
||||
if macro_def.is_fn_like() {
|
||||
acc.add_macro(ctx, Some(name.clone()), macro_def);
|
||||
}
|
||||
}
|
||||
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
|
||||
acc.add_resolution(ctx, name, &def);
|
||||
}
|
||||
|
@ -58,6 +60,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
|||
}
|
||||
}
|
||||
|
||||
if let hir::ScopeDef::MacroDef(macro_def) = def {
|
||||
if !macro_def.is_fn_like() {
|
||||
// Don't suggest attribute macros and derives.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
acc.add_resolution(ctx, name, &def);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
|||
// only show macros in {Assoc}ItemList
|
||||
ctx.scope.process_all_names(&mut |name, res| {
|
||||
if let hir::ScopeDef::MacroDef(mac) = res {
|
||||
if mac.is_fn_like() {
|
||||
acc.add_macro(ctx, Some(name.clone()), mac);
|
||||
}
|
||||
}
|
||||
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
|
||||
acc.add_resolution(ctx, name, &res);
|
||||
}
|
||||
|
@ -46,7 +48,13 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
|||
cov_mark::hit!(skip_lifetime_completion);
|
||||
return;
|
||||
}
|
||||
let add_resolution = match res {
|
||||
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
||||
_ => true,
|
||||
};
|
||||
if add_resolution {
|
||||
acc.add_resolution(ctx, name, &res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -426,6 +434,44 @@ mod macros {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_complete_non_fn_macros() {
|
||||
check(
|
||||
r#"
|
||||
#[rustc_builtin_macro]
|
||||
pub macro Clone {}
|
||||
|
||||
fn f() {$0}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn f() fn()
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
#[rustc_builtin_macro]
|
||||
pub macro Clone {}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
$0
|
||||
}
|
||||
"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
mod m {
|
||||
#[rustc_builtin_macro]
|
||||
pub macro Clone {}
|
||||
}
|
||||
|
||||
fn f() {m::$0}
|
||||
"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_std_prelude_if_core_is_defined() {
|
||||
check(
|
||||
|
|
Loading…
Reference in a new issue