Skip to content

Commit b6199de

Browse files
bors[bot]Veykriljonas-schievink
authored
Merge #9181 #9182
9181: Don't complete values in type position r=jonas-schievink a=Veykril Will add some proper tests in a bit 9182: fix: don't complete derive macros as fn-like macros r=jonas-schievink a=jonas-schievink Part of #8518 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com> Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
3 parents 4e3769f + 1a26af1 + ee374ff commit b6199de

File tree

10 files changed

+219
-59
lines changed

10 files changed

+219
-59
lines changed

crates/hir/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,13 @@ impl MacroDef {
13511351
MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro,
13521352
}
13531353
}
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+
}
13541361
}
13551362

13561363
/// Invariant: `inner.as_assoc_item(db).is_some()`
@@ -2496,6 +2503,18 @@ impl ScopeDef {
24962503

24972504
items
24982505
}
2506+
2507+
pub fn is_value_def(&self) -> bool {
2508+
matches!(
2509+
self,
2510+
ScopeDef::ModuleDef(ModuleDef::Function(_))
2511+
| ScopeDef::ModuleDef(ModuleDef::Variant(_))
2512+
| ScopeDef::ModuleDef(ModuleDef::Const(_))
2513+
| ScopeDef::ModuleDef(ModuleDef::Static(_))
2514+
| ScopeDef::GenericParam(GenericParam::ConstParam(_))
2515+
| ScopeDef::Local(_)
2516+
)
2517+
}
24992518
}
25002519

25012520
impl From<ItemInNs> for ScopeDef {

crates/hir/src/semantics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ pub enum PathResolution {
3535
Def(ModuleDef),
3636
/// A local binding (only value namespace)
3737
Local(Local),
38-
/// A generic parameter
38+
/// A type parameter
3939
TypeParam(TypeParam),
40+
/// A const parameter
4041
ConstParam(ConstParam),
4142
SelfType(Impl),
4243
Macro(MacroDef),

crates/ide_completion/src/completions.rs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,16 @@ impl Builder {
5656
}
5757

5858
impl Completions {
59-
pub(crate) fn add(&mut self, item: CompletionItem) {
59+
fn add(&mut self, item: CompletionItem) {
6060
self.buf.push(item)
6161
}
6262

63+
fn add_opt(&mut self, item: Option<CompletionItem>) {
64+
if let Some(item) = item {
65+
self.buf.push(item)
66+
}
67+
}
68+
6369
pub(crate) fn add_all<I>(&mut self, items: I)
6470
where
6571
I: IntoIterator,
@@ -103,9 +109,10 @@ impl Completions {
103109
local_name: hir::Name,
104110
resolution: &hir::ScopeDef,
105111
) {
106-
if let Some(item) = render_resolution(RenderContext::new(ctx), local_name, resolution) {
107-
self.add(item);
112+
if ctx.expects_type() && resolution.is_value_def() {
113+
return;
108114
}
115+
self.add_opt(render_resolution(RenderContext::new(ctx), local_name, resolution));
109116
}
110117

111118
pub(crate) fn add_macro(
@@ -118,9 +125,7 @@ impl Completions {
118125
Some(it) => it,
119126
None => return,
120127
};
121-
if let Some(item) = render_macro(RenderContext::new(ctx), None, name, macro_) {
122-
self.add(item);
123-
}
128+
self.add_opt(render_macro(RenderContext::new(ctx), None, name, macro_));
124129
}
125130

126131
pub(crate) fn add_function(
@@ -129,9 +134,10 @@ impl Completions {
129134
func: hir::Function,
130135
local_name: Option<hir::Name>,
131136
) {
132-
if let Some(item) = render_fn(RenderContext::new(ctx), None, local_name, func) {
133-
self.add(item)
137+
if ctx.expects_type() {
138+
return;
134139
}
140+
self.add_opt(render_fn(RenderContext::new(ctx), None, local_name, func));
135141
}
136142

137143
pub(crate) fn add_method(
@@ -141,10 +147,7 @@ impl Completions {
141147
receiver: Option<hir::Name>,
142148
local_name: Option<hir::Name>,
143149
) {
144-
if let Some(item) = render_method(RenderContext::new(ctx), None, receiver, local_name, func)
145-
{
146-
self.add(item)
147-
}
150+
self.add_opt(render_method(RenderContext::new(ctx), None, receiver, local_name, func));
148151
}
149152

150153
pub(crate) fn add_variant_pat(
@@ -153,9 +156,7 @@ impl Completions {
153156
variant: hir::Variant,
154157
local_name: Option<hir::Name>,
155158
) {
156-
if let Some(item) = render_variant_pat(RenderContext::new(ctx), variant, local_name, None) {
157-
self.add(item);
158-
}
159+
self.add_opt(render_variant_pat(RenderContext::new(ctx), variant, local_name, None));
159160
}
160161

161162
pub(crate) fn add_qualified_variant_pat(
@@ -164,9 +165,7 @@ impl Completions {
164165
variant: hir::Variant,
165166
path: hir::ModPath,
166167
) {
167-
if let Some(item) = render_variant_pat(RenderContext::new(ctx), variant, None, Some(path)) {
168-
self.add(item);
169-
}
168+
self.add_opt(render_variant_pat(RenderContext::new(ctx), variant, None, Some(path)));
170169
}
171170

172171
pub(crate) fn add_struct_pat(
@@ -175,21 +174,18 @@ impl Completions {
175174
strukt: hir::Struct,
176175
local_name: Option<hir::Name>,
177176
) {
178-
if let Some(item) = render_struct_pat(RenderContext::new(ctx), strukt, local_name) {
179-
self.add(item);
180-
}
177+
self.add_opt(render_struct_pat(RenderContext::new(ctx), strukt, local_name));
181178
}
182179

183180
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
184-
if let Some(item) = render_const(RenderContext::new(ctx), constant) {
185-
self.add(item);
181+
if ctx.expects_type() {
182+
return;
186183
}
184+
self.add_opt(render_const(RenderContext::new(ctx), constant));
187185
}
188186

189187
pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir::TypeAlias) {
190-
if let Some(item) = render_type_alias(RenderContext::new(ctx), type_alias) {
191-
self.add(item)
192-
}
188+
self.add_opt(render_type_alias(RenderContext::new(ctx), type_alias));
193189
}
194190

195191
pub(crate) fn add_qualified_enum_variant(
@@ -208,6 +204,9 @@ impl Completions {
208204
variant: hir::Variant,
209205
local_name: Option<hir::Name>,
210206
) {
207+
if ctx.expects_type() {
208+
return;
209+
}
211210
let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None);
212211
self.add(item);
213212
}

crates/ide_completion/src/completions/attribute.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib
6969
}
7070

7171
if is_inner || !attr_completion.prefer_inner {
72-
acc.add(item.build());
72+
item.add_to(acc);
7373
}
7474
};
7575

@@ -96,7 +96,7 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib
9696
if let Some(docs) = mac.docs(ctx.sema.db) {
9797
item.documentation(docs);
9898
}
99-
acc.add(item.build());
99+
item.add_to(acc);
100100
}
101101
}
102102
});

crates/ide_completion/src/completions/flyimport.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090
//! Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding
9191
//! capability enabled.
9292
93-
use hir::ModPath;
9493
use ide_db::helpers::{
9594
import_assets::{ImportAssets, ImportCandidate},
9695
insert_use::ImportScope,
@@ -208,7 +207,7 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
208207
}
209208

210209
fn compute_fuzzy_completion_order_key(
211-
proposed_mod_path: &ModPath,
210+
proposed_mod_path: &hir::ModPath,
212211
user_input_lowercased: &str,
213212
) -> usize {
214213
cov_mark::hit!(certain_fuzzy_order_test);

crates/ide_completion/src/completions/pattern.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
3939
| hir::ModuleDef::Module(..) => refutable,
4040
_ => false,
4141
},
42-
hir::ScopeDef::MacroDef(_) => true,
42+
hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
4343
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
4444
Some(hir::Adt::Struct(strukt)) => {
4545
acc.add_struct_pat(ctx, strukt, Some(name.clone()));
@@ -101,6 +101,28 @@ fn foo() {
101101
);
102102
}
103103

104+
#[test]
105+
fn does_not_complete_non_fn_macros() {
106+
check(
107+
r#"
108+
macro_rules! m { ($e:expr) => { $e } }
109+
enum E { X }
110+
111+
#[rustc_builtin_macro]
112+
macro Clone {}
113+
114+
fn 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+
104126
#[test]
105127
fn completes_in_simple_macro_call() {
106128
check(

crates/ide_completion/src/completions/qualified_path.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
2626
let module_scope = module.scope(ctx.db, context_module);
2727
for (name, def) in module_scope {
2828
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+
}
3032
}
3133
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
3234
acc.add_resolution(ctx, name, &def);
@@ -58,6 +60,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
5860
}
5961
}
6062

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+
6170
acc.add_resolution(ctx, name, &def);
6271
}
6372
}
@@ -198,6 +207,36 @@ mod tests {
198207
check(r#"use self::foo$0;"#, expect![[""]]);
199208
}
200209

210+
#[test]
211+
fn dont_complete_values_in_type_pos() {
212+
check(
213+
r#"
214+
const FOO: () = ();
215+
static BAR: () = ();
216+
struct Baz;
217+
fn foo() {
218+
let _: self::$0;
219+
}
220+
"#,
221+
expect![[r#"
222+
st Baz
223+
"#]],
224+
);
225+
}
226+
227+
#[test]
228+
fn dont_complete_enum_variants_in_type_pos() {
229+
check(
230+
r#"
231+
enum Foo { Bar }
232+
fn foo() {
233+
let _: Foo::$0;
234+
}
235+
"#,
236+
expect![[r#""#]],
237+
);
238+
}
239+
201240
#[test]
202241
fn dont_complete_current_use_in_braces_with_glob() {
203242
check(

0 commit comments

Comments
 (0)