Unnamed repository; edit this file 'description' to name the repository.
Fix empty closure completion analysis
Example --- ```rust fn foo() { bar(|| $0); } fn bar(f: impl FnOnce() -> u32) {} ``` **Before this PR**: ``` ty: impl FnOnce() -> u32, name: ? ``` **After this PR**: ``` ty: u32, name: ? ```
A4-Tacks 6 months ago
parent 90d2e1c · commit 2fdac92
-rw-r--r--crates/ide-completion/src/context/analysis.rs15
-rw-r--r--crates/ide-completion/src/context/tests.rs13
2 files changed, 24 insertions, 4 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index 6cd098462f..0b8ba808e5 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -562,10 +562,10 @@ fn analyze<'db>(
/// Calculate the expected type and name of the cursor position.
fn expected_type_and_name<'db>(
sema: &Semantics<'db, RootDatabase>,
- token: &SyntaxToken,
+ self_token: &SyntaxToken,
name_like: &ast::NameLike,
) -> (Option<Type<'db>>, Option<NameOrNameRef>) {
- let token = prev_special_biased_token_at_trivia(token.clone());
+ let token = prev_special_biased_token_at_trivia(self_token.clone());
let mut node = match token.parent() {
Some(it) => it,
None => return (None, None),
@@ -755,7 +755,15 @@ fn expected_type_and_name<'db>(
.map(|c| (Some(c.return_type()), None))
.unwrap_or((None, None))
},
- ast::ParamList(_) => (None, None),
+ ast::ParamList(it) => {
+ let closure = it.syntax().parent().and_then(ast::ClosureExpr::cast);
+ let ty = closure
+ .filter(|_| it.syntax().text_range().end() <= self_token.text_range().start())
+ .and_then(|it| sema.type_of_expr(&it.into()));
+ ty.and_then(|ty| ty.original.as_callable(sema.db))
+ .map(|c| (Some(c.return_type()), None))
+ .unwrap_or((None, None))
+ },
ast::Stmt(_) => (None, None),
ast::Item(_) => (None, None),
_ => {
@@ -1940,6 +1948,7 @@ fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
| T![|=]
| T![&=]
| T![^=]
+ | T![|]
| T![return]
| T![break]
| T![continue] = prev.kind()
diff --git a/crates/ide-completion/src/context/tests.rs b/crates/ide-completion/src/context/tests.rs
index 24647ab627..e798f3b23a 100644
--- a/crates/ide-completion/src/context/tests.rs
+++ b/crates/ide-completion/src/context/tests.rs
@@ -373,7 +373,6 @@ fn foo() -> u32 {
#[test]
fn expected_type_closure_param_return() {
- // FIXME: make this work with `|| $0`
check_expected_type_and_name(
r#"
//- minicore: fn
@@ -385,6 +384,18 @@ fn bar(f: impl FnOnce() -> u32) {}
"#,
expect![[r#"ty: u32, name: ?"#]],
);
+
+ check_expected_type_and_name(
+ r#"
+//- minicore: fn
+fn foo() {
+ bar(|| $0);
+}
+
+fn bar(f: impl FnOnce() -> u32) {}
+"#,
+ expect![[r#"ty: u32, name: ?"#]],
+ );
}
#[test]