Skip to content

Commit ac7615b

Browse files
committed
Add ReturnExpr completion suggest
1 parent e10fa93 commit ac7615b

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

crates/ide-completion/src/context/analysis.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ fn expected_type_and_name<'db>(
559559
token: &SyntaxToken,
560560
name_like: &ast::NameLike,
561561
) -> (Option<Type<'db>>, Option<NameOrNameRef>) {
562-
let token = prev_assign_token_at_trivia(token.clone());
562+
let token = prev_special_biased_token_at_trivia(token.clone());
563563
let mut node = match token.parent() {
564564
Some(it) => it,
565565
None => return (None, None),
@@ -724,6 +724,18 @@ fn expected_type_and_name<'db>(
724724
let def = sema.to_def(&it);
725725
(def.map(|def| def.ret_type(sema.db)), None)
726726
},
727+
ast::ReturnExpr(it) => {
728+
let fn_ = sema.ancestors_with_macros(it.syntax().clone())
729+
.find_map(Either::<ast::Fn, ast::ClosureExpr>::cast);
730+
let ty = fn_.and_then(|f| match f {
731+
Either::Left(f) => Some(sema.to_def(&f)?.ret_type(sema.db)),
732+
Either::Right(f) => {
733+
let ty = sema.type_of_expr(&f.into())?.original.as_callable(sema.db)?;
734+
Some(ty.return_type())
735+
},
736+
});
737+
(ty, None)
738+
},
727739
ast::ClosureExpr(it) => {
728740
let ty = sema.type_of_expr(&it.into());
729741
ty.and_then(|ty| ty.original.as_callable(sema.db))
@@ -1868,7 +1880,7 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
18681880
None
18691881
}
18701882

1871-
fn prev_assign_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
1883+
fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
18721884
while token.kind().is_trivia()
18731885
&& let Some(prev) = token.prev_token()
18741886
&& let T![=]
@@ -1881,7 +1893,10 @@ fn prev_assign_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
18811893
| T![-=]
18821894
| T![|=]
18831895
| T![&=]
1884-
| T![^=] = prev.kind()
1896+
| T![^=]
1897+
| T![return]
1898+
| T![break]
1899+
| T![continue] = prev.kind()
18851900
{
18861901
token = prev
18871902
}

crates/ide-completion/src/context/tests.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,3 +484,39 @@ fn foo() {
484484
expect![[r#"ty: State, name: ?"#]],
485485
);
486486
}
487+
488+
#[test]
489+
fn expected_type_return_expr() {
490+
check_expected_type_and_name(
491+
r#"
492+
enum State { Stop }
493+
fn foo() -> State {
494+
let _: i32 = if true {
495+
8
496+
} else {
497+
return $0;
498+
};
499+
}
500+
"#,
501+
expect![[r#"ty: State, name: ?"#]],
502+
);
503+
}
504+
505+
#[test]
506+
fn expected_type_return_expr_in_closure() {
507+
check_expected_type_and_name(
508+
r#"
509+
enum State { Stop }
510+
fn foo() {
511+
let _f: fn() -> State = || {
512+
let _: i32 = if true {
513+
8
514+
} else {
515+
return $0;
516+
};
517+
};
518+
}
519+
"#,
520+
expect![[r#"ty: State, name: ?"#]],
521+
);
522+
}

0 commit comments

Comments
 (0)