Skip to content

Commit 2abe19e

Browse files
committed
Don't offer qualified path completions for buitlin derives
1 parent a8b76b6 commit 2abe19e

File tree

6 files changed

+42
-82
lines changed

6 files changed

+42
-82
lines changed

crates/hir/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,10 @@ impl Macro {
18111811
pub fn is_attr(&self, db: &dyn HirDatabase) -> bool {
18121812
matches!(self.kind(db), MacroKind::Attr)
18131813
}
1814+
1815+
pub fn is_derive(&self, db: &dyn HirDatabase) -> bool {
1816+
matches!(self.kind(db), MacroKind::Derive)
1817+
}
18141818
}
18151819

18161820
impl HasVisibility for Macro {

crates/ide_completion/src/completions/attribute/derive.rs

Lines changed: 10 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
//! Completion for derives
2-
use hir::{HasAttrs, Macro, MacroKind};
3-
use ide_db::{
4-
imports::{import_assets::ImportAssets, insert_use::ImportScope},
5-
SymbolKind,
6-
};
2+
use hir::{HasAttrs, Macro};
3+
use ide_db::SymbolKind;
74
use itertools::Itertools;
8-
use rustc_hash::FxHashSet;
9-
use syntax::{SmolStr, SyntaxKind};
5+
use syntax::SmolStr;
106

117
use crate::{
12-
completions::flyimport::compute_fuzzy_completion_order_key,
138
context::{CompletionContext, PathCompletionCtx, PathKind},
149
item::CompletionItem,
15-
Completions, ImportEdit,
10+
Completions,
1611
};
1712

1813
pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
19-
let attr = match (&ctx.path_context, ctx.attr.as_ref()) {
20-
(Some(PathCompletionCtx { kind: Some(PathKind::Derive), .. }), Some(attr)) => attr,
14+
match ctx.path_context {
15+
// FIXME: Enable qualified completions
16+
Some(PathCompletionCtx { kind: Some(PathKind::Derive), qualifier: None, .. }) => (),
2117
_ => return,
22-
};
18+
}
2319

2420
let core = ctx.famous_defs().core();
25-
let existing_derives: FxHashSet<_> =
26-
ctx.sema.resolve_derive_macro(attr).into_iter().flatten().flatten().collect();
2721

2822
for (name, mac) in get_derives_in_scope(ctx) {
29-
if existing_derives.contains(&mac) {
23+
if ctx.existing_derives.contains(&mac) {
3024
continue;
3125
}
3226

@@ -41,7 +35,7 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
4135
let mut components = vec![derive_completion.label];
4236
components.extend(derive_completion.dependencies.iter().filter(
4337
|&&dependency| {
44-
!existing_derives
38+
!ctx.existing_derives
4539
.iter()
4640
.map(|it| it.name(ctx.db))
4741
.any(|it| it.to_smol_str() == dependency)
@@ -66,8 +60,6 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
6660
}
6761
item.add_to(acc);
6862
}
69-
70-
flyimport_derive(acc, ctx);
7163
}
7264

7365
fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, Macro)> {
@@ -82,51 +74,6 @@ fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, Macro)> {
8274
result
8375
}
8476

85-
fn flyimport_derive(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
86-
if ctx.token.kind() != SyntaxKind::IDENT {
87-
return None;
88-
};
89-
let potential_import_name = ctx.token.to_string();
90-
let module = ctx.module?;
91-
let parent = ctx.token.parent()?;
92-
let user_input_lowercased = potential_import_name.to_lowercase();
93-
let import_assets = ImportAssets::for_fuzzy_path(
94-
module,
95-
None,
96-
potential_import_name,
97-
&ctx.sema,
98-
parent.clone(),
99-
)?;
100-
let import_scope = ImportScope::find_insert_use_container(&parent, &ctx.sema)?;
101-
acc.add_all(
102-
import_assets
103-
.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
104-
.into_iter()
105-
.filter_map(|import| match import.original_item {
106-
hir::ItemInNs::Macros(mac) => Some((import, mac)),
107-
_ => None,
108-
})
109-
.filter(|&(_, mac)| mac.kind(ctx.db) == MacroKind::Derive)
110-
.filter(|&(_, mac)| !ctx.is_item_hidden(&hir::ItemInNs::Macros(mac)))
111-
.sorted_by_key(|(import, _)| {
112-
compute_fuzzy_completion_order_key(&import.import_path, &user_input_lowercased)
113-
})
114-
.filter_map(|(import, mac)| {
115-
let mut item = CompletionItem::new(
116-
SymbolKind::Derive,
117-
ctx.source_range(),
118-
mac.name(ctx.db).to_smol_str(),
119-
);
120-
item.add_import(ImportEdit { import, scope: import_scope.clone() });
121-
if let Some(docs) = mac.docs(ctx.db) {
122-
item.documentation(docs);
123-
}
124-
Some(item.build())
125-
}),
126-
);
127-
Some(())
128-
}
129-
13077
struct DeriveDependencies {
13178
label: &'static str,
13279
dependencies: &'static [&'static str],

crates/ide_completion/src/completions/flyimport.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
142142
)?;
143143

144144
let ns_filter = |import: &LocatedImport| {
145-
let kind = match ctx.path_kind() {
145+
let path_kind = match ctx.path_kind() {
146146
Some(kind) => kind,
147147
None => {
148148
return match import.original_item {
@@ -151,9 +151,9 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
151151
}
152152
}
153153
};
154-
match (kind, import.original_item) {
154+
match (path_kind, import.original_item) {
155155
// Aren't handled in flyimport
156-
(PathKind::Vis { .. } | PathKind::Use | PathKind::Derive, _) => false,
156+
(PathKind::Vis { .. } | PathKind::Use, _) => false,
157157
// modules are always fair game
158158
(_, ItemInNs::Types(hir::ModuleDef::Module(_))) => true,
159159
// and so are macros(except for attributes)
@@ -173,6 +173,11 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
173173

174174
(PathKind::Attr { .. }, ItemInNs::Macros(mac)) => mac.is_attr(ctx.db),
175175
(PathKind::Attr { .. }, _) => false,
176+
177+
(PathKind::Derive, ItemInNs::Macros(mac)) => {
178+
mac.is_derive(ctx.db) && !ctx.existing_derives.contains(&mac)
179+
}
180+
(PathKind::Derive, _) => false,
176181
}
177182
};
178183

crates/ide_completion/src/context.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use ide_db::{
1212
famous_defs::FamousDefs,
1313
RootDatabase,
1414
};
15+
use rustc_hash::FxHashSet;
1516
use syntax::{
1617
algo::{find_node_at_offset, non_trivia_sibling},
1718
ast::{self, AttrKind, HasName, NameOrNameRef},
@@ -127,7 +128,6 @@ pub(crate) struct CompletionContext<'a> {
127128

128129
/// The parent function of the cursor position if it exists.
129130
pub(super) function_def: Option<ast::Fn>,
130-
pub(super) attr: Option<ast::Attr>,
131131
/// The parent impl of the cursor position if it exists.
132132
pub(super) impl_def: Option<ast::Impl>,
133133
/// The NameLike under the cursor in the original file if it exists.
@@ -143,6 +143,8 @@ pub(crate) struct CompletionContext<'a> {
143143
pub(super) pattern_ctx: Option<PatternContext>,
144144
pub(super) path_context: Option<PathCompletionCtx>,
145145

146+
pub(super) existing_derives: FxHashSet<hir::Macro>,
147+
146148
pub(super) locals: Vec<(Name, Local)>,
147149

148150
no_completion_required: bool,
@@ -440,7 +442,6 @@ impl<'a> CompletionContext<'a> {
440442
expected_name: None,
441443
expected_type: None,
442444
function_def: None,
443-
attr: None,
444445
impl_def: None,
445446
name_syntax: None,
446447
lifetime_ctx: None,
@@ -453,6 +454,7 @@ impl<'a> CompletionContext<'a> {
453454
locals,
454455
incomplete_let: false,
455456
no_completion_required: false,
457+
existing_derives: Default::default(),
456458
};
457459
ctx.expand_and_fill(
458460
original_file.syntax().clone(),
@@ -746,11 +748,6 @@ impl<'a> CompletionContext<'a> {
746748
(fn_is_prev && !inside_impl_trait_block) || for_is_prev2
747749
};
748750

749-
self.attr = self
750-
.sema
751-
.token_ancestors_with_macros(self.token.clone())
752-
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
753-
.find_map(ast::Attr::cast);
754751
self.fake_attribute_under_caret = syntax_element.ancestors().find_map(ast::Attr::cast);
755752

756753
self.incomplete_let =
@@ -764,9 +761,21 @@ impl<'a> CompletionContext<'a> {
764761

765762
// Overwrite the path kind for derives
766763
if let Some((original_file, file_with_fake_ident, offset)) = derive_ctx {
764+
let attr = self
765+
.sema
766+
.token_ancestors_with_macros(self.token.clone())
767+
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
768+
.find_map(ast::Attr::cast);
769+
if let Some(attr) = &attr {
770+
self.existing_derives =
771+
self.sema.resolve_derive_macro(attr).into_iter().flatten().flatten().collect();
772+
}
773+
767774
if let Some(ast::NameLike::NameRef(name_ref)) =
768775
find_node_at_offset(&file_with_fake_ident, offset)
769776
{
777+
self.name_syntax =
778+
find_node_at_offset(&original_file, name_ref.syntax().text_range().start());
770779
if let Some((path_ctx, _)) =
771780
Self::classify_name_ref(&self.sema, &original_file, name_ref)
772781
{

crates/ide_completion/src/render/macro_.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ fn detail(sema: &Semantics<RootDatabase>, macro_: hir::Macro) -> Option<String>
109109
let _ = sema.parse_or_expand(file_id);
110110
let detail = match value {
111111
Either::Left(node) => macro_label(&node),
112+
// FIXME: this should render with the derive name, not the function name
112113
Either::Right(node) => fn_as_proc_macro_label(&node),
113114
};
114115
Some(detail)

crates/ide_completion/src/tests/attribute.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ mod derive {
764764
#[derive(der$0)] struct Test;
765765
"#,
766766
expect![[r#"
767-
de DeriveIdentity (use proc_macros::DeriveIdentity)
767+
de DeriveIdentity (use proc_macros::DeriveIdentity) pub macro derive_identity
768768
"#]],
769769
);
770770
check_derive(
@@ -805,21 +805,15 @@ use proc_macros::DeriveIdentity;
805805
//- minicore: derive, copy, clone
806806
#[derive(proc_macros::$0)] struct Test;
807807
"#,
808-
expect![[r#"
809-
de Clone, Copy
810-
de Clone
811-
"#]],
808+
expect![[r#""#]],
812809
);
813810
check_derive(
814811
r#"
815812
//- proc_macros: derive_identity
816813
//- minicore: derive, copy, clone
817814
#[derive(proc_macros::C$0)] struct Test;
818815
"#,
819-
expect![[r#"
820-
de Clone, Copy
821-
de Clone
822-
"#]],
816+
expect![[r#""#]],
823817
);
824818
}
825819
}

0 commit comments

Comments
 (0)