Skip to content

Commit 45ca9b5

Browse files
committed
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: ? ```
1 parent 4ed6346 commit 45ca9b5

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,10 +562,10 @@ fn analyze<'db>(
562562
/// Calculate the expected type and name of the cursor position.
563563
fn expected_type_and_name<'db>(
564564
sema: &Semantics<'db, RootDatabase>,
565-
token: &SyntaxToken,
565+
self_token: &SyntaxToken,
566566
name_like: &ast::NameLike,
567567
) -> (Option<Type<'db>>, Option<NameOrNameRef>) {
568-
let token = prev_special_biased_token_at_trivia(token.clone());
568+
let token = prev_special_biased_token_at_trivia(self_token.clone());
569569
let mut node = match token.parent() {
570570
Some(it) => it,
571571
None => return (None, None),
@@ -755,7 +755,15 @@ fn expected_type_and_name<'db>(
755755
.map(|c| (Some(c.return_type()), None))
756756
.unwrap_or((None, None))
757757
},
758-
ast::ParamList(_) => (None, None),
758+
ast::ParamList(it) => {
759+
let closure = it.syntax().parent().and_then(ast::ClosureExpr::cast);
760+
let ty = closure
761+
.filter(|_| it.syntax().text_range().end() <= self_token.text_range().start())
762+
.and_then(|it| sema.type_of_expr(&it.into()));
763+
ty.and_then(|ty| ty.original.as_callable(sema.db))
764+
.map(|c| (Some(c.return_type()), None))
765+
.unwrap_or((None, None))
766+
},
759767
ast::Stmt(_) => (None, None),
760768
ast::Item(_) => (None, None),
761769
_ => {
@@ -1940,6 +1948,7 @@ fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
19401948
| T![|=]
19411949
| T![&=]
19421950
| T![^=]
1951+
| T![|]
19431952
| T![return]
19441953
| T![break]
19451954
| T![continue] = prev.kind()

src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,25 @@ fn foo() -> u32 {
373373

374374
#[test]
375375
fn expected_type_closure_param_return() {
376-
// FIXME: make this work with `|| $0`
377376
check_expected_type_and_name(
378377
r#"
379378
//- minicore: fn
380379
fn foo() {
381380
bar(|| a$0);
382381
}
383382
383+
fn bar(f: impl FnOnce() -> u32) {}
384+
"#,
385+
expect![[r#"ty: u32, name: ?"#]],
386+
);
387+
388+
check_expected_type_and_name(
389+
r#"
390+
//- minicore: fn
391+
fn foo() {
392+
bar(|| $0);
393+
}
394+
384395
fn bar(f: impl FnOnce() -> u32) {}
385396
"#,
386397
expect![[r#"ty: u32, name: ?"#]],

0 commit comments

Comments
 (0)