Skip to content

Commit 439a513

Browse files
committed
Auto merge of rust-lang#12597 - Veykril:completions, r=Veykril
fix: Fix auto-ref completions inserting into wrong locations Fixes rust-lang/rust-analyzer#8058
2 parents 9fdfa9f + 8b07898 commit 439a513

File tree

21 files changed

+352
-212
lines changed

21 files changed

+352
-212
lines changed

crates/ide-completion/src/completions.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ use crate::{
3636
const_::render_const,
3737
function::{render_fn, render_method},
3838
literal::{render_struct_literal, render_variant_lit},
39-
macro_::render_macro,
39+
macro_::{render_macro, render_macro_pat},
4040
pattern::{render_struct_pat, render_variant_pat},
41-
render_field, render_path_resolution, render_resolution_simple, render_tuple_field,
41+
render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
4242
type_alias::{render_type_alias, render_type_alias_with_eq},
4343
union_literal::render_union_literal,
4444
RenderContext,
@@ -134,10 +134,14 @@ impl Completions {
134134
item.add_to(self);
135135
}
136136

137-
pub(crate) fn add_crate_roots(&mut self, ctx: &CompletionContext) {
137+
pub(crate) fn add_crate_roots(
138+
&mut self,
139+
ctx: &CompletionContext,
140+
path_ctx: &PathCompletionCtx,
141+
) {
138142
ctx.process_all_names(&mut |name, res| match res {
139143
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
140-
self.add_module(ctx, m, name);
144+
self.add_module(ctx, path_ctx, m, name);
141145
}
142146
_ => (),
143147
});
@@ -160,25 +164,36 @@ impl Completions {
160164
);
161165
}
162166

163-
pub(crate) fn add_resolution_simple(
167+
pub(crate) fn add_pattern_resolution(
164168
&mut self,
165169
ctx: &CompletionContext,
170+
pattern_ctx: &PatternContext,
166171
local_name: hir::Name,
167172
resolution: hir::ScopeDef,
168173
) {
169174
if ctx.is_scope_def_hidden(resolution) {
175+
cov_mark::hit!(qualified_path_doc_hidden);
170176
return;
171177
}
172-
self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution).build());
178+
self.add(
179+
render_pattern_resolution(RenderContext::new(ctx), pattern_ctx, local_name, resolution)
180+
.build(),
181+
);
173182
}
174183

175184
pub(crate) fn add_module(
176185
&mut self,
177186
ctx: &CompletionContext,
187+
path_ctx: &PathCompletionCtx,
178188
module: hir::Module,
179189
local_name: hir::Name,
180190
) {
181-
self.add_resolution_simple(ctx, local_name, hir::ScopeDef::ModuleDef(module.into()));
191+
self.add_path_resolution(
192+
ctx,
193+
path_ctx,
194+
local_name,
195+
hir::ScopeDef::ModuleDef(module.into()),
196+
);
182197
}
183198

184199
pub(crate) fn add_macro(
@@ -204,6 +219,29 @@ impl Completions {
204219
);
205220
}
206221

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+
207245
pub(crate) fn add_function(
208246
&mut self,
209247
ctx: &CompletionContext,
@@ -341,6 +379,7 @@ impl Completions {
341379
pub(crate) fn add_field(
342380
&mut self,
343381
ctx: &CompletionContext,
382+
dot_access: &DotAccess,
344383
receiver: Option<hir::Name>,
345384
field: hir::Field,
346385
ty: &hir::Type,
@@ -352,6 +391,7 @@ impl Completions {
352391
};
353392
let item = render_field(
354393
RenderContext::new(ctx).private_editable(is_private_editable),
394+
dot_access,
355395
receiver,
356396
field,
357397
ty,

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,24 @@ pub(crate) fn complete_attribute_path(
9595
acc.add_macro(ctx, path_ctx, m, name)
9696
}
9797
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
98-
acc.add_module(ctx, m, name)
98+
acc.add_module(ctx, path_ctx, m, name)
9999
}
100100
_ => (),
101101
}
102102
}
103103
return;
104104
}
105105
// fresh use tree with leading colon2, only show crate roots
106-
Qualified::Absolute => acc.add_crate_roots(ctx),
106+
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
107107
// only show modules in a fresh UseTree
108108
Qualified::No => {
109109
ctx.process_all_names(&mut |name, def| match def {
110110
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(ctx.db) => {
111111
acc.add_macro(ctx, path_ctx, m, name)
112112
}
113-
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
113+
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
114+
acc.add_module(ctx, path_ctx, m, name)
115+
}
114116
_ => (),
115117
});
116118
acc.add_nameref_keywords_with_colon(ctx);

crates/ide-completion/src/completions/attribute/derive.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ pub(crate) fn complete_derive_path(
3535
{
3636
acc.add_macro(ctx, path_ctx, mac, name)
3737
}
38-
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
38+
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
39+
acc.add_module(ctx, path_ctx, m, name)
40+
}
3941
_ => (),
4042
}
4143
}
4244
}
43-
Qualified::Absolute => acc.add_crate_roots(ctx),
45+
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
4446
// only show modules in a fresh UseTree
4547
Qualified::No => {
4648
ctx.process_all_names(&mut |name, def| {
@@ -51,7 +53,7 @@ pub(crate) fn complete_derive_path(
5153
mac
5254
}
5355
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
54-
return acc.add_module(ctx, m, name);
56+
return acc.add_module(ctx, path_ctx, m, name);
5557
}
5658
_ => return,
5759
};

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext, dot_a
2929
acc,
3030
ctx,
3131
&receiver_ty,
32-
|acc, field, ty| acc.add_field(ctx, None, field, &ty),
32+
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
3333
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
3434
);
3535
}
@@ -64,7 +64,19 @@ pub(crate) fn complete_undotted_self(
6464
acc,
6565
ctx,
6666
&ty,
67-
|acc, field, ty| acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
67+
|acc, field, ty| {
68+
acc.add_field(
69+
ctx,
70+
&DotAccess {
71+
receiver: None,
72+
receiver_ty: None,
73+
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
74+
},
75+
Some(hir::known::SELF_PARAM),
76+
field,
77+
&ty,
78+
)
79+
},
6880
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
6981
);
7082
complete_methods(ctx, &ty, |func| {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(crate) fn complete_expr_path(
152152
_ => (),
153153
}
154154
}
155-
Qualified::Absolute => acc.add_crate_roots(ctx),
155+
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
156156
Qualified::No => {
157157
acc.add_nameref_keywords_with_colon(ctx);
158158
if let Some(adt) =

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

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
CompletionContext, DotAccess, PathCompletionCtx, PathKind, PatternContext, Qualified,
1313
TypeLocation,
1414
},
15-
render::{render_resolution_with_import, RenderContext},
15+
render::{render_resolution_with_import, render_resolution_with_import_pat, RenderContext},
1616
};
1717

1818
use super::Completions;
@@ -149,30 +149,22 @@ pub(crate) fn import_on_the_fly_path(
149149
pub(crate) fn import_on_the_fly_pat(
150150
acc: &mut Completions,
151151
ctx: &CompletionContext,
152-
pat_ctx: &PatternContext,
152+
pattern_ctx: &PatternContext,
153153
) -> Option<()> {
154154
if !ctx.config.enable_imports_on_the_fly {
155155
return None;
156156
}
157-
if let PatternContext { record_pat: Some(_), .. } = pat_ctx {
157+
if let PatternContext { record_pat: Some(_), .. } = pattern_ctx {
158158
return None;
159159
}
160160

161161
let potential_import_name = import_name(ctx);
162162
let import_assets = import_assets_for_path(ctx, &potential_import_name, None)?;
163163

164-
import_on_the_fly(
164+
import_on_the_fly_pat2(
165165
acc,
166166
ctx,
167-
&PathCompletionCtx {
168-
has_call_parens: false,
169-
has_macro_bang: false,
170-
qualified: Qualified::No,
171-
parent: None,
172-
kind: crate::context::PathKind::Pat { pat_ctx: pat_ctx.clone() },
173-
has_type_args: false,
174-
use_tree_parent: false,
175-
},
167+
pattern_ctx,
176168
import_assets,
177169
ctx.original_token.parent()?,
178170
potential_import_name,
@@ -287,6 +279,50 @@ fn import_on_the_fly(
287279
Some(())
288280
}
289281

282+
fn import_on_the_fly_pat2(
283+
acc: &mut Completions,
284+
ctx: &CompletionContext,
285+
pattern_ctx: &PatternContext,
286+
import_assets: ImportAssets,
287+
position: SyntaxNode,
288+
potential_import_name: String,
289+
) -> Option<()> {
290+
let _p = profile::span("import_on_the_fly_pat").detail(|| potential_import_name.clone());
291+
292+
if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
293+
return None;
294+
}
295+
296+
let ns_filter = |import: &LocatedImport| match import.original_item {
297+
ItemInNs::Macros(mac) => mac.is_fn_like(ctx.db),
298+
ItemInNs::Types(_) => true,
299+
ItemInNs::Values(def) => matches!(def, hir::ModuleDef::Const(_)),
300+
};
301+
let user_input_lowercased = potential_import_name.to_lowercase();
302+
303+
acc.add_all(
304+
import_assets
305+
.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
306+
.into_iter()
307+
.filter(ns_filter)
308+
.filter(|import| {
309+
!ctx.is_item_hidden(&import.item_to_import)
310+
&& !ctx.is_item_hidden(&import.original_item)
311+
})
312+
.sorted_by_key(|located_import| {
313+
compute_fuzzy_completion_order_key(
314+
&located_import.import_path,
315+
&user_input_lowercased,
316+
)
317+
})
318+
.filter_map(|import| {
319+
render_resolution_with_import_pat(RenderContext::new(ctx), pattern_ctx, import)
320+
})
321+
.map(|builder| builder.build()),
322+
);
323+
Some(())
324+
}
325+
290326
fn import_on_the_fly_method(
291327
acc: &mut Completions,
292328
ctx: &CompletionContext,
@@ -295,7 +331,7 @@ fn import_on_the_fly_method(
295331
position: SyntaxNode,
296332
potential_import_name: String,
297333
) -> Option<()> {
298-
let _p = profile::span("import_on_the_fly").detail(|| potential_import_name.clone());
334+
let _p = profile::span("import_on_the_fly_method").detail(|| potential_import_name.clone());
299335

300336
if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
301337
return None;

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub(crate) fn complete_item_list(
4545
acc.add_macro(ctx, path_ctx, m, name)
4646
}
4747
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
48-
acc.add_module(ctx, m, name)
48+
acc.add_module(ctx, path_ctx, m, name)
4949
}
5050
_ => (),
5151
}
@@ -55,13 +55,15 @@ pub(crate) fn complete_item_list(
5555
acc.add_keyword(ctx, "super::");
5656
}
5757
}
58-
Qualified::Absolute => acc.add_crate_roots(ctx),
58+
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
5959
Qualified::No if ctx.qualifier_ctx.none() => {
6060
ctx.process_all_names(&mut |name, def| match def {
6161
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => {
6262
acc.add_macro(ctx, path_ctx, m, name)
6363
}
64-
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
64+
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
65+
acc.add_module(ctx, path_ctx, m, name)
66+
}
6567
_ => (),
6668
});
6769
acc.add_nameref_keywords_with_colon(ctx);

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,7 @@ pub(crate) fn complete_pattern(
8282
hir::ModuleDef::Const(..) => refutable,
8383
hir::ModuleDef::Module(..) => true,
8484
hir::ModuleDef::Macro(mac) if mac.is_fn_like(ctx.db) => {
85-
return acc.add_macro(
86-
ctx,
87-
&PathCompletionCtx {
88-
has_call_parens: false,
89-
has_macro_bang: false,
90-
qualified: Qualified::No,
91-
parent: None,
92-
kind: crate::context::PathKind::Pat { pat_ctx: pattern_ctx.clone() },
93-
has_type_args: false,
94-
use_tree_parent: false,
95-
},
96-
mac,
97-
name,
98-
)
85+
return acc.add_macro_pat(ctx, pattern_ctx, mac, name);
9986
}
10087
_ => false,
10188
},
@@ -116,7 +103,7 @@ pub(crate) fn complete_pattern(
116103
| ScopeDef::Unknown => false,
117104
};
118105
if add_simple_path {
119-
acc.add_resolution_simple(ctx, name, res);
106+
acc.add_pattern_resolution(ctx, pattern_ctx, name, res);
120107
}
121108
});
122109
}
@@ -205,7 +192,7 @@ pub(crate) fn complete_pattern_path(
205192
}
206193
}
207194
// qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
208-
Qualified::Absolute => acc.add_crate_roots(ctx),
195+
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
209196
Qualified::No => {
210197
ctx.process_all_names(&mut |name, res| {
211198
// FIXME: properly filter here

0 commit comments

Comments
 (0)