Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/render/function.rs')
-rw-r--r--crates/ide-completion/src/render/function.rs59
1 files changed, 52 insertions, 7 deletions
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index 27186a2b7f..32075baef5 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -8,8 +8,13 @@ use syntax::{format_smolstr, AstNode, SmolStr};
use crate::{
context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind},
- item::{Builder, CompletionItem, CompletionItemKind, CompletionRelevance},
- render::{compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext},
+ item::{
+ Builder, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevanceFn,
+ CompletionRelevanceReturnType,
+ },
+ render::{
+ compute_exact_name_match, compute_ref_match, compute_type_match, match_types, RenderContext,
+ },
CallableSnippets,
};
@@ -99,13 +104,20 @@ fn render(
.filter(|_| !has_call_parens)
.and_then(|cap| Some((cap, params(ctx.completion, func, &func_kind, has_dot_receiver)?)));
+ let type_match = if has_call_parens || complete_call_parens.is_some() {
+ compute_type_match(completion, &ret_type)
+ } else {
+ compute_type_match(completion, &func.ty(db))
+ };
+
+ let function = assoc_item
+ .and_then(|assoc_item| assoc_item.implementing_ty(db))
+ .and_then(|self_type| compute_function_match(db, &ctx, self_type, func, &ret_type));
+
item.set_relevance(CompletionRelevance {
- type_match: if has_call_parens || complete_call_parens.is_some() {
- compute_type_match(completion, &ret_type)
- } else {
- compute_type_match(completion, &func.ty(db))
- },
+ type_match,
exact_name_match: compute_exact_name_match(completion, &call),
+ function,
is_op_method,
is_item_from_notable_trait,
..ctx.completion_relevance()
@@ -156,6 +168,39 @@ fn render(
item
}
+fn compute_function_match(
+ db: &dyn HirDatabase,
+ ctx: &RenderContext<'_>,
+ self_type: hir::Type,
+ func: hir::Function,
+ func_return_type: &hir::Type,
+) -> Option<CompletionRelevanceFn> {
+ let has_args = func.num_params(db) > 0;
+ let has_self_arg = func.self_param(db).is_some();
+
+ let return_type = if match_types(ctx.completion, &self_type, &func_return_type).is_some() {
+ // fn([..]) -> Self
+ CompletionRelevanceReturnType::DirectConstructor
+ } else if func_return_type
+ .type_arguments()
+ .any(|ret_type_arg| match_types(ctx.completion, &self_type, &ret_type_arg).is_some())
+ {
+ // fn([..]) -> Result<Self, E> OR Wrapped<Foo, Self>
+ CompletionRelevanceReturnType::Constructor
+ } else if func_return_type
+ .as_adt()
+ .and_then(|adt| adt.name(db).as_str().map(|name| name.ends_with("Builder")))
+ .unwrap_or(false)
+ {
+ // fn([..]) -> [..]Builder
+ CompletionRelevanceReturnType::Builder
+ } else {
+ CompletionRelevanceReturnType::Other
+ };
+
+ Some(CompletionRelevanceFn { return_type, has_args, has_self_arg })
+}
+
pub(super) fn add_call_parens<'b>(
builder: &'b mut Builder,
ctx: &CompletionContext<'_>,