Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/render.rs')
-rw-r--r--crates/ide-completion/src/render.rs94
1 files changed, 88 insertions, 6 deletions
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index c0f09e1d95..765304d818 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -10,7 +10,7 @@ pub(crate) mod type_alias;
pub(crate) mod union_literal;
pub(crate) mod variant;
-use hir::{AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type, sym};
+use hir::{AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type};
use ide_db::text_edit::TextEdit;
use ide_db::{
RootDatabase, SnippetCap, SymbolKind,
@@ -91,8 +91,7 @@ impl<'a> RenderContext<'a> {
}
fn is_deprecated(&self, def: impl HasAttrs) -> bool {
- let attrs = def.attrs(self.db());
- attrs.by_key(sym::deprecated).exists()
+ def.attrs(self.db()).is_deprecated()
}
fn is_deprecated_assoc_item(&self, as_assoc_item: impl AsAssocItem) -> bool {
@@ -115,7 +114,7 @@ impl<'a> RenderContext<'a> {
}
// FIXME: remove this
- fn docs(&self, def: impl HasDocs) -> Option<Documentation> {
+ fn docs(&self, def: impl HasDocs) -> Option<Documentation<'a>> {
def.docs(self.db())
}
}
@@ -320,7 +319,9 @@ pub(crate) fn render_expr(
);
let edit = TextEdit::replace(source_range, snippet);
item.snippet_edit(ctx.config.snippet_cap?, edit);
- item.documentation(Documentation::new(String::from("Autogenerated expression by term search")));
+ item.documentation(Documentation::new_owned(String::from(
+ "Autogenerated expression by term search",
+ )));
item.set_relevance(crate::CompletionRelevance {
type_match: compute_type_match(ctx, &expr.ty(ctx.db)),
..Default::default()
@@ -553,7 +554,7 @@ fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind {
}
}
-fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentation> {
+fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentation<'_>> {
use hir::ModuleDef::*;
match resolution {
ScopeDef::ModuleDef(Module(it)) => it.docs(db),
@@ -603,6 +604,14 @@ fn compute_type_match(
return None;
}
+ // &mut ty -> &ty
+ if completion_ty.is_mutable_reference()
+ && let Some(expected_type) = expected_type.remove_ref()
+ && let Some(completion_ty) = completion_ty.remove_ref()
+ {
+ return match_types(ctx, &expected_type, &completion_ty);
+ }
+
match_types(ctx, expected_type, completion_ty)
}
@@ -621,6 +630,8 @@ fn compute_ref_match(
return None;
}
if let Some(expected_without_ref) = &expected_without_ref
+ && (completion_without_ref.is_none()
+ || completion_ty.could_unify_with(ctx.db, expected_without_ref))
&& completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref)
{
cov_mark::hit!(suggest_ref);
@@ -2049,6 +2060,17 @@ fn go(world: &WorldSnapshot) { go(w$0) }
}
#[test]
+ fn prioritize_mutable_ref_as_immutable_ref_match() {
+ check_relevance(
+ r#"fn foo(r: &mut i32) -> &i32 { $0 }"#,
+ expect![[r#"
+ lc r &mut i32 [type+local]
+ fn foo(…) fn(&mut i32) -> &i32 [type]
+ "#]],
+ );
+ }
+
+ #[test]
fn too_many_arguments() {
cov_mark::check!(too_many_arguments);
check_relevance(
@@ -2211,6 +2233,24 @@ fn main() {
fn main() fn() []
"#]],
);
+ check_relevance(
+ r#"
+struct S;
+fn foo(s: &&S) {}
+fn main() {
+ let mut ssss = &S;
+ foo($0);
+}
+ "#,
+ expect![[r#"
+ st S S []
+ lc ssss &S [local]
+ lc &ssss [type+local]
+ st S S []
+ fn foo(…) fn(&&S) []
+ fn main() fn() []
+ "#]],
+ );
}
#[test]
@@ -3240,6 +3280,48 @@ impl S {
}
#[test]
+ fn field_access_includes_closure_this_param() {
+ check_edit(
+ "length",
+ r#"
+//- minicore: fn
+struct S {
+ length: i32
+}
+
+impl S {
+ fn pack(&mut self, f: impl FnOnce(&mut Self, i32)) {
+ self.length += 1;
+ f(self, 3);
+ self.length -= 1;
+ }
+
+ fn some_fn(&mut self) {
+ self.pack(|this, n| len$0);
+ }
+}
+"#,
+ r#"
+struct S {
+ length: i32
+}
+
+impl S {
+ fn pack(&mut self, f: impl FnOnce(&mut Self, i32)) {
+ self.length += 1;
+ f(self, 3);
+ self.length -= 1;
+ }
+
+ fn some_fn(&mut self) {
+ self.pack(|this, n| this.length);
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
fn notable_traits_method_relevance() {
check_kinds(
r#"