Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21277 from A4-Tacks/strip-deref
Fix expected type no strip deref
Chayim Refael Friedman 4 months ago
parent 87cfc88 · parent d359992 · commit 0023f19
-rw-r--r--crates/ide-completion/src/context/analysis.rs18
-rw-r--r--crates/ide-completion/src/context/tests.rs12
2 files changed, 29 insertions, 1 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index add637a16f..b65c68a240 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -600,10 +600,26 @@ fn expected_type_and_name<'db>(
Some(it) => it,
None => return ty,
};
- for _ in top_syn.ancestors().skip(1).map_while(ast::RefExpr::cast) {
+ let refs_level = top_syn
+ .ancestors()
+ .skip(1)
+ .map_while(Either::<ast::RefExpr, ast::PrefixExpr>::cast)
+ .take_while(|it| match it {
+ Either::Left(_) => true,
+ Either::Right(prefix) => prefix.op_kind() == Some(ast::UnaryOp::Deref),
+ })
+ .fold(0i32, |level, expr| match expr {
+ Either::Left(_) => level + 1,
+ Either::Right(_) => level - 1,
+ });
+ for _ in 0..refs_level {
cov_mark::hit!(expected_type_fn_param_ref);
ty = ty.strip_reference();
}
+ for _ in refs_level..0 {
+ cov_mark::hit!(expected_type_fn_param_deref);
+ ty = ty.add_reference(hir::Mutability::Shared);
+ }
ty
}
_ => ty,
diff --git a/crates/ide-completion/src/context/tests.rs b/crates/ide-completion/src/context/tests.rs
index 41f0db3c52..b929d36ce6 100644
--- a/crates/ide-completion/src/context/tests.rs
+++ b/crates/ide-completion/src/context/tests.rs
@@ -147,6 +147,18 @@ fn bar(x: &u32) {}
}
#[test]
+fn expected_type_fn_param_deref() {
+ cov_mark::check!(expected_type_fn_param_deref);
+ check_expected_type_and_name(
+ r#"
+fn foo() { bar(*$0); }
+fn bar(x: &u32) {}
+"#,
+ expect!["ty: &'_ &'_ u32, name: x"],
+ );
+}
+
+#[test]
fn expected_type_struct_field_without_leading_char() {
cov_mark::check!(expected_type_struct_field_without_leading_char);
check_expected_type_and_name(