@@ -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+
233240struct ElseBlock < ' db > {
234241 exist_else_block : Option < ast:: BlockExpr > ,
235242 is_never_block : bool ,
@@ -297,6 +304,7 @@ impl<'db> ElseBlock<'db> {
297304
298305enum 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