1use std::iter::successors;
2
3use either::Either;
4use ide_db::{
5 RootDatabase,
6 defs::NameClass,
7 syntax_helpers::node_ext::{is_pattern_cond, single_let},
8 ty_filter::TryEnum,
9};
10use syntax::{
11 AstNode, Edition, T, TextRange,
12 ast::{self, HasName, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory},
13};
14
15use crate::{
16 AssistContext, AssistId, Assists,
17 utils::{does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block},
18};
19
20pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
47 let if_expr: ast::IfExpr = ctx.find_node_at_offset()?;
48 let available_range = TextRange::new(
49 if_expr.syntax().text_range().start(),
50 if_expr.then_branch()?.syntax().text_range().start(),
51 );
52 let cursor_in_range = available_range.contains_range(ctx.selection_trimmed());
53 if !cursor_in_range {
54 return None;
55 }
56 let mut else_block = None;
57 let if_exprs = successors(Some(if_expr.clone()), |expr| match expr.else_branch()? {
58 ast::ElseBranch::IfExpr(expr) => Some(expr),
59 ast::ElseBranch::Block(block) => {
60 else_block = Some(block);
61 None
62 }
63 });
64 let scrutinee_to_be_expr = if_expr.condition()?;
65 let scrutinee_to_be_expr = match single_let(scrutinee_to_be_expr.clone()) {
66 Some(cond) => cond.expr()?,
67 None => scrutinee_to_be_expr,
68 };
69
70 let mut pat_seen = false;
71 let mut cond_bodies = Vec::new();
72 for if_expr in if_exprs {
73 let cond = if_expr.condition()?;
74 let cond = match single_let(cond.clone()) {
75 Some(let_) => {
76 let pat = let_.pat()?;
77 let expr = let_.expr()?;
78 if scrutinee_to_be_expr.syntax().text() != expr.syntax().text() {
81 return None;
83 }
84 pat_seen = true;
85 Either::Left(pat)
86 }
87 None if is_pattern_cond(cond.clone()) => return None,
89 None => Either::Right(cond),
90 };
91 let body = if_expr.then_branch()?;
92 cond_bodies.push((cond, body));
93 }
94
95 if !pat_seen && cond_bodies.len() != 1 {
96 return None;
99 }
100
101 let let_ = if pat_seen { " let" } else { "" };
102
103 acc.add(
104 AssistId::refactor_rewrite("replace_if_let_with_match"),
105 format!("Replace if{let_} with match"),
106 available_range,
107 move |builder| {
108 let make = SyntaxFactory::with_mappings();
109 let match_expr = {
110 let else_arm = make_else_arm(ctx, &make, else_block, &cond_bodies);
111 let make_match_arm = |(pat, body): (_, ast::BlockExpr)| {
112 let body = make.block_expr(body.statements(), body.tail_expr());
113 body.indent(IndentLevel::from(1));
114 let body = unwrap_trivial_block(body);
115 match pat {
116 Either::Left(pat) => make.match_arm(pat, None, body),
117 Either::Right(_) if !pat_seen => {
118 make.match_arm(make.literal_pat("true").into(), None, body)
119 }
120 Either::Right(expr) => make.match_arm(
121 make.wildcard_pat().into(),
122 Some(make.match_guard(expr)),
123 body,
124 ),
125 }
126 };
127 let arms = cond_bodies.into_iter().map(make_match_arm).chain([else_arm]);
128 let match_expr = make.expr_match(scrutinee_to_be_expr, make.match_arm_list(arms));
129 match_expr.indent(IndentLevel::from_node(if_expr.syntax()));
130 match_expr.into()
131 };
132
133 let has_preceding_if_expr =
134 if_expr.syntax().parent().is_some_and(|it| ast::IfExpr::can_cast(it.kind()));
135 let expr = if has_preceding_if_expr {
136 make.block_expr([], Some(match_expr)).into()
138 } else {
139 match_expr
140 };
141
142 let mut editor = builder.make_editor(if_expr.syntax());
143 editor.replace(if_expr.syntax(), expr.syntax());
144 editor.add_mappings(make.finish_with_mappings());
145 builder.add_file_edits(ctx.vfs_file_id(), editor);
146 },
147 )
148}
149
150fn make_else_arm(
151 ctx: &AssistContext<'_>,
152 make: &SyntaxFactory,
153 else_block: Option<ast::BlockExpr>,
154 conditionals: &[(Either<ast::Pat, ast::Expr>, ast::BlockExpr)],
155) -> ast::MatchArm {
156 let (pattern, expr) = if let Some(else_block) = else_block {
157 let pattern = match conditionals {
158 [(Either::Right(_), _)] => make.literal_pat("false").into(),
159 [(Either::Left(pat), _)] => match ctx
160 .sema
161 .type_of_pat(pat)
162 .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
163 {
164 Some(it) => {
165 if does_pat_match_variant(pat, &it.sad_pattern()) {
166 it.happy_pattern_wildcard()
167 } else if does_pat_variant_nested_or_literal(ctx, pat) {
168 make.wildcard_pat().into()
169 } else {
170 it.sad_pattern()
171 }
172 }
173 None => make.wildcard_pat().into(),
174 },
175 _ => make.wildcard_pat().into(),
176 };
177 (pattern, unwrap_trivial_block(else_block))
178 } else {
179 let pattern = match conditionals {
180 [(Either::Right(_), _)] => make.literal_pat("false").into(),
181 _ => make.wildcard_pat().into(),
182 };
183 (pattern, make.expr_unit())
184 };
185 make.match_arm(pattern, None, expr)
186}
187
188pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
215 let match_expr: ast::MatchExpr = ctx.find_node_at_offset()?;
216 let match_arm_list = match_expr.match_arm_list()?;
217 let available_range = TextRange::new(
218 match_expr.syntax().text_range().start(),
219 match_arm_list.syntax().text_range().start(),
220 );
221 let cursor_in_range = available_range.contains_range(ctx.selection_trimmed());
222 if !cursor_in_range {
223 return None;
224 }
225
226 let mut arms = match_arm_list.arms();
227 let (first_arm, second_arm) = (arms.next()?, arms.next()?);
228 if arms.next().is_some() || second_arm.guard().is_some() {
229 return None;
230 }
231 if first_arm.guard().is_some() && ctx.edition() < Edition::Edition2024 {
232 return None;
233 }
234
235 let (if_let_pat, guard, then_expr, else_expr) = pick_pattern_and_expr_order(
236 &ctx.sema,
237 first_arm.pat()?,
238 second_arm.pat()?,
239 first_arm.expr()?,
240 second_arm.expr()?,
241 first_arm.guard(),
242 second_arm.guard(),
243 )?;
244 let scrutinee = match_expr.expr()?;
245 let guard = guard.and_then(|it| it.condition());
246
247 let let_ = match &if_let_pat {
248 ast::Pat::LiteralPat(p)
249 if p.literal()
250 .map(|it| it.token().kind())
251 .is_some_and(|it| it == T![true] || it == T![false]) =>
252 {
253 ""
254 }
255 _ => " let",
256 };
257 acc.add(
258 AssistId::refactor_rewrite("replace_match_with_if_let"),
259 format!("Replace match with if{let_}"),
260 match_expr.syntax().text_range(),
261 move |builder| {
262 let make = SyntaxFactory::with_mappings();
263 let make_block_expr = |expr: ast::Expr| {
264 match expr {
268 ast::Expr::BlockExpr(block) if block.modifier().is_none() => block,
269 expr => make.block_expr([], Some(expr)),
270 }
271 };
272
273 let condition = match if_let_pat {
274 ast::Pat::LiteralPat(p)
275 if p.literal().is_some_and(|it| it.token().kind() == T![true]) =>
276 {
277 scrutinee
278 }
279 ast::Pat::LiteralPat(p)
280 if p.literal().is_some_and(|it| it.token().kind() == T![false]) =>
281 {
282 make.expr_prefix(T![!], scrutinee).into()
283 }
284 _ => make.expr_let(if_let_pat, scrutinee).into(),
285 };
286 let condition = if let Some(guard) = guard {
287 make.expr_bin(condition, ast::BinaryOp::LogicOp(ast::LogicOp::And), guard).into()
288 } else {
289 condition
290 };
291 let then_expr = then_expr.clone_for_update();
292 then_expr.reindent_to(IndentLevel::single());
293 let then_block = make_block_expr(then_expr);
294 let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
295 let if_let_expr = make.expr_if(
296 condition,
297 then_block,
298 else_expr.map(make_block_expr).map(ast::ElseBranch::Block),
299 );
300 if_let_expr.indent(IndentLevel::from_node(match_expr.syntax()));
301
302 let mut editor = builder.make_editor(match_expr.syntax());
303 editor.replace(match_expr.syntax(), if_let_expr.syntax());
304 editor.add_mappings(make.finish_with_mappings());
305 builder.add_file_edits(ctx.vfs_file_id(), editor);
306 },
307 )
308}
309
310fn pick_pattern_and_expr_order(
312 sema: &hir::Semantics<'_, RootDatabase>,
313 pat: ast::Pat,
314 pat2: ast::Pat,
315 expr: ast::Expr,
316 expr2: ast::Expr,
317 guard: Option<ast::MatchGuard>,
318 guard2: Option<ast::MatchGuard>,
319) -> Option<(ast::Pat, Option<ast::MatchGuard>, ast::Expr, ast::Expr)> {
320 if guard.is_some() && guard2.is_some() {
321 return None;
322 }
323 let res = match (pat, pat2) {
324 (ast::Pat::WildcardPat(_), _) => return None,
325 (pat, ast::Pat::WildcardPat(_)) => (pat, guard, expr, expr2),
326 (pat, _) if is_empty_expr(&expr2) => (pat, guard, expr, expr2),
327 (_, pat) if is_empty_expr(&expr) => (pat, guard, expr2, expr),
328 (pat, pat2) => match (binds_name(sema, &pat), binds_name(sema, &pat2)) {
329 (true, true) => return None,
330 (true, false) => (pat, guard, expr, expr2),
331 (false, true) => {
332 if let ast::Pat::IdentPat(_) = pat2 {
335 return None;
336 }
337 (pat2, guard2, expr2, expr)
338 }
339 _ if is_sad_pat(sema, &pat) => (pat2, guard2, expr2, expr),
340 (false, false) => (pat, guard, expr, expr2),
341 },
342 };
343 Some(res)
344}
345
346fn is_empty_expr(expr: &ast::Expr) -> bool {
347 match expr {
348 ast::Expr::BlockExpr(expr) => match expr.stmt_list() {
349 Some(it) => it.statements().next().is_none() && it.tail_expr().is_none(),
350 None => true,
351 },
352 ast::Expr::TupleExpr(expr) => expr.fields().next().is_none(),
353 _ => false,
354 }
355}
356
357fn binds_name(sema: &hir::Semantics<'_, RootDatabase>, pat: &ast::Pat) -> bool {
358 let binds_name_v = |pat| binds_name(sema, &pat);
359 match pat {
360 ast::Pat::IdentPat(pat) => !matches!(
361 pat.name().and_then(|name| NameClass::classify(sema, &name)),
362 Some(NameClass::ConstReference(_))
363 ),
364 ast::Pat::MacroPat(_) => true,
365 ast::Pat::OrPat(pat) => pat.pats().any(binds_name_v),
366 ast::Pat::SlicePat(pat) => pat.pats().any(binds_name_v),
367 ast::Pat::TuplePat(it) => it.fields().any(binds_name_v),
368 ast::Pat::TupleStructPat(it) => it.fields().any(binds_name_v),
369 ast::Pat::RecordPat(it) => it
370 .record_pat_field_list()
371 .is_some_and(|rpfl| rpfl.fields().flat_map(|rpf| rpf.pat()).any(binds_name_v)),
372 ast::Pat::RefPat(pat) => pat.pat().is_some_and(binds_name_v),
373 ast::Pat::BoxPat(pat) => pat.pat().is_some_and(binds_name_v),
374 ast::Pat::ParenPat(pat) => pat.pat().is_some_and(binds_name_v),
375 _ => false,
376 }
377}
378
379fn is_sad_pat(sema: &hir::Semantics<'_, RootDatabase>, pat: &ast::Pat) -> bool {
380 sema.type_of_pat(pat)
381 .and_then(|ty| TryEnum::from_ty(sema, &ty.adjusted()))
382 .is_some_and(|it| does_pat_match_variant(pat, &it.sad_pattern()))
383}
384
385#[cfg(test)]
386mod tests {
387 use super::*;
388
389 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
390
391 #[test]
392 fn test_if_let_with_match_inapplicable_for_simple_ifs() {
393 check_assist_not_applicable(
394 replace_if_let_with_match,
395 r#"
396fn main() {
397 if $0true {} else if false {} else {}
398}
399"#,
400 )
401 }
402
403 #[test]
404 fn test_if_with_match_no_else() {
405 check_assist(
406 replace_if_let_with_match,
407 r#"
408pub fn foo(foo: bool) {
409 if foo$0 {
410 self.foo();
411 }
412}
413"#,
414 r#"
415pub fn foo(foo: bool) {
416 match foo {
417 true => {
418 self.foo();
419 }
420 false => (),
421 }
422}
423"#,
424 )
425 }
426
427 #[test]
428 fn test_if_with_match_with_else() {
429 check_assist(
430 replace_if_let_with_match,
431 r#"
432pub fn foo(foo: bool) {
433 if foo$0 {
434 self.foo();
435 } else {
436 self.bar();
437 }
438}
439"#,
440 r#"
441pub fn foo(foo: bool) {
442 match foo {
443 true => {
444 self.foo();
445 }
446 false => {
447 self.bar();
448 }
449 }
450}
451"#,
452 )
453 }
454
455 #[test]
456 fn test_if_let_with_match_no_else() {
457 check_assist(
458 replace_if_let_with_match,
459 r#"
460impl VariantData {
461 pub fn foo(&self) {
462 if $0let VariantData::Struct(..) = *self {
463 self.foo();
464 }
465 }
466}
467"#,
468 r#"
469impl VariantData {
470 pub fn foo(&self) {
471 match *self {
472 VariantData::Struct(..) => {
473 self.foo();
474 }
475 _ => (),
476 }
477 }
478}
479"#,
480 )
481 }
482
483 #[test]
484 fn test_if_let_with_match_available_range_left() {
485 check_assist_not_applicable(
486 replace_if_let_with_match,
487 r#"
488impl VariantData {
489 pub fn foo(&self) {
490 $0 if let VariantData::Struct(..) = *self {
491 self.foo();
492 }
493 }
494}
495"#,
496 )
497 }
498
499 #[test]
500 fn test_if_let_with_match_available_range_right() {
501 check_assist_not_applicable(
502 replace_if_let_with_match,
503 r#"
504impl VariantData {
505 pub fn foo(&self) {
506 if let VariantData::Struct(..) = *self {$0
507 self.foo();
508 }
509 }
510}
511"#,
512 )
513 }
514
515 #[test]
516 fn test_if_let_with_match_let_chain() {
517 check_assist_not_applicable(
518 replace_if_let_with_match,
519 r#"
520fn main() {
521 if $0let true = true && let Some(1) = None {}
522}
523"#,
524 )
525 }
526
527 #[test]
528 fn test_if_let_with_match_basic() {
529 check_assist(
530 replace_if_let_with_match,
531 r#"
532impl VariantData {
533 pub fn is_struct(&self) -> bool {
534 if $0let VariantData::Struct(..) = *self {
535 true
536 } else if let VariantData::Tuple(..) = *self {
537 false
538 } else if cond() {
539 true
540 } else {
541 bar(
542 123
543 )
544 }
545 }
546}
547"#,
548 r#"
549impl VariantData {
550 pub fn is_struct(&self) -> bool {
551 match *self {
552 VariantData::Struct(..) => true,
553 VariantData::Tuple(..) => false,
554 _ if cond() => true,
555 _ => {
556 bar(
557 123
558 )
559 }
560 }
561 }
562}
563"#,
564 )
565 }
566
567 #[test]
568 fn test_if_let_with_match_on_tail_if_let() {
569 check_assist(
570 replace_if_let_with_match,
571 r#"
572impl VariantData {
573 pub fn is_struct(&self) -> bool {
574 if let VariantData::Struct(..) = *self {
575 true
576 } else if let$0 VariantData::Tuple(..) = *self {
577 false
578 } else {
579 false
580 }
581 }
582}
583"#,
584 r#"
585impl VariantData {
586 pub fn is_struct(&self) -> bool {
587 if let VariantData::Struct(..) = *self {
588 true
589 } else {
590 match *self {
591 VariantData::Tuple(..) => false,
592 _ => false,
593 }
594}
595 }
596}
597"#,
598 )
599 }
600
601 #[test]
602 fn special_case_option() {
603 check_assist(
604 replace_if_let_with_match,
605 r#"
606//- minicore: option
607fn foo(x: Option<i32>) {
608 $0if let Some(x) = x {
609 println!("{}", x)
610 } else {
611 println!("none")
612 }
613}
614"#,
615 r#"
616fn foo(x: Option<i32>) {
617 match x {
618 Some(x) => println!("{}", x),
619 None => println!("none"),
620 }
621}
622"#,
623 );
624 }
625
626 #[test]
627 fn special_case_inverted_option() {
628 check_assist(
629 replace_if_let_with_match,
630 r#"
631//- minicore: option
632fn foo(x: Option<i32>) {
633 $0if let None = x {
634 println!("none")
635 } else {
636 println!("some")
637 }
638}
639"#,
640 r#"
641fn foo(x: Option<i32>) {
642 match x {
643 None => println!("none"),
644 Some(_) => println!("some"),
645 }
646}
647"#,
648 );
649 }
650
651 #[test]
652 fn special_case_result() {
653 check_assist(
654 replace_if_let_with_match,
655 r#"
656//- minicore: result
657fn foo(x: Result<i32, ()>) {
658 $0if let Ok(x) = x {
659 println!("{}", x)
660 } else {
661 println!("none")
662 }
663}
664"#,
665 r#"
666fn foo(x: Result<i32, ()>) {
667 match x {
668 Ok(x) => println!("{}", x),
669 Err(_) => println!("none"),
670 }
671}
672"#,
673 );
674 }
675
676 #[test]
677 fn special_case_inverted_result() {
678 check_assist(
679 replace_if_let_with_match,
680 r#"
681//- minicore: result
682fn foo(x: Result<i32, ()>) {
683 $0if let Err(x) = x {
684 println!("{}", x)
685 } else {
686 println!("ok")
687 }
688}
689"#,
690 r#"
691fn foo(x: Result<i32, ()>) {
692 match x {
693 Err(x) => println!("{}", x),
694 Ok(_) => println!("ok"),
695 }
696}
697"#,
698 );
699 }
700
701 #[test]
702 fn nested_indent() {
703 check_assist(
704 replace_if_let_with_match,
705 r#"
706fn main() {
707 if true {
708 $0if let Ok(rel_path) = path.strip_prefix(root_path) {
709 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
710 Some((*id, rel_path))
711 } else {
712 None
713 }
714 }
715}
716"#,
717 r#"
718fn main() {
719 if true {
720 match path.strip_prefix(root_path) {
721 Ok(rel_path) => {
722 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
723 Some((*id, rel_path))
724 }
725 _ => None,
726 }
727 }
728}
729"#,
730 )
731 }
732
733 #[test]
734 fn test_if_let_with_match_nested_tuple_struct() {
735 check_assist(
736 replace_if_let_with_match,
737 r#"
738//- minicore: result, option
739fn foo(x: Result<i32, ()>) {
740 let bar: Result<_, ()> = Ok(Some(1));
741 $0if let Ok(Some(_)) = bar {
742 ()
743 } else {
744 ()
745 }
746}
747"#,
748 r#"
749fn foo(x: Result<i32, ()>) {
750 let bar: Result<_, ()> = Ok(Some(1));
751 match bar {
752 Ok(Some(_)) => (),
753 _ => (),
754 }
755}
756"#,
757 );
758
759 check_assist(
760 replace_if_let_with_match,
761 r#"
762//- minicore: result
763struct MyStruct(i32, i32);
764fn foo(x: Result<MyStruct, ()>) {
765 let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2));
766 $0if let Ok(MyStruct(a, b)) = bar {
767 ()
768 } else {
769 ()
770 }
771}
772"#,
773 r#"
774struct MyStruct(i32, i32);
775fn foo(x: Result<MyStruct, ()>) {
776 let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2));
777 match bar {
778 Ok(MyStruct(a, b)) => (),
779 Err(_) => (),
780 }
781}
782"#,
783 );
784 }
785
786 #[test]
787 fn test_if_let_with_match_nested_slice() {
788 check_assist(
789 replace_if_let_with_match,
790 r#"
791//- minicore: result
792fn foo(x: Result<&[i32], ()>) {
793 let foo: Result<&[_], ()> = Ok(&[0, 1, 2]);
794 $0if let Ok([]) = foo {
795 ()
796 } else {
797 ()
798 }
799}
800 "#,
801 r#"
802fn foo(x: Result<&[i32], ()>) {
803 let foo: Result<&[_], ()> = Ok(&[0, 1, 2]);
804 match foo {
805 Ok([]) => (),
806 _ => (),
807 }
808}
809 "#,
810 );
811
812 check_assist(
813 replace_if_let_with_match,
814 r#"
815//- minicore: result
816fn foo(x: Result<[&'static str; 2], ()>) {
817 let foobar: Result<_, ()> = Ok(["foo", "bar"]);
818 $0if let Ok([_, "bar"]) = foobar {
819 ()
820 } else {
821 ()
822 }
823}
824"#,
825 r#"
826fn foo(x: Result<[&'static str; 2], ()>) {
827 let foobar: Result<_, ()> = Ok(["foo", "bar"]);
828 match foobar {
829 Ok([_, "bar"]) => (),
830 _ => (),
831 }
832}
833"#,
834 );
835
836 check_assist(
837 replace_if_let_with_match,
838 r#"
839//- minicore: result
840fn foo(x: Result<[&'static str; 2], ()>) {
841 let foobar: Result<_, ()> = Ok(["foo", "bar"]);
842 $0if let Ok([..]) = foobar {
843 ()
844 } else {
845 ()
846 }
847}
848"#,
849 r#"
850fn foo(x: Result<[&'static str; 2], ()>) {
851 let foobar: Result<_, ()> = Ok(["foo", "bar"]);
852 match foobar {
853 Ok([..]) => (),
854 Err(_) => (),
855 }
856}
857"#,
858 );
859
860 check_assist(
861 replace_if_let_with_match,
862 r#"
863//- minicore: result
864fn foo(x: Result<&[&'static str], ()>) {
865 let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
866 $0if let Ok([a, ..]) = foobar {
867 ()
868 } else {
869 ()
870 }
871}
872"#,
873 r#"
874fn foo(x: Result<&[&'static str], ()>) {
875 let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
876 match foobar {
877 Ok([a, ..]) => (),
878 _ => (),
879 }
880}
881"#,
882 );
883
884 check_assist(
885 replace_if_let_with_match,
886 r#"
887//- minicore: result
888fn foo(x: Result<&[&'static str], ()>) {
889 let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
890 $0if let Ok([a, .., b, c]) = foobar {
891 ()
892 } else {
893 ()
894 }
895}
896"#,
897 r#"
898fn foo(x: Result<&[&'static str], ()>) {
899 let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
900 match foobar {
901 Ok([a, .., b, c]) => (),
902 _ => (),
903 }
904}
905"#,
906 );
907
908 check_assist(
909 replace_if_let_with_match,
910 r#"
911//- minicore: result
912fn foo(x: Result<Option<[&'static str; 2]>, ()>) {
913 let foobar: Result<_, ()> = Ok(Some(["foo", "bar"]));
914 $0if let Ok(Some([_, "bar"])) = foobar {
915 ()
916 } else {
917 ()
918 }
919}
920"#,
921 r#"
922fn foo(x: Result<Option<[&'static str; 2]>, ()>) {
923 let foobar: Result<_, ()> = Ok(Some(["foo", "bar"]));
924 match foobar {
925 Ok(Some([_, "bar"])) => (),
926 _ => (),
927 }
928}
929"#,
930 );
931 }
932
933 #[test]
934 fn test_if_let_with_match_nested_literal() {
935 check_assist(
936 replace_if_let_with_match,
937 r#"
938//- minicore: result
939fn foo(x: Result<&'static str, ()>) {
940 let bar: Result<&_, ()> = Ok("bar");
941 $0if let Ok("foo") = bar {
942 ()
943 } else {
944 ()
945 }
946}
947"#,
948 r#"
949fn foo(x: Result<&'static str, ()>) {
950 let bar: Result<&_, ()> = Ok("bar");
951 match bar {
952 Ok("foo") => (),
953 _ => (),
954 }
955}
956"#,
957 );
958 }
959
960 #[test]
961 fn test_if_let_with_match_nested_tuple() {
962 check_assist(
963 replace_if_let_with_match,
964 r#"
965//- minicore: result
966fn foo(x: Result<(i32, i32, i32), ()>) {
967 let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
968 $0if let Ok((1, second, third)) = bar {
969 ()
970 } else {
971 ()
972 }
973}
974"#,
975 r#"
976fn foo(x: Result<(i32, i32, i32), ()>) {
977 let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
978 match bar {
979 Ok((1, second, third)) => (),
980 _ => (),
981 }
982}
983"#,
984 );
985
986 check_assist(
987 replace_if_let_with_match,
988 r#"
989//- minicore: result
990fn foo(x: Result<(i32, i32, i32), ()>) {
991 let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
992 $0if let Ok((first, second, third)) = bar {
993 ()
994 } else {
995 ()
996 }
997}
998"#,
999 r#"
1000fn foo(x: Result<(i32, i32, i32), ()>) {
1001 let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
1002 match bar {
1003 Ok((first, second, third)) => (),
1004 Err(_) => (),
1005 }
1006}
1007"#,
1008 );
1009 }
1010
1011 #[test]
1012 fn test_if_let_with_match_nested_or() {
1013 check_assist(
1014 replace_if_let_with_match,
1015 r#"
1016//- minicore: result
1017fn foo(x: Result<i32, ()>) {
1018 let bar: Result<i32, ()> = Ok(1);
1019 $0if let Ok(1 | 2) = bar {
1020 ()
1021 } else {
1022 ()
1023 }
1024}
1025"#,
1026 r#"
1027fn foo(x: Result<i32, ()>) {
1028 let bar: Result<i32, ()> = Ok(1);
1029 match bar {
1030 Ok(1 | 2) => (),
1031 _ => (),
1032 }
1033}
1034"#,
1035 );
1036
1037 check_assist(
1038 replace_if_let_with_match,
1039 r#"
1040//- minicore: result
1041fn foo(x: Result<(i32, i32), ()>) {
1042 let bar: Result<(i32, i32), ()> = Ok((1, 2));
1043 $0if let Ok((b, a) | (a, b)) = bar {
1044 ()
1045 } else {
1046 ()
1047 }
1048}
1049"#,
1050 r#"
1051fn foo(x: Result<(i32, i32), ()>) {
1052 let bar: Result<(i32, i32), ()> = Ok((1, 2));
1053 match bar {
1054 Ok((b, a) | (a, b)) => (),
1055 Err(_) => (),
1056 }
1057}
1058"#,
1059 );
1060
1061 check_assist(
1062 replace_if_let_with_match,
1063 r#"
1064//- minicore: result
1065fn foo(x: Result<(i32, i32), ()>) {
1066 let bar: Result<(i32, i32), ()> = Ok((1, 2));
1067 $0if let Ok((1, a) | (a, 2)) = bar {
1068 ()
1069 } else {
1070 ()
1071 }
1072}
1073"#,
1074 r#"
1075fn foo(x: Result<(i32, i32), ()>) {
1076 let bar: Result<(i32, i32), ()> = Ok((1, 2));
1077 match bar {
1078 Ok((1, a) | (a, 2)) => (),
1079 _ => (),
1080 }
1081}
1082"#,
1083 );
1084 }
1085
1086 #[test]
1087 fn test_if_let_with_match_nested_range() {
1088 check_assist(
1089 replace_if_let_with_match,
1090 r#"
1091//- minicore: result
1092fn foo(x: Result<i32, ()>) {
1093 let bar: Result<i32, ()> = Ok(1);
1094 $0if let Ok(1..2) = bar {
1095 ()
1096 } else {
1097 ()
1098 }
1099}
1100"#,
1101 r#"
1102fn foo(x: Result<i32, ()>) {
1103 let bar: Result<i32, ()> = Ok(1);
1104 match bar {
1105 Ok(1..2) => (),
1106 _ => (),
1107 }
1108}
1109"#,
1110 );
1111 }
1112
1113 #[test]
1114 fn test_if_let_with_match_nested_paren() {
1115 check_assist(
1116 replace_if_let_with_match,
1117 r#"
1118//- minicore: result
1119fn foo(x: Result<(i32, i32), ()>) {
1120 let bar: Result<(i32, i32), ()> = Ok((1, 1));
1121 $0if let Ok(((1, 2))) = bar {
1122 ()
1123 } else {
1124 ()
1125 }
1126}
1127"#,
1128 r#"
1129fn foo(x: Result<(i32, i32), ()>) {
1130 let bar: Result<(i32, i32), ()> = Ok((1, 1));
1131 match bar {
1132 Ok(((1, 2))) => (),
1133 _ => (),
1134 }
1135}
1136"#,
1137 );
1138
1139 check_assist(
1140 replace_if_let_with_match,
1141 r#"
1142//- minicore: result
1143fn foo(x: Result<(i32, i32), ()>) {
1144 let bar: Result<(i32, i32), ()> = Ok((1, 1));
1145 $0if let Ok(((a, b))) = bar {
1146 ()
1147 } else {
1148 ()
1149 }
1150}
1151"#,
1152 r#"
1153fn foo(x: Result<(i32, i32), ()>) {
1154 let bar: Result<(i32, i32), ()> = Ok((1, 1));
1155 match bar {
1156 Ok(((a, b))) => (),
1157 Err(_) => (),
1158 }
1159}
1160"#,
1161 );
1162 }
1163
1164 #[test]
1165 fn test_if_let_with_match_nested_macro() {
1166 check_assist(
1167 replace_if_let_with_match,
1168 r#"
1169//- minicore: result
1170fn foo(x: Result<i32, ()>) {
1171 macro_rules! is_42 {
1172 () => {
1173 42
1174 };
1175 }
1176
1177 let bar: Result<i32, ()> = Ok(1);
1178 $0if let Ok(is_42!()) = bar {
1179 ()
1180 } else {
1181 ()
1182 }
1183}
1184"#,
1185 r#"
1186fn foo(x: Result<i32, ()>) {
1187 macro_rules! is_42 {
1188 () => {
1189 42
1190 };
1191 }
1192
1193 let bar: Result<i32, ()> = Ok(1);
1194 match bar {
1195 Ok(is_42!()) => (),
1196 _ => (),
1197 }
1198}
1199"#,
1200 );
1201 }
1202
1203 #[test]
1204 fn test_if_let_with_match_nested_path() {
1205 check_assist(
1206 replace_if_let_with_match,
1207 r#"
1208//- minicore: result
1209enum MyEnum {
1210 Foo,
1211 Bar,
1212}
1213
1214fn foo(x: Result<MyEnum, ()>) {
1215 let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo);
1216 $0if let Ok(MyEnum::Foo) = bar {
1217 ()
1218 } else {
1219 ()
1220 }
1221}
1222"#,
1223 r#"
1224enum MyEnum {
1225 Foo,
1226 Bar,
1227}
1228
1229fn foo(x: Result<MyEnum, ()>) {
1230 let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo);
1231 match bar {
1232 Ok(MyEnum::Foo) => (),
1233 _ => (),
1234 }
1235}
1236"#,
1237 );
1238 }
1239
1240 #[test]
1241 fn test_if_let_with_match_nested_record() {
1242 check_assist(
1243 replace_if_let_with_match,
1244 r#"
1245//- minicore: result
1246struct MyStruct {
1247 foo: i32,
1248 bar: i32,
1249}
1250
1251fn foo(x: Result<MyStruct, ()>) {
1252 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1253 $0if let Ok(MyStruct { foo, bar }) = bar {
1254 ()
1255 } else {
1256 ()
1257 }
1258}
1259"#,
1260 r#"
1261struct MyStruct {
1262 foo: i32,
1263 bar: i32,
1264}
1265
1266fn foo(x: Result<MyStruct, ()>) {
1267 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1268 match bar {
1269 Ok(MyStruct { foo, bar }) => (),
1270 Err(_) => (),
1271 }
1272}
1273"#,
1274 );
1275
1276 check_assist(
1277 replace_if_let_with_match,
1278 r#"
1279//- minicore: result
1280struct MyStruct {
1281 foo: i32,
1282 bar: i32,
1283}
1284
1285fn foo(x: Result<MyStruct, ()>) {
1286 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1287 $0if let Ok(MyStruct { foo, bar: 12 }) = bar {
1288 ()
1289 } else {
1290 ()
1291 }
1292}
1293"#,
1294 r#"
1295struct MyStruct {
1296 foo: i32,
1297 bar: i32,
1298}
1299
1300fn foo(x: Result<MyStruct, ()>) {
1301 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1302 match bar {
1303 Ok(MyStruct { foo, bar: 12 }) => (),
1304 _ => (),
1305 }
1306}
1307"#,
1308 );
1309
1310 check_assist(
1311 replace_if_let_with_match,
1312 r#"
1313//- minicore: result
1314struct MyStruct {
1315 foo: i32,
1316 bar: i32,
1317}
1318
1319fn foo(x: Result<MyStruct, ()>) {
1320 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1321 $0if let Ok(MyStruct { foo, .. }) = bar {
1322 ()
1323 } else {
1324 ()
1325 }
1326}
1327"#,
1328 r#"
1329struct MyStruct {
1330 foo: i32,
1331 bar: i32,
1332}
1333
1334fn foo(x: Result<MyStruct, ()>) {
1335 let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
1336 match bar {
1337 Ok(MyStruct { foo, .. }) => (),
1338 Err(_) => (),
1339 }
1340}
1341"#,
1342 );
1343
1344 check_assist(
1345 replace_if_let_with_match,
1346 r#"
1347//- minicore: result
1348enum MyEnum {
1349 Foo(i32, i32),
1350 Bar { a: i32, b: i32 },
1351}
1352
1353fn foo(x: Result<MyEnum, ()>) {
1354 let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2));
1355 $0if let Ok(MyEnum::Bar { a, b }) = bar {
1356 ()
1357 } else {
1358 ()
1359 }
1360}
1361"#,
1362 r#"
1363enum MyEnum {
1364 Foo(i32, i32),
1365 Bar { a: i32, b: i32 },
1366}
1367
1368fn foo(x: Result<MyEnum, ()>) {
1369 let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2));
1370 match bar {
1371 Ok(MyEnum::Bar { a, b }) => (),
1372 _ => (),
1373 }
1374}
1375"#,
1376 );
1377 }
1378
1379 #[test]
1380 fn test_if_let_with_match_nested_ident() {
1381 check_assist(
1382 replace_if_let_with_match,
1383 r#"
1384//- minicore: result
1385fn foo(x: Result<i32, ()>) {
1386 let bar: Result<i32, ()> = Ok(1);
1387 $0if let Ok(a @ 1..2) = bar {
1388 ()
1389 } else {
1390 ()
1391 }
1392}
1393"#,
1394 r#"
1395fn foo(x: Result<i32, ()>) {
1396 let bar: Result<i32, ()> = Ok(1);
1397 match bar {
1398 Ok(a @ 1..2) => (),
1399 _ => (),
1400 }
1401}
1402"#,
1403 );
1404
1405 check_assist(
1406 replace_if_let_with_match,
1407 r#"
1408//- minicore: result
1409fn foo(x: Result<i32, ()>) {
1410 let bar: Result<i32, ()> = Ok(1);
1411 $0if let Ok(a) = bar {
1412 ()
1413 } else {
1414 ()
1415 }
1416}
1417"#,
1418 r#"
1419fn foo(x: Result<i32, ()>) {
1420 let bar: Result<i32, ()> = Ok(1);
1421 match bar {
1422 Ok(a) => (),
1423 Err(_) => (),
1424 }
1425}
1426"#,
1427 );
1428
1429 check_assist(
1430 replace_if_let_with_match,
1431 r#"
1432//- minicore: result
1433fn foo(x: Result<i32, ()>) {
1434 let bar: Result<i32, ()> = Ok(1);
1435 $0if let Ok(a @ b @ c @ d) = bar {
1436 ()
1437 } else {
1438 ()
1439 }
1440}
1441"#,
1442 r#"
1443fn foo(x: Result<i32, ()>) {
1444 let bar: Result<i32, ()> = Ok(1);
1445 match bar {
1446 Ok(a @ b @ c @ d) => (),
1447 Err(_) => (),
1448 }
1449}
1450"#,
1451 );
1452 }
1453
1454 #[test]
1455 fn test_replace_match_with_if_let_unwraps_simple_expressions() {
1456 check_assist(
1457 replace_match_with_if_let,
1458 r#"
1459impl VariantData {
1460 pub fn is_struct(&self) -> bool {
1461 $0match *self {
1462 VariantData::Struct(..) => true,
1463 _ => false,
1464 }
1465 }
1466} "#,
1467 r#"
1468impl VariantData {
1469 pub fn is_struct(&self) -> bool {
1470 if let VariantData::Struct(..) = *self {
1471 true
1472 } else {
1473 false
1474 }
1475 }
1476} "#,
1477 )
1478 }
1479
1480 #[test]
1481 fn test_replace_match_with_if_let_doesnt_unwrap_multiline_expressions() {
1482 check_assist(
1483 replace_match_with_if_let,
1484 r#"
1485fn foo() {
1486 $0match a {
1487 VariantData::Struct(..) => {
1488 bar(
1489 123
1490 )
1491 }
1492 _ => false,
1493 }
1494} "#,
1495 r#"
1496fn foo() {
1497 if let VariantData::Struct(..) = a {
1498 bar(
1499 123
1500 )
1501 } else {
1502 false
1503 }
1504} "#,
1505 )
1506 }
1507
1508 #[test]
1509 fn replace_match_with_if_let_target() {
1510 check_assist_target(
1511 replace_match_with_if_let,
1512 r#"
1513impl VariantData {
1514 pub fn is_struct(&self) -> bool {
1515 $0match *self {
1516 VariantData::Struct(..) => true,
1517 _ => false,
1518 }
1519 }
1520} "#,
1521 r#"match *self {
1522 VariantData::Struct(..) => true,
1523 _ => false,
1524 }"#,
1525 );
1526 }
1527
1528 #[test]
1529 fn special_case_option_match_to_if_let() {
1530 check_assist(
1531 replace_match_with_if_let,
1532 r#"
1533//- minicore: option
1534fn foo(x: Option<i32>) {
1535 $0match x {
1536 Some(x) => println!("{}", x),
1537 None => println!("none"),
1538 }
1539}
1540"#,
1541 r#"
1542fn foo(x: Option<i32>) {
1543 if let Some(x) = x {
1544 println!("{}", x)
1545 } else {
1546 println!("none")
1547 }
1548}
1549"#,
1550 );
1551 }
1552
1553 #[test]
1554 fn special_case_result_match_to_if_let() {
1555 check_assist(
1556 replace_match_with_if_let,
1557 r#"
1558//- minicore: result
1559fn foo(x: Result<i32, ()>) {
1560 $0match x {
1561 Ok(x) => println!("{}", x),
1562 Err(_) => println!("none"),
1563 }
1564}
1565"#,
1566 r#"
1567fn foo(x: Result<i32, ()>) {
1568 if let Ok(x) = x {
1569 println!("{}", x)
1570 } else {
1571 println!("none")
1572 }
1573}
1574"#,
1575 );
1576 }
1577
1578 #[test]
1579 fn nested_indent_match_to_if_let() {
1580 check_assist(
1581 replace_match_with_if_let,
1582 r#"
1583fn main() {
1584 if true {
1585 $0match path.strip_prefix(root_path) {
1586 Ok(rel_path) => {
1587 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
1588 Some((*id, rel_path))
1589 }
1590 _ => None,
1591 }
1592 }
1593}
1594"#,
1595 r#"
1596fn main() {
1597 if true {
1598 if let Ok(rel_path) = path.strip_prefix(root_path) {
1599 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
1600 Some((*id, rel_path))
1601 } else {
1602 None
1603 }
1604 }
1605}
1606"#,
1607 )
1608 }
1609
1610 #[test]
1611 fn replace_match_with_if_let_empty_wildcard_expr() {
1612 check_assist(
1613 replace_match_with_if_let,
1614 r#"
1615fn main() {
1616 $0match path.strip_prefix(root_path) {
1617 Ok(rel_path) => println!("{}", rel_path),
1618 _ => (),
1619 }
1620}
1621"#,
1622 r#"
1623fn main() {
1624 if let Ok(rel_path) = path.strip_prefix(root_path) {
1625 println!("{}", rel_path)
1626 }
1627}
1628"#,
1629 )
1630 }
1631
1632 #[test]
1633 fn replace_match_with_if_let_number_body() {
1634 check_assist(
1635 replace_match_with_if_let,
1636 r#"
1637fn main() {
1638 $0match Ok(()) {
1639 Ok(()) => {},
1640 Err(_) => 0,
1641 }
1642}
1643"#,
1644 r#"
1645fn main() {
1646 if let Err(_) = Ok(()) {
1647 0
1648 }
1649}
1650"#,
1651 )
1652 }
1653
1654 #[test]
1655 fn replace_match_with_if_let_exhaustive() {
1656 check_assist(
1657 replace_match_with_if_let,
1658 r#"
1659fn print_source(def_source: ModuleSource) {
1660 match def_so$0urce {
1661 ModuleSource::SourceFile(..) => { println!("source file"); }
1662 ModuleSource::Module(..) => { println!("module"); }
1663 }
1664}
1665"#,
1666 r#"
1667fn print_source(def_source: ModuleSource) {
1668 if let ModuleSource::SourceFile(..) = def_source { println!("source file"); } else { println!("module"); }
1669}
1670"#,
1671 )
1672 }
1673
1674 #[test]
1675 fn replace_match_with_if_let_prefer_name_bind() {
1676 check_assist(
1677 replace_match_with_if_let,
1678 r#"
1679fn foo() {
1680 match $0Foo(0) {
1681 Foo(_) => (),
1682 Bar(bar) => println!("bar {}", bar),
1683 }
1684}
1685"#,
1686 r#"
1687fn foo() {
1688 if let Bar(bar) = Foo(0) {
1689 println!("bar {}", bar)
1690 }
1691}
1692"#,
1693 );
1694 check_assist(
1695 replace_match_with_if_let,
1696 r#"
1697fn foo() {
1698 match $0Foo(0) {
1699 Bar(bar) => println!("bar {}", bar),
1700 Foo(_) => (),
1701 }
1702}
1703"#,
1704 r#"
1705fn foo() {
1706 if let Bar(bar) = Foo(0) {
1707 println!("bar {}", bar)
1708 }
1709}
1710"#,
1711 );
1712 }
1713
1714 #[test]
1715 fn replace_match_with_if_let_prefer_nonempty_body() {
1716 check_assist(
1717 replace_match_with_if_let,
1718 r#"
1719fn foo() {
1720 match $0Ok(0) {
1721 Ok(value) => {},
1722 Err(err) => eprintln!("{}", err),
1723 }
1724}
1725"#,
1726 r#"
1727fn foo() {
1728 if let Err(err) = Ok(0) {
1729 eprintln!("{}", err)
1730 }
1731}
1732"#,
1733 );
1734 check_assist(
1735 replace_match_with_if_let,
1736 r#"
1737fn foo() {
1738 match $0Ok(0) {
1739 Err(err) => eprintln!("{}", err),
1740 Ok(value) => {},
1741 }
1742}
1743"#,
1744 r#"
1745fn foo() {
1746 if let Err(err) = Ok(0) {
1747 eprintln!("{}", err)
1748 }
1749}
1750"#,
1751 );
1752 }
1753
1754 #[test]
1755 fn replace_match_with_if_let_rejects_double_name_bindings() {
1756 check_assist_not_applicable(
1757 replace_match_with_if_let,
1758 r#"
1759fn foo() {
1760 match $0Foo(0) {
1761 Foo(foo) => println!("bar {}", foo),
1762 Bar(bar) => println!("bar {}", bar),
1763 }
1764}
1765"#,
1766 );
1767 }
1768
1769 #[test]
1770 fn test_replace_match_with_if_let_keeps_unsafe_block() {
1771 check_assist(
1772 replace_match_with_if_let,
1773 r#"
1774impl VariantData {
1775 pub fn is_struct(&self) -> bool {
1776 $0match *self {
1777 VariantData::Struct(..) => true,
1778 _ => unsafe { unreachable_unchecked() },
1779 }
1780 }
1781} "#,
1782 r#"
1783impl VariantData {
1784 pub fn is_struct(&self) -> bool {
1785 if let VariantData::Struct(..) = *self {
1786 true
1787 } else {
1788 unsafe { unreachable_unchecked() }
1789 }
1790 }
1791} "#,
1792 )
1793 }
1794
1795 #[test]
1796 fn test_replace_match_with_if_let_forces_else() {
1797 check_assist(
1798 replace_match_with_if_let,
1799 r#"
1800fn main() {
1801 match$0 0 {
1802 0 => (),
1803 _ => code(),
1804 }
1805}
1806"#,
1807 r#"
1808fn main() {
1809 if let 0 = 0 {
1810 ()
1811 } else {
1812 code()
1813 }
1814}
1815"#,
1816 )
1817 }
1818
1819 #[test]
1820 fn test_replace_match_with_if_bool() {
1821 check_assist(
1822 replace_match_with_if_let,
1823 r#"
1824fn main() {
1825 match$0 b {
1826 true => (),
1827 _ => code(),
1828 }
1829}
1830"#,
1831 r#"
1832fn main() {
1833 if b {
1834 ()
1835 } else {
1836 code()
1837 }
1838}
1839"#,
1840 );
1841 check_assist(
1842 replace_match_with_if_let,
1843 r#"
1844fn main() {
1845 match$0 b {
1846 false => code(),
1847 true => (),
1848 }
1849}
1850"#,
1851 r#"
1852fn main() {
1853 if !b {
1854 code()
1855 }
1856}
1857"#,
1858 );
1859 check_assist(
1860 replace_match_with_if_let,
1861 r#"
1862fn main() {
1863 match$0 b {
1864 false => (),
1865 true => code(),
1866 }
1867}
1868"#,
1869 r#"
1870fn main() {
1871 if b {
1872 code()
1873 }
1874}
1875"#,
1876 )
1877 }
1878
1879 #[test]
1880 fn test_replace_match_with_if_let_chain() {
1881 check_assist(
1882 replace_match_with_if_let,
1883 r#"
1884fn main() {
1885 match$0 Some(0) {
1886 Some(n) if n % 2 == 0 && n != 6 => (),
1887 _ => code(),
1888 }
1889}
1890"#,
1891 r#"
1892fn main() {
1893 if let Some(n) = Some(0) && n % 2 == 0 && n != 6 {
1894 ()
1895 } else {
1896 code()
1897 }
1898}
1899"#,
1900 )
1901 }
1902
1903 #[test]
1904 fn test_replace_match_with_if_let_not_applicable_pat2_is_ident_pat() {
1905 check_assist_not_applicable(
1906 replace_match_with_if_let,
1907 r"
1908fn test(a: i32) {
1909 match$0 a {
1910 1 => code(),
1911 other => code(other),
1912 }
1913}
1914",
1915 )
1916 }
1917}