Skip to content

Commit 7696e68

Browse files
Merge pull request #21919 from A4-Tacks/label-block-guarded
feat: support labeled block for convert_to_guarded_return
2 parents e2722dd + 8dd9f6c commit 7696e68

1 file changed

Lines changed: 41 additions & 4 deletions

File tree

crates/ide-assists/src/handlers/convert_to_guarded_return.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ fn if_expr_to_guarded_return(
101101
return None;
102102
}
103103

104-
let parent_container = parent_block.syntax().parent()?;
105-
let else_block = ElseBlock::new(&ctx.sema, else_block, &parent_container)?;
104+
let container = container_of(&parent_block)?;
105+
let else_block = ElseBlock::new(&ctx.sema, else_block, &container)?;
106106

107107
if parent_block.tail_expr() != Some(if_expr.clone().into())
108108
&& !(else_block.is_never_block
@@ -201,8 +201,8 @@ fn let_stmt_to_guarded_return(
201201
let target = let_stmt.syntax().text_range();
202202

203203
let parent_block = let_stmt.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
204-
let parent_container = parent_block.syntax().parent()?;
205-
let else_block = ElseBlock::new(&ctx.sema, None, &parent_container)?;
204+
let container = container_of(&parent_block)?;
205+
let else_block = ElseBlock::new(&ctx.sema, None, &container)?;
206206

207207
acc.add(
208208
AssistId::refactor_rewrite("convert_to_guarded_return"),
@@ -230,6 +230,13 @@ fn let_stmt_to_guarded_return(
230230
)
231231
}
232232

233+
fn container_of(block: &ast::BlockExpr) -> Option<SyntaxNode> {
234+
if block.label().is_some() {
235+
return Some(block.syntax().clone());
236+
}
237+
block.syntax().parent()
238+
}
239+
233240
struct ElseBlock<'db> {
234241
exist_else_block: Option<ast::BlockExpr>,
235242
is_never_block: bool,
@@ -297,6 +304,7 @@ impl<'db> ElseBlock<'db> {
297304

298305
enum EarlyKind<'db> {
299306
Continue,
307+
Break(ast::Lifetime, hir::Type<'db>),
300308
Return(hir::Type<'db>),
301309
}
302310

@@ -309,6 +317,7 @@ impl<'db> EarlyKind<'db> {
309317
match parent_container {
310318
ast::Fn(it) => Some(Self::Return(sema.to_def(&it)?.ret_type(sema.db))),
311319
ast::ClosureExpr(it) => Some(Self::Return(sema.type_of_expr(&it.body()?)?.original)),
320+
ast::BlockExpr(it) => Some(Self::Break(it.label()?.lifetime()?, sema.type_of_expr(&it.into())?.original)),
312321
ast::WhileExpr(_) => Some(Self::Continue),
313322
ast::LoopExpr(_) => Some(Self::Continue),
314323
ast::ForExpr(_) => Some(Self::Continue),
@@ -325,6 +334,7 @@ impl<'db> EarlyKind<'db> {
325334
) -> ast::Expr {
326335
match self {
327336
EarlyKind::Continue => make.expr_continue(None).into(),
337+
EarlyKind::Break(label, _) => make.expr_break(Some(label.clone()), ret).into(),
328338
EarlyKind::Return(ty) => {
329339
let expr = match TryEnum::from_ty(sema, ty) {
330340
Some(TryEnum::Option) => {
@@ -340,6 +350,7 @@ impl<'db> EarlyKind<'db> {
340350
fn is_unit(&self) -> bool {
341351
match self {
342352
EarlyKind::Continue => true,
353+
EarlyKind::Break(_, ty) => ty.is_unit(),
343354
EarlyKind::Return(ty) => ty.is_unit(),
344355
}
345356
}
@@ -1067,6 +1078,32 @@ fn main() {
10671078
);
10681079
}
10691080

1081+
#[test]
1082+
fn convert_let_inside_labeled_block() {
1083+
check_assist(
1084+
convert_to_guarded_return,
1085+
r#"
1086+
fn main() {
1087+
'l: {
1088+
if$0 let Some(n) = n {
1089+
foo(n);
1090+
bar();
1091+
}
1092+
}
1093+
}
1094+
"#,
1095+
r#"
1096+
fn main() {
1097+
'l: {
1098+
let Some(n) = n else { break 'l };
1099+
foo(n);
1100+
bar();
1101+
}
1102+
}
1103+
"#,
1104+
);
1105+
}
1106+
10701107
#[test]
10711108
fn convert_let_inside_for_with_else() {
10721109
check_assist(

0 commit comments

Comments
 (0)