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.rs | 94 |
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#" |