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 | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index bc5589a645..765304d818 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -604,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) } @@ -622,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); @@ -2050,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( @@ -2212,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] @@ -3241,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#" |