Skip to content

Commit 24e6a9f

Browse files
committed
completion relevance distinguish between exact type match and could unify
1 parent 546f8bc commit 24e6a9f

File tree

4 files changed

+58
-35
lines changed

4 files changed

+58
-35
lines changed

crates/ide_completion/src/item.rs

+28-19
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl fmt::Debug for CompletionItem {
122122
}
123123
}
124124

125-
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default)]
125+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
126126
pub struct CompletionRelevance {
127127
/// This is set in cases like these:
128128
///
@@ -143,24 +143,24 @@ pub struct CompletionRelevance {
143143
/// f($0) // type of local matches the type of param
144144
/// }
145145
/// ```
146-
pub exact_type_match: bool,
146+
pub type_match: Option<CompletionRelevanceTypeMatch>,
147147
/// This is set in cases like these:
148148
///
149149
/// ```
150-
/// fn foo(bar: u32) {
151-
/// $0 // `bar` is local
152-
/// }
153-
/// ```
154-
///
155-
/// ```
156-
/// fn foo() {
157-
/// let bar = 0;
158-
/// $0 // `bar` is local
150+
/// fn foo(a: u32) {
151+
/// let b = 0;
152+
/// $0 // `a` and `b` are local
159153
/// }
160154
/// ```
161155
pub is_local: bool,
162156
}
163157

158+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
159+
pub enum CompletionRelevanceTypeMatch {
160+
CouldUnify,
161+
Exact,
162+
}
163+
164164
impl CompletionRelevance {
165165
/// Provides a relevance score. Higher values are more relevant.
166166
///
@@ -177,9 +177,11 @@ impl CompletionRelevance {
177177
if self.exact_name_match {
178178
score += 1;
179179
}
180-
if self.exact_type_match {
181-
score += 3;
182-
}
180+
score += match self.type_match {
181+
Some(CompletionRelevanceTypeMatch::Exact) => 4,
182+
Some(CompletionRelevanceTypeMatch::CouldUnify) => 3,
183+
None => 0,
184+
};
183185
if self.is_local {
184186
score += 1;
185187
}
@@ -342,7 +344,7 @@ impl CompletionItem {
342344
// match, but with exact type match set because self.ref_match
343345
// is only set if there is an exact type match.
344346
let mut relevance = self.relevance;
345-
relevance.exact_type_match = true;
347+
relevance.type_match = Some(CompletionRelevanceTypeMatch::Exact);
346348

347349
self.ref_match.map(|mutability| (mutability, relevance))
348350
}
@@ -523,7 +525,7 @@ mod tests {
523525
use itertools::Itertools;
524526
use test_utils::assert_eq_text;
525527

526-
use super::CompletionRelevance;
528+
use super::{CompletionRelevance, CompletionRelevanceTypeMatch};
527529

528530
/// Check that these are CompletionRelevance are sorted in ascending order
529531
/// by their relevance score.
@@ -576,15 +578,22 @@ mod tests {
576578
is_local: true,
577579
..CompletionRelevance::default()
578580
}],
579-
vec![CompletionRelevance { exact_type_match: true, ..CompletionRelevance::default() }],
581+
vec![CompletionRelevance {
582+
type_match: Some(CompletionRelevanceTypeMatch::CouldUnify),
583+
..CompletionRelevance::default()
584+
}],
585+
vec![CompletionRelevance {
586+
type_match: Some(CompletionRelevanceTypeMatch::Exact),
587+
..CompletionRelevance::default()
588+
}],
580589
vec![CompletionRelevance {
581590
exact_name_match: true,
582-
exact_type_match: true,
591+
type_match: Some(CompletionRelevanceTypeMatch::Exact),
583592
..CompletionRelevance::default()
584593
}],
585594
vec![CompletionRelevance {
586595
exact_name_match: true,
587-
exact_type_match: true,
596+
type_match: Some(CompletionRelevanceTypeMatch::Exact),
588597
is_local: true,
589598
}],
590599
];

crates/ide_completion/src/render.rs

+28-14
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use ide_db::{
2020
use syntax::TextRange;
2121

2222
use crate::{
23-
item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
24-
CompletionRelevance,
23+
item::{CompletionRelevanceTypeMatch, ImportEdit},
24+
CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance,
2525
};
2626

2727
use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro};
@@ -143,7 +143,7 @@ impl<'a> Render<'a> {
143143
.set_deprecated(is_deprecated);
144144

145145
item.set_relevance(CompletionRelevance {
146-
exact_type_match: compute_exact_type_match(self.ctx.completion, ty),
146+
type_match: compute_exact_type_match(self.ctx.completion, ty),
147147
exact_name_match: compute_exact_name_match(self.ctx.completion, name.to_string()),
148148
..CompletionRelevance::default()
149149
});
@@ -243,7 +243,7 @@ impl<'a> Render<'a> {
243243
}
244244

245245
item.set_relevance(CompletionRelevance {
246-
exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
246+
type_match: compute_exact_type_match(self.ctx.completion, &ty),
247247
exact_name_match: compute_exact_name_match(self.ctx.completion, &local_name),
248248
is_local: true,
249249
..CompletionRelevance::default()
@@ -307,15 +307,24 @@ impl<'a> Render<'a> {
307307
}
308308
}
309309

310-
fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> bool {
311-
match ctx.expected_type.as_ref() {
312-
Some(expected_type) => {
313-
// We don't ever consider unit type to be an exact type match, since
314-
// nearly always this is not meaningful to the user.
315-
(completion_ty == expected_type || expected_type.could_unify_with(completion_ty))
316-
&& !expected_type.is_unit()
317-
}
318-
None => false,
310+
fn compute_exact_type_match(
311+
ctx: &CompletionContext,
312+
completion_ty: &hir::Type,
313+
) -> Option<CompletionRelevanceTypeMatch> {
314+
let expected_type = ctx.expected_type.as_ref()?;
315+
316+
// We don't ever consider unit type to be an exact type match, since
317+
// nearly always this is not meaningful to the user.
318+
if expected_type.is_unit() {
319+
return None;
320+
}
321+
322+
if completion_ty == expected_type {
323+
Some(CompletionRelevanceTypeMatch::Exact)
324+
} else if expected_type.could_unify_with(completion_ty) {
325+
Some(CompletionRelevanceTypeMatch::CouldUnify)
326+
} else {
327+
None
319328
}
320329
}
321330

@@ -347,6 +356,7 @@ mod tests {
347356
use itertools::Itertools;
348357

349358
use crate::{
359+
item::CompletionRelevanceTypeMatch,
350360
test_utils::{check_edit, do_completion, get_all_items, TEST_CONFIG},
351361
CompletionKind, CompletionRelevance,
352362
};
@@ -359,7 +369,11 @@ mod tests {
359369
fn check_relevance(ra_fixture: &str, expect: Expect) {
360370
fn display_relevance(relevance: CompletionRelevance) -> String {
361371
let relevance_factors = vec![
362-
(relevance.exact_type_match, "type"),
372+
(relevance.type_match == Some(CompletionRelevanceTypeMatch::Exact), "type"),
373+
(
374+
relevance.type_match == Some(CompletionRelevanceTypeMatch::CouldUnify),
375+
"type_could_unify",
376+
),
363377
(relevance.exact_name_match, "name"),
364378
(relevance.is_local, "local"),
365379
]

crates/ide_completion/src/render/enum_variant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl<'a> EnumRender<'a> {
7777

7878
let ty = self.variant.parent_enum(self.ctx.completion.db).ty(self.ctx.completion.db);
7979
item.set_relevance(CompletionRelevance {
80-
exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
80+
type_match: compute_exact_type_match(self.ctx.completion, &ty),
8181
..CompletionRelevance::default()
8282
});
8383

crates/ide_completion/src/render/function.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'a> FunctionRender<'a> {
6161

6262
let ret_type = self.func.ret_type(self.ctx.db());
6363
item.set_relevance(CompletionRelevance {
64-
exact_type_match: compute_exact_type_match(self.ctx.completion, &ret_type),
64+
type_match: compute_exact_type_match(self.ctx.completion, &ret_type),
6565
exact_name_match: compute_exact_name_match(self.ctx.completion, self.name.clone()),
6666
..CompletionRelevance::default()
6767
});

0 commit comments

Comments
 (0)