Skip to content

Commit 631ed2a

Browse files
committed
Auto merge of #13092 - Veykril:ref-match-completion, r=Veykril
fix: Fix reference autocompletions using incorrect offsets in macro inputs Fixes #13035
2 parents 6627b47 + 6c5d158 commit 631ed2a

File tree

5 files changed

+41
-16
lines changed

5 files changed

+41
-16
lines changed

crates/ide-completion/src/context.rs

+3
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ pub(crate) struct PathCompletionCtx {
6464
pub(super) qualified: Qualified,
6565
/// The parent of the path we are completing.
6666
pub(super) parent: Option<ast::Path>,
67+
#[allow(dead_code)]
6768
/// The path of which we are completing the segment
6869
pub(super) path: ast::Path,
70+
/// The path of which we are completing the segment in the original file
71+
pub(crate) original_path: Option<ast::Path>,
6972
pub(super) kind: PathKind,
7073
/// Whether the path segment has type args or not.
7174
pub(super) has_type_args: bool,

crates/ide-completion/src/context/analysis.rs

+3
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,15 @@ impl<'a> CompletionContext<'a> {
588588
};
589589

590590
let path = segment.parent_path();
591+
let original_path = find_node_in_file_compensated(sema, original_file, &path);
592+
591593
let mut path_ctx = PathCompletionCtx {
592594
has_call_parens: false,
593595
has_macro_bang: false,
594596
qualified: Qualified::No,
595597
parent: None,
596598
path: path.clone(),
599+
original_path,
597600
kind: PathKind::Item { kind: ItemListKind::SourceFile },
598601
has_type_args: false,
599602
use_tree_parent: false,

crates/ide-completion/src/render.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,7 @@ fn render_resolution_path(
323323
..CompletionRelevance::default()
324324
});
325325

326-
if let Some(ref_match) = compute_ref_match(completion, &ty) {
327-
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
328-
}
326+
path_ref_match(completion, path_ctx, &ty, &mut item);
329327
};
330328
item
331329
}
@@ -453,6 +451,29 @@ fn compute_ref_match(
453451
None
454452
}
455453

454+
fn path_ref_match(
455+
completion: &CompletionContext<'_>,
456+
path_ctx: &PathCompletionCtx,
457+
ty: &hir::Type,
458+
item: &mut Builder,
459+
) {
460+
if let Some(original_path) = &path_ctx.original_path {
461+
// At least one char was typed by the user already, in that case look for the original path
462+
if let Some(original_path) = completion.sema.original_ast_node(original_path.clone()) {
463+
if let Some(ref_match) = compute_ref_match(completion, ty) {
464+
item.ref_match(ref_match, original_path.syntax().text_range().start());
465+
}
466+
}
467+
} else {
468+
// completion requested on an empty identifier, there is no path here yet.
469+
// FIXME: This might create inconsistent completions where we show a ref match in macro inputs
470+
// as long as nothing was typed yet
471+
if let Some(ref_match) = compute_ref_match(completion, ty) {
472+
item.ref_match(ref_match, completion.position.offset);
473+
}
474+
}
475+
}
476+
456477
#[cfg(test)]
457478
mod tests {
458479
use std::cmp;

crates/ide-completion/src/render/function.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ fn render(
7979
..ctx.completion_relevance()
8080
});
8181

82-
if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
83-
match func_kind {
84-
FuncKind::Function(path_ctx) => {
85-
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
86-
}
87-
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
88-
if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
82+
match func_kind {
83+
FuncKind::Function(path_ctx) => {
84+
super::path_ref_match(completion, path_ctx, &ret_type, &mut item);
85+
}
86+
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
87+
if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
88+
if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
8989
item.ref_match(ref_match, original_expr.syntax().text_range().start());
9090
}
9191
}
92-
_ => (),
9392
}
93+
_ => (),
9494
}
9595

9696
item.set_documentation(ctx.docs(func))

crates/ide-completion/src/render/literal.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
33
use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
44
use ide_db::SymbolKind;
5-
use syntax::AstNode;
65

76
use crate::{
87
context::{CompletionContext, PathCompletionCtx, PathKind},
98
item::{Builder, CompletionItem},
109
render::{
11-
compute_ref_match, compute_type_match,
10+
compute_type_match,
1211
variant::{
1312
format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit,
1413
visible_fields, RenderedLiteral,
@@ -125,9 +124,8 @@ fn render(
125124
type_match: compute_type_match(ctx.completion, &ty),
126125
..ctx.completion_relevance()
127126
});
128-
if let Some(ref_match) = compute_ref_match(completion, &ty) {
129-
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
130-
}
127+
128+
super::path_ref_match(completion, path_ctx, &ty, &mut item);
131129

132130
if let Some(import_to_add) = ctx.import_to_add {
133131
item.add_import(import_to_add);

0 commit comments

Comments
 (0)