@@ -39,16 +39,10 @@ use crate::{
39
39
// ```
40
40
pub ( crate ) fn convert_while_to_loop ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
41
41
let while_kw = ctx. find_token_syntax_at_offset ( T ! [ while ] ) ?;
42
- let while_expr: ast :: WhileExpr = while_kw. parent ( ) . and_then ( ast:: WhileExpr :: cast) ?;
42
+ let while_expr = while_kw. parent ( ) . and_then ( ast:: WhileExpr :: cast) ?;
43
43
let while_body = while_expr. loop_body ( ) ?;
44
- let cond = while_expr. condition ( ) ?;
45
-
46
- // Don't handle while let
47
- if cond. pat ( ) . is_some ( ) {
48
- return None ;
49
- } ;
50
-
51
- let cond_expr = cond. expr ( ) ?;
44
+ let while_cond = while_expr. condition ( ) ?;
45
+ let while_cond_expr = while_cond. expr ( ) ?;
52
46
53
47
let target = while_expr. syntax ( ) . text_range ( ) ;
54
48
acc. add (
@@ -58,27 +52,25 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext) -> O
58
52
|edit| {
59
53
let while_indent_level = IndentLevel :: from_node ( while_expr. syntax ( ) ) ;
60
54
61
- let replacement = {
62
- let if_expr = {
63
- let cond = invert_boolean_expression ( cond_expr) ;
64
- let then_branch = make:: block_expr (
65
- once ( make:: expr_stmt ( make:: expr_break ( None ) ) . into ( ) ) ,
66
- None ,
67
- ) ;
68
-
69
- make:: expr_if ( make:: condition ( cond, None ) , then_branch, None )
70
- } ;
71
-
72
- let if_expr = if_expr. indent ( while_indent_level) ;
73
- let stmts = once ( make:: expr_stmt ( if_expr) . into ( ) ) . chain ( while_body. statements ( ) ) ;
74
-
75
- let block_expr = make:: block_expr ( stmts, while_body. tail_expr ( ) ) ;
76
-
77
- let block_expr = block_expr. indent ( while_indent_level) ;
78
-
79
- make:: expr_loop ( block_expr)
55
+ let break_block =
56
+ make:: block_expr ( once ( make:: expr_stmt ( make:: expr_break ( None ) ) . into ( ) ) , None )
57
+ . indent ( while_indent_level) ;
58
+ let block_expr = match while_cond. pat ( ) {
59
+ Some ( _) => {
60
+ let if_expr = make:: expr_if ( while_cond, while_body, Some ( break_block. into ( ) ) ) ;
61
+ let stmts = once ( make:: expr_stmt ( if_expr) . into ( ) ) ;
62
+ make:: block_expr ( stmts, None )
63
+ }
64
+ None => {
65
+ let if_cond = make:: condition ( invert_boolean_expression ( while_cond_expr) , None ) ;
66
+ let if_expr = make:: expr_if ( if_cond, break_block, None ) ;
67
+ let stmts =
68
+ once ( make:: expr_stmt ( if_expr) . into ( ) ) . chain ( while_body. statements ( ) ) ;
69
+ make:: block_expr ( stmts, while_body. tail_expr ( ) )
70
+ }
80
71
} ;
81
72
73
+ let replacement = make:: expr_loop ( block_expr. indent ( while_indent_level) ) ;
82
74
edit. replace ( target, replacement. syntax ( ) . text ( ) )
83
75
} ,
84
76
)
@@ -160,15 +152,26 @@ fn main() {
160
152
}
161
153
162
154
#[ test]
163
- fn ignore_while_let ( ) {
164
- check_assist_not_applicable (
155
+ fn convert_while_let ( ) {
156
+ check_assist (
165
157
convert_while_to_loop,
166
158
r#"
167
159
fn main() {
168
160
while$0 let Some(_) = foo() {
169
161
bar();
170
162
}
171
163
}
164
+ "# ,
165
+ r#"
166
+ fn main() {
167
+ loop {
168
+ if let Some(_) = foo() {
169
+ bar();
170
+ } else {
171
+ break;
172
+ }
173
+ }
174
+ }
172
175
"# ,
173
176
) ;
174
177
}
0 commit comments