mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Auto merge of #13092 - Veykril:ref-match-completion, r=Veykril
fix: Fix reference autocompletions using incorrect offsets in macro inputs Fixes https://github.com/rust-lang/rust-analyzer/issues/13035
This commit is contained in:
commit
631ed2a518
@ -64,8 +64,11 @@ pub(crate) struct PathCompletionCtx {
|
|||||||
pub(super) qualified: Qualified,
|
pub(super) qualified: Qualified,
|
||||||
/// The parent of the path we are completing.
|
/// The parent of the path we are completing.
|
||||||
pub(super) parent: Option<ast::Path>,
|
pub(super) parent: Option<ast::Path>,
|
||||||
|
#[allow(dead_code)]
|
||||||
/// The path of which we are completing the segment
|
/// The path of which we are completing the segment
|
||||||
pub(super) path: ast::Path,
|
pub(super) path: ast::Path,
|
||||||
|
/// The path of which we are completing the segment in the original file
|
||||||
|
pub(crate) original_path: Option<ast::Path>,
|
||||||
pub(super) kind: PathKind,
|
pub(super) kind: PathKind,
|
||||||
/// Whether the path segment has type args or not.
|
/// Whether the path segment has type args or not.
|
||||||
pub(super) has_type_args: bool,
|
pub(super) has_type_args: bool,
|
||||||
|
@ -588,12 +588,15 @@ impl<'a> CompletionContext<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let path = segment.parent_path();
|
let path = segment.parent_path();
|
||||||
|
let original_path = find_node_in_file_compensated(sema, original_file, &path);
|
||||||
|
|
||||||
let mut path_ctx = PathCompletionCtx {
|
let mut path_ctx = PathCompletionCtx {
|
||||||
has_call_parens: false,
|
has_call_parens: false,
|
||||||
has_macro_bang: false,
|
has_macro_bang: false,
|
||||||
qualified: Qualified::No,
|
qualified: Qualified::No,
|
||||||
parent: None,
|
parent: None,
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
|
original_path,
|
||||||
kind: PathKind::Item { kind: ItemListKind::SourceFile },
|
kind: PathKind::Item { kind: ItemListKind::SourceFile },
|
||||||
has_type_args: false,
|
has_type_args: false,
|
||||||
use_tree_parent: false,
|
use_tree_parent: false,
|
||||||
|
@ -323,9 +323,7 @@ fn render_resolution_path(
|
|||||||
..CompletionRelevance::default()
|
..CompletionRelevance::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref_match) = compute_ref_match(completion, &ty) {
|
path_ref_match(completion, path_ctx, &ty, &mut item);
|
||||||
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
@ -453,6 +451,29 @@ fn compute_ref_match(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn path_ref_match(
|
||||||
|
completion: &CompletionContext<'_>,
|
||||||
|
path_ctx: &PathCompletionCtx,
|
||||||
|
ty: &hir::Type,
|
||||||
|
item: &mut Builder,
|
||||||
|
) {
|
||||||
|
if let Some(original_path) = &path_ctx.original_path {
|
||||||
|
// At least one char was typed by the user already, in that case look for the original path
|
||||||
|
if let Some(original_path) = completion.sema.original_ast_node(original_path.clone()) {
|
||||||
|
if let Some(ref_match) = compute_ref_match(completion, ty) {
|
||||||
|
item.ref_match(ref_match, original_path.syntax().text_range().start());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// completion requested on an empty identifier, there is no path here yet.
|
||||||
|
// FIXME: This might create inconsistent completions where we show a ref match in macro inputs
|
||||||
|
// as long as nothing was typed yet
|
||||||
|
if let Some(ref_match) = compute_ref_match(completion, ty) {
|
||||||
|
item.ref_match(ref_match, completion.position.offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -79,18 +79,18 @@ fn render(
|
|||||||
..ctx.completion_relevance()
|
..ctx.completion_relevance()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
|
match func_kind {
|
||||||
match func_kind {
|
FuncKind::Function(path_ctx) => {
|
||||||
FuncKind::Function(path_ctx) => {
|
super::path_ref_match(completion, path_ctx, &ret_type, &mut item);
|
||||||
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
|
}
|
||||||
}
|
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
|
||||||
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
|
if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
|
||||||
if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
|
if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
|
||||||
item.ref_match(ref_match, original_expr.syntax().text_range().start());
|
item.ref_match(ref_match, original_expr.syntax().text_range().start());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
item.set_documentation(ctx.docs(func))
|
item.set_documentation(ctx.docs(func))
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
|
use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
|
||||||
use ide_db::SymbolKind;
|
use ide_db::SymbolKind;
|
||||||
use syntax::AstNode;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::{CompletionContext, PathCompletionCtx, PathKind},
|
context::{CompletionContext, PathCompletionCtx, PathKind},
|
||||||
item::{Builder, CompletionItem},
|
item::{Builder, CompletionItem},
|
||||||
render::{
|
render::{
|
||||||
compute_ref_match, compute_type_match,
|
compute_type_match,
|
||||||
variant::{
|
variant::{
|
||||||
format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit,
|
format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit,
|
||||||
visible_fields, RenderedLiteral,
|
visible_fields, RenderedLiteral,
|
||||||
@ -125,9 +124,8 @@ fn render(
|
|||||||
type_match: compute_type_match(ctx.completion, &ty),
|
type_match: compute_type_match(ctx.completion, &ty),
|
||||||
..ctx.completion_relevance()
|
..ctx.completion_relevance()
|
||||||
});
|
});
|
||||||
if let Some(ref_match) = compute_ref_match(completion, &ty) {
|
|
||||||
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
|
super::path_ref_match(completion, path_ctx, &ty, &mut item);
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(import_to_add) = ctx.import_to_add {
|
if let Some(import_to_add) = ctx.import_to_add {
|
||||||
item.add_import(import_to_add);
|
item.add_import(import_to_add);
|
||||||
|
Loading…
Reference in New Issue
Block a user