Skip to content

Commit 7a0fc46

Browse files
committed
Auto merge of rust-lang#18026 - Veykril:completions, r=Veykril
internal: Adjust completions scoring
2 parents fb38e4b + 3414a9e commit 7a0fc46

File tree

4 files changed

+125
-134
lines changed

4 files changed

+125
-134
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ fn add_function_impl_(
221221
let mut item = CompletionItem::new(completion_kind, replacement_range, label, ctx.edition);
222222
item.lookup_by(format!("{}fn {}", async_, fn_name.display(ctx.db, ctx.edition)))
223223
.set_documentation(func.docs(ctx.db))
224-
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
224+
.set_relevance(CompletionRelevance { exact_name_match: true, ..Default::default() });
225225

226226
if let Some(source) = ctx.sema.source(func) {
227227
if let Some(transformed_fn) =
@@ -366,7 +366,7 @@ fn add_type_alias_impl(
366366
CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label, ctx.edition);
367367
item.lookup_by(format!("type {alias_name}"))
368368
.set_documentation(type_alias.docs(ctx.db))
369-
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
369+
.set_relevance(CompletionRelevance { exact_name_match: true, ..Default::default() });
370370

371371
if let Some(source) = ctx.sema.source(type_alias) {
372372
let assoc_item = ast::AssocItem::TypeAlias(source.value);
@@ -440,7 +440,7 @@ fn add_const_impl(
440440
item.lookup_by(format_smolstr!("const {const_name}"))
441441
.set_documentation(const_.docs(ctx.db))
442442
.set_relevance(CompletionRelevance {
443-
is_item_from_trait: true,
443+
exact_name_match: true,
444444
..Default::default()
445445
});
446446
match ctx.config.snippet_cap {

src/tools/rust-analyzer/crates/ide-completion/src/item.rs

Lines changed: 86 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ use crate::{
1919
};
2020

2121
/// `CompletionItem` describes a single completion entity which expands to 1 or more entries in the
22-
/// editor pop-up. It is basically a POD with various properties. To construct a
23-
/// [`CompletionItem`], use [`Builder::new`] method and the [`Builder`] struct.
22+
/// editor pop-up.
23+
///
24+
/// It is basically a POD with various properties. To construct a [`CompletionItem`],
25+
/// use [`Builder::new`] method and the [`Builder`] struct.
2426
#[derive(Clone)]
2527
#[non_exhaustive]
2628
pub struct CompletionItem {
@@ -129,7 +131,8 @@ impl fmt::Debug for CompletionItem {
129131

130132
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
131133
pub struct CompletionRelevance {
132-
/// This is set in cases like these:
134+
/// This is set when the identifier being completed matches up with the name that is expected,
135+
/// like in a function argument.
133136
///
134137
/// ```
135138
/// fn f(spam: String) {}
@@ -139,9 +142,9 @@ pub struct CompletionRelevance {
139142
/// }
140143
/// ```
141144
pub exact_name_match: bool,
142-
/// See CompletionRelevanceTypeMatch doc comments for cases where this is set.
145+
/// See [`CompletionRelevanceTypeMatch`].
143146
pub type_match: Option<CompletionRelevanceTypeMatch>,
144-
/// This is set in cases like these:
147+
/// Set for local variables.
145148
///
146149
/// ```
147150
/// fn foo(a: u32) {
@@ -150,25 +153,26 @@ pub struct CompletionRelevance {
150153
/// }
151154
/// ```
152155
pub is_local: bool,
153-
/// This is set when trait items are completed in an impl of that trait.
154-
pub is_item_from_trait: bool,
155-
/// This is set for when trait items are from traits with `#[doc(notable_trait)]`
156-
pub is_item_from_notable_trait: bool,
157-
/// This is set when an import is suggested whose name is already imported.
156+
/// Populated when the completion item comes from a trait (impl).
157+
pub trait_: Option<CompletionRelevanceTraitInfo>,
158+
/// This is set when an import is suggested in a use item whose name is already imported.
158159
pub is_name_already_imported: bool,
159160
/// This is set for completions that will insert a `use` item.
160161
pub requires_import: bool,
161-
/// Set for method completions of the `core::ops` and `core::cmp` family.
162-
pub is_op_method: bool,
163162
/// Set for item completions that are private but in the workspace.
164163
pub is_private_editable: bool,
165164
/// Set for postfix snippet item completions
166165
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
167-
/// This is set for type inference results
168-
pub is_definite: bool,
169166
/// This is set for items that are function (associated or method)
170167
pub function: Option<CompletionRelevanceFn>,
171168
}
169+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
170+
pub struct CompletionRelevanceTraitInfo {
171+
/// The trait this item is from is a `#[doc(notable_trait)]`
172+
pub notable_trait: bool,
173+
/// Set for method completions of the `core::ops` and `core::cmp` family.
174+
pub is_op_method: bool,
175+
}
172176

173177
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
174178
pub enum CompletionRelevanceTypeMatch {
@@ -182,7 +186,7 @@ pub enum CompletionRelevanceTypeMatch {
182186
/// }
183187
/// ```
184188
CouldUnify,
185-
/// This is set in cases like these:
189+
/// This is set in cases where the type matches the expected type, like:
186190
///
187191
/// ```
188192
/// fn f(spam: String) {}
@@ -238,90 +242,82 @@ impl CompletionRelevance {
238242
/// See is_relevant if you need to make some judgement about score
239243
/// in an absolute sense.
240244
pub fn score(self) -> u32 {
241-
let mut score = 0;
245+
let mut score = !0 / 2;
242246
let CompletionRelevance {
243247
exact_name_match,
244248
type_match,
245249
is_local,
246-
is_item_from_trait,
247250
is_name_already_imported,
248251
requires_import,
249-
is_op_method,
250252
is_private_editable,
251253
postfix_match,
252-
is_definite,
253-
is_item_from_notable_trait,
254+
trait_,
254255
function,
255256
} = self;
256257

258+
// only applicable for completions within use items
259+
// lower rank for conflicting import names
260+
if is_name_already_imported {
261+
score -= 1;
262+
}
263+
// slightly prefer locals
264+
if is_local {
265+
score += 1;
266+
}
267+
257268
// lower rank private things
258269
if !is_private_editable {
259270
score += 1;
260271
}
261-
// lower rank trait op methods
262-
if !is_op_method {
263-
score += 10;
272+
273+
if let Some(trait_) = trait_ {
274+
// lower rank trait methods unless its notable
275+
if !trait_.notable_trait {
276+
score -= 5;
277+
}
278+
// lower rank trait op methods
279+
if trait_.is_op_method {
280+
score -= 5;
281+
}
264282
}
265-
// lower rank for conflicting import names
266-
if !is_name_already_imported {
267-
score += 1;
268-
}
269-
// lower rank for items that don't need an import
270-
if !requires_import {
271-
score += 1;
283+
// lower rank for items that need an import
284+
if requires_import {
285+
score -= 1;
272286
}
273287
if exact_name_match {
274-
score += 10;
288+
score += 20;
275289
}
276-
score += match postfix_match {
277-
Some(CompletionRelevancePostfixMatch::Exact) => 100,
278-
Some(CompletionRelevancePostfixMatch::NonExact) => 0,
279-
None => 3,
290+
match postfix_match {
291+
Some(CompletionRelevancePostfixMatch::Exact) => score += 100,
292+
Some(CompletionRelevancePostfixMatch::NonExact) => score -= 5,
293+
None => (),
280294
};
281295
score += match type_match {
282-
Some(CompletionRelevanceTypeMatch::Exact) => 8,
283-
Some(CompletionRelevanceTypeMatch::CouldUnify) => 3,
296+
Some(CompletionRelevanceTypeMatch::Exact) => 18,
297+
Some(CompletionRelevanceTypeMatch::CouldUnify) => 5,
284298
None => 0,
285299
};
286-
// slightly prefer locals
287-
if is_local {
288-
score += 1;
289-
}
290-
if is_item_from_trait {
291-
score += 1;
292-
}
293-
if is_item_from_notable_trait {
294-
score += 1;
295-
}
296-
if is_definite {
297-
score += 10;
298-
}
299-
300-
score += function
301-
.map(|asf| {
302-
let mut fn_score = match asf.return_type {
303-
CompletionRelevanceReturnType::DirectConstructor => 15,
304-
CompletionRelevanceReturnType::Builder => 10,
305-
CompletionRelevanceReturnType::Constructor => 5,
306-
CompletionRelevanceReturnType::Other => 0,
307-
};
308-
309-
// When a fn is bumped due to return type:
310-
// Bump Constructor or Builder methods with no arguments,
311-
// over them than with self arguments
312-
if fn_score > 0 {
313-
if !asf.has_params {
314-
// bump associated functions
315-
fn_score += 1;
316-
} else if asf.has_self_param {
317-
// downgrade methods (below Constructor)
318-
fn_score = 1;
319-
}
320-
}
300+
if let Some(function) = function {
301+
let mut fn_score = match function.return_type {
302+
CompletionRelevanceReturnType::DirectConstructor => 15,
303+
CompletionRelevanceReturnType::Builder => 10,
304+
CompletionRelevanceReturnType::Constructor => 5,
305+
CompletionRelevanceReturnType::Other => 0u32,
306+
};
307+
308+
// When a fn is bumped due to return type:
309+
// Bump Constructor or Builder methods with no arguments,
310+
// over them than with self arguments
311+
if function.has_params {
312+
// bump associated functions
313+
fn_score = fn_score.saturating_sub(1);
314+
} else if function.has_self_param {
315+
// downgrade methods (below Constructor)
316+
fn_score = fn_score.min(1);
317+
}
321318

322-
fn_score
323-
})
324-
.unwrap_or_default();
319+
score += fn_score;
320+
};
325321

326322
score
327323
}
@@ -701,8 +697,21 @@ mod tests {
701697
// that any items in the same vec have the same score.
702698
let expected_relevance_order = vec![
703699
vec![],
704-
vec![Cr { is_op_method: true, is_private_editable: true, ..default }],
705-
vec![Cr { is_op_method: true, ..default }],
700+
vec![Cr {
701+
trait_: Some(crate::item::CompletionRelevanceTraitInfo {
702+
notable_trait: false,
703+
is_op_method: true,
704+
}),
705+
is_private_editable: true,
706+
..default
707+
}],
708+
vec![Cr {
709+
trait_: Some(crate::item::CompletionRelevanceTraitInfo {
710+
notable_trait: false,
711+
is_op_method: true,
712+
}),
713+
..default
714+
}],
706715
vec![Cr { postfix_match: Some(CompletionRelevancePostfixMatch::NonExact), ..default }],
707716
vec![Cr { is_private_editable: true, ..default }],
708717
vec![default],

0 commit comments

Comments
 (0)