Skip to content

Commit fee7485

Browse files
Propose custom derives in completion
1 parent 767bff8 commit fee7485

File tree

2 files changed

+39
-16
lines changed

2 files changed

+39
-16
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use hir_def::{
1919
use hir_expand::{
2020
diagnostics::DiagnosticSink,
2121
name::{name, AsName},
22-
MacroDefId,
22+
MacroDefId, MacroDefKind,
2323
};
2424
use hir_ty::{
2525
autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy,
@@ -762,13 +762,12 @@ impl MacroDef {
762762

763763
/// Indicate it is a proc-macro
764764
pub fn is_proc_macro(&self) -> bool {
765-
match self.id.kind {
766-
hir_expand::MacroDefKind::Declarative => false,
767-
hir_expand::MacroDefKind::BuiltIn(_) => false,
768-
hir_expand::MacroDefKind::BuiltInDerive(_) => false,
769-
hir_expand::MacroDefKind::BuiltInEager(_) => false,
770-
hir_expand::MacroDefKind::CustomDerive(_) => true,
771-
}
765+
matches!(self.id.kind, MacroDefKind::CustomDerive(_))
766+
}
767+
768+
/// Indicate it is a derive macro
769+
pub fn is_derive_macro(&self) -> bool {
770+
matches!(self.id.kind, MacroDefKind::CustomDerive(_) | MacroDefKind::BuiltInDerive(_))
772771
}
773772
}
774773

crates/ra_ide/src/completion/complete_attribute.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,8 @@ const ATTRIBUTES: &[AttrCompletion] = &[
130130
];
131131

132132
fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) {
133-
// TODO kb autodetect derive macros
134-
// https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0/topic/Find.20all.20possible.20derive.20macro.20values.3F/near/195955580
135-
136133
if let Ok(existing_derives) = parse_derive_input(derive_input) {
137-
for derive_completion in DERIVE_COMPLETIONS
134+
for derive_completion in DEFAULT_DERIVE_COMPLETIONS
138135
.into_iter()
139136
.filter(|completion| !existing_derives.contains(completion.label))
140137
{
@@ -147,9 +144,21 @@ fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input:
147144
label.push_str(", ");
148145
label.push_str(dependency);
149146
}
150-
let item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label)
151-
.kind(CompletionItemKind::Attribute);
152-
acc.add(item);
147+
acc.add(
148+
CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label)
149+
.kind(CompletionItemKind::Attribute),
150+
);
151+
}
152+
153+
for custom_derive_name in get_derive_names_in_scope(ctx).difference(&existing_derives) {
154+
acc.add(
155+
CompletionItem::new(
156+
CompletionKind::Attribute,
157+
ctx.source_range(),
158+
custom_derive_name,
159+
)
160+
.kind(CompletionItemKind::Attribute),
161+
);
153162
}
154163
}
155164
}
@@ -174,12 +183,27 @@ fn parse_derive_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>,
174183
}
175184
}
176185

186+
fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> {
187+
let mut result = FxHashSet::default();
188+
ctx.scope().process_all_names(&mut |name, scope_def| {
189+
if let hir::ScopeDef::MacroDef(mac) = scope_def {
190+
if mac.is_derive_macro() {
191+
let name_string = name.to_string();
192+
result.insert(name_string);
193+
}
194+
}
195+
});
196+
result
197+
}
198+
177199
struct DeriveCompletion {
178200
label: &'static str,
179201
dependencies: &'static [&'static str],
180202
}
181203

182-
const DERIVE_COMPLETIONS: &[DeriveCompletion] = &[
204+
/// Standard Rust derives and the information about their dependencies
205+
/// (the dependencies are needed so that the main derive don't break the compilation when added)
206+
const DEFAULT_DERIVE_COMPLETIONS: &[DeriveCompletion] = &[
183207
DeriveCompletion { label: "Clone", dependencies: &[] },
184208
DeriveCompletion { label: "Copy", dependencies: &["Clone"] },
185209
DeriveCompletion { label: "Debug", dependencies: &[] },

0 commit comments

Comments
 (0)