Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6fc5c3c

Browse files
committed
Auto merge of rust-lang#12604 - Veykril:completions, r=Veykril
internal: Simplify some completions
2 parents 312ac83 + 7a0774d commit 6fc5c3c

File tree

11 files changed

+146
-221
lines changed

11 files changed

+146
-221
lines changed

crates/hir/src/semantics.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
mod source_to_def;
44

5-
use std::{cell::RefCell, fmt, iter};
5+
use std::{cell::RefCell, fmt, iter, ops};
66

77
use base_db::{FileId, FileRange};
88
use hir_def::{
@@ -1449,3 +1449,11 @@ impl<'a> SemanticsScope<'a> {
14491449
}
14501450

14511451
pub struct VisibleTraits(pub FxHashSet<TraitId>);
1452+
1453+
impl ops::Deref for VisibleTraits {
1454+
type Target = FxHashSet<TraitId>;
1455+
1456+
fn deref(&self) -> &Self::Target {
1457+
&self.0
1458+
}
1459+
}

crates/ide-completion/src/completions.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::{
3636
const_::render_const,
3737
function::{render_fn, render_method},
3838
literal::{render_struct_literal, render_variant_lit},
39-
macro_::{render_macro, render_macro_pat},
39+
macro_::render_macro,
4040
pattern::{render_struct_pat, render_variant_pat},
4141
render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
4242
type_alias::{render_type_alias, render_type_alias_with_eq},
@@ -101,15 +101,15 @@ impl Completions {
101101
pub(crate) fn add_keyword_snippet_expr(
102102
&mut self,
103103
ctx: &CompletionContext,
104+
incomplete_let: bool,
104105
kw: &str,
105106
snippet: &str,
106-
incomplete_let: bool,
107107
) {
108108
let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
109109

110110
match ctx.config.snippet_cap {
111111
Some(cap) => {
112-
if snippet.ends_with('}') && incomplete_let {
112+
if incomplete_let && snippet.ends_with('}') {
113113
// complete block expression snippets with a trailing semicolon, if inside an incomplete let
114114
cov_mark::hit!(let_semi);
115115
item.insert_snippet(cap, format!("{};", snippet));
@@ -181,6 +181,17 @@ impl Completions {
181181
);
182182
}
183183

184+
pub(crate) fn add_enum_variants(
185+
&mut self,
186+
ctx: &CompletionContext,
187+
path_ctx: &PathCompletionCtx,
188+
e: hir::Enum,
189+
) {
190+
e.variants(ctx.db)
191+
.into_iter()
192+
.for_each(|variant| self.add_enum_variant(ctx, path_ctx, variant, None));
193+
}
194+
184195
pub(crate) fn add_module(
185196
&mut self,
186197
ctx: &CompletionContext,
@@ -219,29 +230,6 @@ impl Completions {
219230
);
220231
}
221232

222-
pub(crate) fn add_macro_pat(
223-
&mut self,
224-
ctx: &CompletionContext,
225-
pattern_ctx: &PatternContext,
226-
mac: hir::Macro,
227-
local_name: hir::Name,
228-
) {
229-
let is_private_editable = match ctx.is_visible(&mac) {
230-
Visible::Yes => false,
231-
Visible::Editable => true,
232-
Visible::No => return,
233-
};
234-
self.add(
235-
render_macro_pat(
236-
RenderContext::new(ctx).private_editable(is_private_editable),
237-
pattern_ctx,
238-
local_name,
239-
mac,
240-
)
241-
.build(),
242-
);
243-
}
244-
245233
pub(crate) fn add_function(
246234
&mut self,
247235
ctx: &CompletionContext,

crates/ide-completion/src/completions/dot.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ fn complete_methods(
121121
receiver.iterate_method_candidates(
122122
ctx.db,
123123
&ctx.scope,
124-
&ctx.traits_in_scope().0,
124+
&ctx.traits_in_scope(),
125125
Some(ctx.module),
126126
None,
127127
|func| {

crates/ide-completion/src/completions/expr.rs

Lines changed: 30 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Completion of names from the current scope in expression position.
22
33
use hir::ScopeDef;
4-
use ide_db::FxHashSet;
54

65
use crate::{
76
context::{ExprCtx, PathCompletionCtx, Qualified},
@@ -33,24 +32,24 @@ pub(crate) fn complete_expr_path(
3332
let wants_mut_token =
3433
ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false);
3534

36-
let scope_def_applicable = |def| {
37-
match def {
38-
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) => {
39-
false
40-
}
41-
// Don't suggest attribute macros and derives.
42-
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
43-
_ => true,
44-
}
35+
let scope_def_applicable = |def| match def {
36+
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) => false,
37+
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
38+
_ => true,
39+
};
40+
41+
let add_assoc_item = |acc: &mut Completions, item| match item {
42+
hir::AssocItem::Function(func) => acc.add_function(ctx, path_ctx, func, None),
43+
hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
44+
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
4545
};
4646

4747
match qualified {
4848
Qualified::Infer => ctx
4949
.traits_in_scope()
50-
.0
51-
.into_iter()
52-
.flat_map(|it| hir::Trait::from(it).items(ctx.sema.db))
53-
.for_each(|item| add_assoc_item(acc, ctx, path_ctx, item)),
50+
.iter()
51+
.flat_map(|&it| hir::Trait::from(it).items(ctx.sema.db))
52+
.for_each(|item| add_assoc_item(acc, item)),
5453
Qualified::With { resolution: None, .. } => {}
5554
Qualified::With { resolution: Some(resolution), .. } => {
5655
// Add associated types on type parameters and `Self`.
@@ -67,46 +66,32 @@ pub(crate) fn complete_expr_path(
6766
}
6867
}
6968
}
70-
7169
hir::PathResolution::Def(
7270
def @ (hir::ModuleDef::Adt(_)
7371
| hir::ModuleDef::TypeAlias(_)
7472
| hir::ModuleDef::BuiltinType(_)),
7573
) => {
76-
if let &hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
77-
add_enum_variants(acc, ctx, path_ctx, e);
78-
}
7974
let ty = match def {
8075
hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
81-
hir::ModuleDef::TypeAlias(a) => {
82-
let ty = a.ty(ctx.db);
83-
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
84-
cov_mark::hit!(completes_variant_through_alias);
85-
add_enum_variants(acc, ctx, path_ctx, e);
86-
}
87-
ty
88-
}
76+
hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
8977
hir::ModuleDef::BuiltinType(builtin) => {
9078
cov_mark::hit!(completes_primitive_assoc_const);
9179
builtin.ty(ctx.db)
9280
}
93-
_ => unreachable!(),
81+
_ => return,
9482
};
9583

84+
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
85+
cov_mark::hit!(completes_variant_through_alias);
86+
acc.add_enum_variants(ctx, path_ctx, e);
87+
}
88+
9689
// XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
9790
// (where AssocType is defined on a trait, not an inherent impl)
9891

99-
ty.iterate_path_candidates(
100-
ctx.db,
101-
&ctx.scope,
102-
&ctx.traits_in_scope().0,
103-
Some(ctx.module),
104-
None,
105-
|item| {
106-
add_assoc_item(acc, ctx, path_ctx, item);
107-
None::<()>
108-
},
109-
);
92+
ctx.iterate_path_candidates(&ty, |item| {
93+
add_assoc_item(acc, item);
94+
});
11095

11196
// Iterate assoc types separately
11297
ty.iterate_assoc_items(ctx.db, ctx.krate, |item| {
@@ -119,7 +104,7 @@ pub(crate) fn complete_expr_path(
119104
hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
120105
// Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
121106
for item in t.items(ctx.db) {
122-
add_assoc_item(acc, ctx, path_ctx, item);
107+
add_assoc_item(acc, item);
123108
}
124109
}
125110
hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
@@ -130,24 +115,12 @@ pub(crate) fn complete_expr_path(
130115
};
131116

132117
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
133-
add_enum_variants(acc, ctx, path_ctx, e);
118+
acc.add_enum_variants(ctx, path_ctx, e);
134119
}
135-
let mut seen = FxHashSet::default();
136-
ty.iterate_path_candidates(
137-
ctx.db,
138-
&ctx.scope,
139-
&ctx.traits_in_scope().0,
140-
Some(ctx.module),
141-
None,
142-
|item| {
143-
// We might iterate candidates of a trait multiple times here, so deduplicate
144-
// them.
145-
if seen.insert(item) {
146-
add_assoc_item(acc, ctx, path_ctx, item);
147-
}
148-
None::<()>
149-
},
150-
);
120+
121+
ctx.iterate_path_candidates(&ty, |item| {
122+
add_assoc_item(acc, item);
123+
});
151124
}
152125
_ => (),
153126
}
@@ -212,7 +185,7 @@ pub(crate) fn complete_expr_path(
212185

213186
if is_func_update.is_none() {
214187
let mut add_keyword =
215-
|kw, snippet| acc.add_keyword_snippet_expr(ctx, kw, snippet, incomplete_let);
188+
|kw, snippet| acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet);
216189

217190
if !in_block_expr {
218191
add_keyword("unsafe", "unsafe {\n $0\n}");
@@ -265,27 +238,3 @@ pub(crate) fn complete_expr_path(
265238
}
266239
}
267240
}
268-
269-
fn add_assoc_item(
270-
acc: &mut Completions,
271-
ctx: &CompletionContext,
272-
path_ctx: &PathCompletionCtx,
273-
item: hir::AssocItem,
274-
) {
275-
match item {
276-
hir::AssocItem::Function(func) => acc.add_function(ctx, path_ctx, func, None),
277-
hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
278-
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
279-
}
280-
}
281-
282-
fn add_enum_variants(
283-
acc: &mut Completions,
284-
ctx: &CompletionContext,
285-
path_ctx: &PathCompletionCtx,
286-
e: hir::Enum,
287-
) {
288-
e.variants(ctx.db)
289-
.into_iter()
290-
.for_each(|variant| acc.add_enum_variant(ctx, path_ctx, variant, None));
291-
}

crates/ide-completion/src/completions/pattern.rs

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Completes constants and paths in unqualified patterns.
22
33
use hir::{db::DefDatabase, AssocItem, ScopeDef};
4-
use ide_db::FxHashSet;
54
use syntax::ast::Pat;
65

76
use crate::{
@@ -81,9 +80,7 @@ pub(crate) fn complete_pattern(
8180
hir::ModuleDef::Adt(hir::Adt::Enum(e)) => refutable || single_variant_enum(e),
8281
hir::ModuleDef::Const(..) => refutable,
8382
hir::ModuleDef::Module(..) => true,
84-
hir::ModuleDef::Macro(mac) if mac.is_fn_like(ctx.db) => {
85-
return acc.add_macro_pat(ctx, pattern_ctx, mac, name);
86-
}
83+
hir::ModuleDef::Macro(mac) => mac.is_fn_like(ctx.db),
8784
_ => false,
8885
},
8986
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
@@ -136,23 +133,14 @@ pub(crate) fn complete_pattern_path(
136133
}
137134
}
138135
}
139-
res @ (hir::PathResolution::TypeParam(_)
140-
| hir::PathResolution::SelfType(_)
141-
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Struct(_)))
142-
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Enum(_)))
143-
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Union(_)))
144-
| hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))) => {
136+
res => {
145137
let ty = match res {
146138
hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
147139
hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
148140
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Struct(s))) => {
149141
s.ty(ctx.db)
150142
}
151143
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Enum(e))) => {
152-
cov_mark::hit!(enum_plain_qualified_use_tree);
153-
e.variants(ctx.db).into_iter().for_each(|variant| {
154-
acc.add_enum_variant(ctx, path_ctx, variant, None)
155-
});
156144
e.ty(ctx.db)
157145
}
158146
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Union(u))) => {
@@ -162,41 +150,33 @@ pub(crate) fn complete_pattern_path(
162150
_ => return,
163151
};
164152

165-
let mut seen = FxHashSet::default();
166-
ty.iterate_path_candidates(
167-
ctx.db,
168-
&ctx.scope,
169-
&ctx.scope.visible_traits().0,
170-
Some(ctx.module),
171-
None,
172-
|item| {
173-
match item {
174-
AssocItem::TypeAlias(ta) => {
175-
// We might iterate candidates of a trait multiple times here, so deduplicate them.
176-
if seen.insert(item) {
177-
acc.add_type_alias(ctx, ta);
178-
}
179-
}
180-
AssocItem::Const(c) => {
181-
if seen.insert(item) {
182-
acc.add_const(ctx, c);
183-
}
184-
}
185-
_ => {}
186-
}
187-
None::<()>
188-
},
189-
);
153+
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
154+
cov_mark::hit!(enum_plain_qualified_use_tree);
155+
acc.add_enum_variants(ctx, path_ctx, e);
156+
}
157+
158+
ctx.iterate_path_candidates(&ty, |item| match item {
159+
AssocItem::TypeAlias(ta) => acc.add_type_alias(ctx, ta),
160+
AssocItem::Const(c) => acc.add_const(ctx, c),
161+
_ => {}
162+
});
190163
}
191-
_ => {}
192164
}
193165
}
194-
// qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
195166
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
196167
Qualified::No => {
168+
// this will only be hit if there are brackets or braces, otherwise this will be parsed as an ident pattern
197169
ctx.process_all_names(&mut |name, res| {
198-
// FIXME: properly filter here
199-
if let ScopeDef::ModuleDef(_) = res {
170+
// FIXME: we should check what kind of pattern we are in and filter accordingly
171+
let add_completion = match res {
172+
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
173+
ScopeDef::ModuleDef(hir::ModuleDef::Adt(_)) => true,
174+
ScopeDef::ModuleDef(hir::ModuleDef::Variant(_)) => true,
175+
ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true,
176+
ScopeDef::ImplSelfType(_) => true,
177+
_ => false,
178+
};
179+
if add_completion {
200180
acc.add_path_resolution(ctx, path_ctx, name, res);
201181
}
202182
});

0 commit comments

Comments
 (0)