Skip to content

Commit 05b7cbc

Browse files
Merge pull request #20507 from A4-Tacks/suggest-return-expr
Add ReturnExpr completion suggest
2 parents 3536955 + ac7615b commit 05b7cbc

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))
@@ -1877,7 +1889,7 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
18771889
None
18781890
}
18791891

1880-
fn prev_assign_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
1892+
fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
18811893
while token.kind().is_trivia()
18821894
&& let Some(prev) = token.prev_token()
18831895
&& let T![=]
@@ -1890,7 +1902,10 @@ fn prev_assign_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
18901902
| T![-=]
18911903
| T![|=]
18921904
| T![&=]
1893-
| T![^=] = prev.kind()
1905+
| T![^=]
1906+
| T![return]
1907+
| T![break]
1908+
| T![continue] = prev.kind()
18941909
{
18951910
token = prev
18961911
}

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

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

0 commit comments

Comments
 (0)