mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +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,
|
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()`
|
/// 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,
|
| hir::ModuleDef::Module(..) => refutable,
|
||||||
_ => false,
|
_ => 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() {
|
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
|
||||||
Some(hir::Adt::Struct(strukt)) => {
|
Some(hir::Adt::Struct(strukt)) => {
|
||||||
acc.add_struct_pat(ctx, strukt, Some(name.clone()));
|
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]
|
#[test]
|
||||||
fn completes_in_simple_macro_call() {
|
fn completes_in_simple_macro_call() {
|
||||||
check(
|
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);
|
let module_scope = module.scope(ctx.db, context_module);
|
||||||
for (name, def) in module_scope {
|
for (name, def) in module_scope {
|
||||||
if let hir::ScopeDef::MacroDef(macro_def) = def {
|
if let hir::ScopeDef::MacroDef(macro_def) = def {
|
||||||
|
if macro_def.is_fn_like() {
|
||||||
acc.add_macro(ctx, Some(name.clone()), macro_def);
|
acc.add_macro(ctx, Some(name.clone()), macro_def);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
|
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
|
||||||
acc.add_resolution(ctx, name, &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);
|
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
|
// only show macros in {Assoc}ItemList
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
ctx.scope.process_all_names(&mut |name, res| {
|
||||||
if let hir::ScopeDef::MacroDef(mac) = res {
|
if let hir::ScopeDef::MacroDef(mac) = res {
|
||||||
|
if mac.is_fn_like() {
|
||||||
acc.add_macro(ctx, Some(name.clone()), mac);
|
acc.add_macro(ctx, Some(name.clone()), mac);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
|
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
|
||||||
acc.add_resolution(ctx, name, &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);
|
cov_mark::hit!(skip_lifetime_completion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let add_resolution = match res {
|
||||||
|
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
if add_resolution {
|
||||||
acc.add_resolution(ctx, name, &res);
|
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]
|
#[test]
|
||||||
fn completes_std_prelude_if_core_is_defined() {
|
fn completes_std_prelude_if_core_is_defined() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Reference in a new issue