@@ -13,7 +13,7 @@ use syntax::{
13
13
edit:: { AstNodeEdit , IndentLevel } ,
14
14
make, HasName ,
15
15
} ,
16
- AstNode , TextRange ,
16
+ AstNode , TextRange , T ,
17
17
} ;
18
18
19
19
use crate :: {
@@ -96,8 +96,9 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
96
96
cond_bodies. push ( ( cond, body) ) ;
97
97
}
98
98
99
- if !pat_seen {
100
- // Don't offer turning an if (chain) without patterns into a match
99
+ if !pat_seen && cond_bodies. len ( ) != 1 {
100
+ // Don't offer turning an if (chain) without patterns into a match,
101
+ // unless its a simple `if cond { .. } (else { .. })`
101
102
return None ;
102
103
}
103
104
@@ -114,6 +115,11 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
114
115
Either :: Left ( pat) => {
115
116
make:: match_arm ( iter:: once ( pat) , None , unwrap_trivial_block ( body) )
116
117
}
118
+ Either :: Right ( _) if !pat_seen => make:: match_arm (
119
+ iter:: once ( make:: literal_pat ( "true" ) . into ( ) ) ,
120
+ None ,
121
+ unwrap_trivial_block ( body) ,
122
+ ) ,
117
123
Either :: Right ( expr) => make:: match_arm (
118
124
iter:: once ( make:: wildcard_pat ( ) . into ( ) ) ,
119
125
Some ( expr) ,
@@ -144,31 +150,36 @@ fn make_else_arm(
144
150
else_block : Option < ast:: BlockExpr > ,
145
151
conditionals : & [ ( Either < ast:: Pat , ast:: Expr > , ast:: BlockExpr ) ] ,
146
152
) -> ast:: MatchArm {
147
- if let Some ( else_block) = else_block {
148
- let pattern = if let [ ( Either :: Left ( pat) , _) ] = conditionals {
149
- ctx. sema
153
+ let ( pattern, expr) = if let Some ( else_block) = else_block {
154
+ let pattern = match conditionals {
155
+ [ ( Either :: Right ( _) , _) ] => make:: literal_pat ( "false" ) . into ( ) ,
156
+ [ ( Either :: Left ( pat) , _) ] => match ctx
157
+ . sema
150
158
. type_of_pat ( pat)
151
159
. and_then ( |ty| TryEnum :: from_ty ( & ctx. sema , & ty. adjusted ( ) ) )
152
- . zip ( Some ( pat) )
153
- } else {
154
- None
155
- } ;
156
- let pattern = match pattern {
157
- Some ( ( it, pat) ) => {
158
- if does_pat_match_variant ( pat, & it. sad_pattern ( ) ) {
159
- it. happy_pattern_wildcard ( )
160
- } else if does_nested_pattern ( pat) {
161
- make:: wildcard_pat ( ) . into ( )
162
- } else {
163
- it. sad_pattern ( )
160
+ {
161
+ Some ( it) => {
162
+ if does_pat_match_variant ( pat, & it. sad_pattern ( ) ) {
163
+ it. happy_pattern_wildcard ( )
164
+ } else if does_nested_pattern ( pat) {
165
+ make:: wildcard_pat ( ) . into ( )
166
+ } else {
167
+ it. sad_pattern ( )
168
+ }
164
169
}
165
- }
166
- None => make:: wildcard_pat ( ) . into ( ) ,
170
+ None => make:: wildcard_pat ( ) . into ( ) ,
171
+ } ,
172
+ _ => make:: wildcard_pat ( ) . into ( ) ,
167
173
} ;
168
- make :: match_arm ( iter :: once ( pattern) , None , unwrap_trivial_block ( else_block) )
174
+ ( pattern, unwrap_trivial_block ( else_block) )
169
175
} else {
170
- make:: match_arm ( iter:: once ( make:: wildcard_pat ( ) . into ( ) ) , None , make:: expr_unit ( ) )
171
- }
176
+ let pattern = match conditionals {
177
+ [ ( Either :: Right ( _) , _) ] => make:: literal_pat ( "false" ) . into ( ) ,
178
+ _ => make:: wildcard_pat ( ) . into ( ) ,
179
+ } ;
180
+ ( pattern, make:: expr_unit ( ) )
181
+ } ;
182
+ make:: match_arm ( iter:: once ( pattern) , None , expr)
172
183
}
173
184
174
185
// Assist: replace_match_with_if_let
@@ -231,7 +242,19 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<'
231
242
}
232
243
}
233
244
234
- let condition = make:: expr_let ( if_let_pat, scrutinee) ;
245
+ let condition = match if_let_pat {
246
+ ast:: Pat :: LiteralPat ( p)
247
+ if p. literal ( ) . map_or ( false , |it| it. token ( ) . kind ( ) == T ! [ true ] ) =>
248
+ {
249
+ scrutinee
250
+ }
251
+ ast:: Pat :: LiteralPat ( p)
252
+ if p. literal ( ) . map_or ( false , |it| it. token ( ) . kind ( ) == T ! [ false ] ) =>
253
+ {
254
+ make:: expr_prefix ( T ! [ !] , scrutinee)
255
+ }
256
+ _ => make:: expr_let ( if_let_pat, scrutinee) . into ( ) ,
257
+ } ;
235
258
let then_block = make_block_expr ( then_expr. reset_indent ( ) ) ;
236
259
let else_expr = if is_empty_expr ( & else_expr) { None } else { Some ( else_expr) } ;
237
260
let if_let_expr = make:: expr_if (
@@ -327,6 +350,58 @@ fn main() {
327
350
)
328
351
}
329
352
353
+ #[ test]
354
+ fn test_if_with_match_no_else ( ) {
355
+ check_assist (
356
+ replace_if_let_with_match,
357
+ r#"
358
+ pub fn foo(foo: bool) {
359
+ if foo$0 {
360
+ self.foo();
361
+ }
362
+ }
363
+ "# ,
364
+ r#"
365
+ pub fn foo(foo: bool) {
366
+ match foo {
367
+ true => {
368
+ self.foo();
369
+ }
370
+ false => (),
371
+ }
372
+ }
373
+ "# ,
374
+ )
375
+ }
376
+
377
+ #[ test]
378
+ fn test_if_with_match_with_else ( ) {
379
+ check_assist (
380
+ replace_if_let_with_match,
381
+ r#"
382
+ pub fn foo(foo: bool) {
383
+ if foo$0 {
384
+ self.foo();
385
+ } else {
386
+ self.bar();
387
+ }
388
+ }
389
+ "# ,
390
+ r#"
391
+ pub fn foo(foo: bool) {
392
+ match foo {
393
+ true => {
394
+ self.foo();
395
+ }
396
+ false => {
397
+ self.bar();
398
+ }
399
+ }
400
+ }
401
+ "# ,
402
+ )
403
+ }
404
+
330
405
#[ test]
331
406
fn test_if_let_with_match_no_else ( ) {
332
407
check_assist (
@@ -993,6 +1068,66 @@ fn main() {
993
1068
code()
994
1069
}
995
1070
}
1071
+ "# ,
1072
+ )
1073
+ }
1074
+
1075
+ #[ test]
1076
+ fn test_replace_match_with_if_bool ( ) {
1077
+ check_assist (
1078
+ replace_match_with_if_let,
1079
+ r#"
1080
+ fn main() {
1081
+ match$0 b {
1082
+ true => (),
1083
+ _ => code(),
1084
+ }
1085
+ }
1086
+ "# ,
1087
+ r#"
1088
+ fn main() {
1089
+ if b {
1090
+ ()
1091
+ } else {
1092
+ code()
1093
+ }
1094
+ }
1095
+ "# ,
1096
+ ) ;
1097
+ check_assist (
1098
+ replace_match_with_if_let,
1099
+ r#"
1100
+ fn main() {
1101
+ match$0 b {
1102
+ false => code(),
1103
+ true => (),
1104
+ }
1105
+ }
1106
+ "# ,
1107
+ r#"
1108
+ fn main() {
1109
+ if !b {
1110
+ code()
1111
+ }
1112
+ }
1113
+ "# ,
1114
+ ) ;
1115
+ check_assist (
1116
+ replace_match_with_if_let,
1117
+ r#"
1118
+ fn main() {
1119
+ match$0 b {
1120
+ false => (),
1121
+ true => code(),
1122
+ }
1123
+ }
1124
+ "# ,
1125
+ r#"
1126
+ fn main() {
1127
+ if b {
1128
+ code()
1129
+ }
1130
+ }
996
1131
"# ,
997
1132
)
998
1133
}
0 commit comments