mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Prioritize locals with correct types
This commit is contained in:
parent
f1587ac263
commit
90c62bcee9
2 changed files with 55 additions and 5 deletions
|
@ -34,7 +34,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||
pub(super) record_pat_syntax: Option<ast::RecordPat>,
|
||||
pub(super) record_field_syntax: Option<ast::RecordField>,
|
||||
pub(super) impl_def: Option<ast::ImplDef>,
|
||||
/// FIXME: `ActiveParameter` is string-based, which is very wrong
|
||||
/// FIXME: `ActiveParameter` is string-based, which is very very wrong
|
||||
pub(super) active_parameter: Option<ActiveParameter>,
|
||||
pub(super) is_param: bool,
|
||||
/// If a name-binding or reference to a const in a pattern.
|
||||
|
|
|
@ -17,12 +17,11 @@ use crate::{
|
|||
impl Completions {
|
||||
pub(crate) fn add_field(&mut self, ctx: &CompletionContext, field: hir::Field, ty: &Type) {
|
||||
let is_deprecated = is_deprecated(field, ctx.db);
|
||||
let ty = ty.display(ctx.db).to_string();
|
||||
let name = field.name(ctx.db);
|
||||
let mut completion_item =
|
||||
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
|
||||
.kind(CompletionItemKind::Field)
|
||||
.detail(ty.clone())
|
||||
.detail(ty.display(ctx.db).to_string())
|
||||
.set_documentation(field.docs(ctx.db))
|
||||
.set_deprecated(is_deprecated);
|
||||
|
||||
|
@ -107,6 +106,12 @@ impl Completions {
|
|||
}
|
||||
};
|
||||
|
||||
if let ScopeDef::Local(local) = resolution {
|
||||
if let Some(score) = compute_score(ctx, &local.ty(ctx.db), &local_name) {
|
||||
completion_item = completion_item.set_score(score);
|
||||
}
|
||||
}
|
||||
|
||||
// Add `<>` for generic types
|
||||
if ctx.is_path_type && !ctx.has_type_args && ctx.config.add_call_parenthesis {
|
||||
if let Some(cap) = ctx.config.snippet_cap {
|
||||
|
@ -319,10 +324,11 @@ impl Completions {
|
|||
|
||||
pub(crate) fn compute_score(
|
||||
ctx: &CompletionContext,
|
||||
// FIXME: this definitely should be a `Type`
|
||||
ty: &str,
|
||||
ty: &Type,
|
||||
name: &str,
|
||||
) -> Option<CompletionScore> {
|
||||
// FIXME: this should not fall back to string equality.
|
||||
let ty = &ty.display(ctx.db).to_string();
|
||||
let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
|
||||
tested_by!(test_struct_field_completion_in_record_lit);
|
||||
let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?;
|
||||
|
@ -1405,4 +1411,48 @@ mod tests {
|
|||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prioritize_exact_ref_match() {
|
||||
assert_debug_snapshot!(
|
||||
do_reference_completion(
|
||||
r"
|
||||
struct WorldSnapshot { _f: () };
|
||||
fn go(world: &WorldSnapshot) {
|
||||
go(w<|>)
|
||||
}
|
||||
",
|
||||
),
|
||||
@r###"
|
||||
[
|
||||
CompletionItem {
|
||||
label: "WorldSnapshot",
|
||||
source_range: 132..133,
|
||||
delete: 132..133,
|
||||
insert: "WorldSnapshot",
|
||||
kind: Struct,
|
||||
},
|
||||
CompletionItem {
|
||||
label: "go(…)",
|
||||
source_range: 132..133,
|
||||
delete: 132..133,
|
||||
insert: "go(${1:world})$0",
|
||||
kind: Function,
|
||||
lookup: "go",
|
||||
detail: "fn go(world: &WorldSnapshot)",
|
||||
trigger_call_info: true,
|
||||
},
|
||||
CompletionItem {
|
||||
label: "world",
|
||||
source_range: 132..133,
|
||||
delete: 132..133,
|
||||
insert: "world",
|
||||
kind: Binding,
|
||||
detail: "&WorldSnapshot",
|
||||
score: TypeAndNameMatch,
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue