mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 19:53:46 +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,
|
||||
/// The parent of the path we are completing.
|
||||
pub(super) parent: Option<ast::Path>,
|
||||
#[allow(dead_code)]
|
||||
/// The path of which we are completing the segment
|
||||
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,
|
||||
/// Whether the path segment has type args or not.
|
||||
pub(super) has_type_args: bool,
|
||||
|
@ -588,12 +588,15 @@ impl<'a> CompletionContext<'a> {
|
||||
};
|
||||
|
||||
let path = segment.parent_path();
|
||||
let original_path = find_node_in_file_compensated(sema, original_file, &path);
|
||||
|
||||
let mut path_ctx = PathCompletionCtx {
|
||||
has_call_parens: false,
|
||||
has_macro_bang: false,
|
||||
qualified: Qualified::No,
|
||||
parent: None,
|
||||
path: path.clone(),
|
||||
original_path,
|
||||
kind: PathKind::Item { kind: ItemListKind::SourceFile },
|
||||
has_type_args: false,
|
||||
use_tree_parent: false,
|
||||
|
@ -323,9 +323,7 @@ fn render_resolution_path(
|
||||
..CompletionRelevance::default()
|
||||
});
|
||||
|
||||
if let Some(ref_match) = compute_ref_match(completion, &ty) {
|
||||
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
|
||||
}
|
||||
path_ref_match(completion, path_ctx, &ty, &mut item);
|
||||
};
|
||||
item
|
||||
}
|
||||
@ -453,6 +451,29 @@ fn compute_ref_match(
|
||||
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)]
|
||||
mod tests {
|
||||
use std::cmp;
|
||||
|
@ -79,18 +79,18 @@ fn render(
|
||||
..ctx.completion_relevance()
|
||||
});
|
||||
|
||||
if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
|
||||
match func_kind {
|
||||
FuncKind::Function(path_ctx) => {
|
||||
item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
|
||||
}
|
||||
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
|
||||
if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
|
||||
match func_kind {
|
||||
FuncKind::Function(path_ctx) => {
|
||||
super::path_ref_match(completion, path_ctx, &ret_type, &mut item);
|
||||
}
|
||||
FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
|
||||
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.set_documentation(ctx.docs(func))
|
||||
|
@ -2,13 +2,12 @@
|
||||
|
||||
use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
|
||||
use ide_db::SymbolKind;
|
||||
use syntax::AstNode;
|
||||
|
||||
use crate::{
|
||||
context::{CompletionContext, PathCompletionCtx, PathKind},
|
||||
item::{Builder, CompletionItem},
|
||||
render::{
|
||||
compute_ref_match, compute_type_match,
|
||||
compute_type_match,
|
||||
variant::{
|
||||
format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit,
|
||||
visible_fields, RenderedLiteral,
|
||||
@ -125,9 +124,8 @@ fn render(
|
||||
type_match: compute_type_match(ctx.completion, &ty),
|
||||
..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 {
|
||||
item.add_import(import_to_add);
|
||||
|
Loading…
Reference in New Issue
Block a user