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.rs55
1 files changed, 51 insertions, 4 deletions
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index dfae715afe..c2e06c926f 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -1,6 +1,6 @@
//! Renderer for function calls.
-use hir::{db::HirDatabase, AsAssocItem, HirDisplay};
+use hir::{db::HirDatabase, AsAssocItem, Callable, HirDisplay, Type};
use ide_db::{SnippetCap, SymbolKind};
use itertools::Itertools;
use stdx::{format_to, to_lower_snake_case};
@@ -8,8 +8,14 @@ use syntax::{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,
+ CompletionRelevanceTypeMatch,
+ },
+ render::{
+ compute_exact_name_match, compute_ref_match, compute_type_match, compute_type_match2,
+ RenderContext,
+ },
CallableSnippets,
};
@@ -62,6 +68,7 @@ fn render(
),
_ => (name.unescaped().to_smol_str(), name.to_smol_str()),
};
+
let mut item = CompletionItem::new(
if func.self_param(db).is_some() {
CompletionItemKind::Method
@@ -77,8 +84,48 @@ fn render(
.as_assoc_item(ctx.db())
.and_then(|trait_| trait_.containing_trait_or_trait_impl(ctx.db()))
.map_or(false, |trait_| completion.is_ops_trait(trait_));
+
+ // TODO next step figure out how to unify function typesk, we need to convert fndef to actual callable type
+
+ let type_match = if let Some(ref t) = completion.expected_type {
+ if let Some(t) = t.as_callable(db) {
+ let (mut param_types_exp, ret_type_exp) = (
+ t.params(db).into_iter().map(|(_, ty)| ty).collect::<Vec<Type>>(),
+ t.return_type(),
+ );
+
+ param_types_exp.push(ret_type_exp);
+
+ let mut param_types = func
+ .ty(db)
+ .as_callable(db)
+ .unwrap()
+ .params(db)
+ .into_iter()
+ .map(|(_, ty)| ty)
+ .collect::<Vec<Type>>();
+ param_types.push(ret_type.clone());
+
+ if param_types.len() != param_types_exp.len() {
+ None
+ } else {
+ if param_types_exp.iter().zip(param_types).all(|(expected_type, item_type)| {
+ compute_type_match2(completion, &expected_type, &item_type).is_some()
+ }) {
+ Some(CompletionRelevanceTypeMatch::CouldUnify)
+ } else {
+ None
+ }
+ }
+ } else {
+ None
+ }
+ } else {
+ None
+ };
+
item.set_relevance(CompletionRelevance {
- type_match: compute_type_match(completion, &ret_type),
+ type_match,
exact_name_match: compute_exact_name_match(completion, &call),
is_op_method,
..ctx.completion_relevance()