@@ -13,7 +13,7 @@ use syntax::{
1313 edit:: { AstNodeEdit , IndentLevel } ,
1414 make, HasName ,
1515 } ,
16- AstNode , TextRange ,
16+ AstNode , TextRange , T ,
1717} ;
1818
1919use crate :: {
@@ -96,8 +96,9 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
9696 cond_bodies. push ( ( cond, body) ) ;
9797 }
9898
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 { .. })`
101102 return None ;
102103 }
103104
@@ -114,6 +115,11 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
114115 Either :: Left ( pat) => {
115116 make:: match_arm ( iter:: once ( pat) , None , unwrap_trivial_block ( body) )
116117 }
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+ ) ,
117123 Either :: Right ( expr) => make:: match_arm (
118124 iter:: once ( make:: wildcard_pat ( ) . into ( ) ) ,
119125 Some ( expr) ,
@@ -144,31 +150,36 @@ fn make_else_arm(
144150 else_block : Option < ast:: BlockExpr > ,
145151 conditionals : & [ ( Either < ast:: Pat , ast:: Expr > , ast:: BlockExpr ) ] ,
146152) -> 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
150158 . type_of_pat ( pat)
151159 . 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+ }
164169 }
165- }
166- None => make:: wildcard_pat ( ) . into ( ) ,
170+ None => make:: wildcard_pat ( ) . into ( ) ,
171+ } ,
172+ _ => make:: wildcard_pat ( ) . into ( ) ,
167173 } ;
168- make :: match_arm ( iter :: once ( pattern) , None , unwrap_trivial_block ( else_block) )
174+ ( pattern, unwrap_trivial_block ( else_block) )
169175 } 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)
172183}
173184
174185// Assist: replace_match_with_if_let
@@ -231,7 +242,19 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<'
231242 }
232243 }
233244
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+ } ;
235258 let then_block = make_block_expr ( then_expr. reset_indent ( ) ) ;
236259 let else_expr = if is_empty_expr ( & else_expr) { None } else { Some ( else_expr) } ;
237260 let if_let_expr = make:: expr_if (
@@ -327,6 +350,58 @@ fn main() {
327350 )
328351 }
329352
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+
330405 #[ test]
331406 fn test_if_let_with_match_no_else ( ) {
332407 check_assist (
@@ -993,6 +1068,66 @@ fn main() {
9931068 code()
9941069 }
9951070}
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+ }
9961131"# ,
9971132 )
9981133 }
0 commit comments