Skip to content

Commit 3c4d642

Browse files
committed
Auto merge of #16117 - mustakimali:mo-order, r=Veykril
feat: completion list suggests constructor like & builder methods first When typing `MyType::` the completion items' order could be re-ordered based on how likely we want to select those: * Constructors: `new` like functions to be able to create the type, * Constructors that take args: Any other function that creates `Self`, * Builder Methods: any builder methods available, * Regular methods & associated functions (no change there) ![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/54593b91-07b3-455a-8a71-8d203d4eaf4a) In this photo, the order is: * `new` constructor is first * `new_builder` second is a builder method * `aaaanew` is a constructor that takes arguments, is third and is irrespective of its alphabetical order among names. --- Another Example using actix `HttpServer` shows preferring constructor without `self` arg first (the `new` method) ![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/938d3fb0-3d7a-4427-ae2f-ec02a834ccbe) ![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/2c13860c-efd1-459d-b25e-df8adb61bbd0) I've dropped my previous idea of highlighting these functions in the rustdoc (rust-lang/rust#107926)
2 parents e944a27 + 2c76104 commit 3c4d642

File tree

3 files changed

+438
-4
lines changed

3 files changed

+438
-4
lines changed

crates/ide-completion/src/item.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ pub struct CompletionRelevance {
166166
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
167167
/// This is set for type inference results
168168
pub is_definite: bool,
169+
/// This is set for items that are function (associated or method)
170+
pub function: Option<CompletionRelevanceFn>,
169171
}
170172

171173
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -207,6 +209,24 @@ pub enum CompletionRelevancePostfixMatch {
207209
Exact,
208210
}
209211

212+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
213+
pub struct CompletionRelevanceFn {
214+
pub has_params: bool,
215+
pub has_self_param: bool,
216+
pub return_type: CompletionRelevanceReturnType,
217+
}
218+
219+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
220+
pub enum CompletionRelevanceReturnType {
221+
Other,
222+
/// Returns the Self type of the impl/trait
223+
DirectConstructor,
224+
/// Returns something that indirectly constructs the `Self` type of the impl/trait e.g. `Result<Self, ()>`, `Option<Self>`
225+
Constructor,
226+
/// Returns a possible builder for the type
227+
Builder,
228+
}
229+
210230
impl CompletionRelevance {
211231
/// Provides a relevance score. Higher values are more relevant.
212232
///
@@ -231,6 +251,7 @@ impl CompletionRelevance {
231251
postfix_match,
232252
is_definite,
233253
is_item_from_notable_trait,
254+
function,
234255
} = self;
235256

236257
// lower rank private things
@@ -275,6 +296,33 @@ impl CompletionRelevance {
275296
if is_definite {
276297
score += 10;
277298
}
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 tha 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+
}
321+
322+
fn_score
323+
})
324+
.unwrap_or_default();
325+
278326
score
279327
}
280328

0 commit comments

Comments
 (0)