Skip to main content

ide_assists/handlers/
unwrap_branch.rs

1use either::Either;
2use syntax::{
3    AstNode, SyntaxElement, SyntaxKind, SyntaxNode, T,
4    ast::{
5        self,
6        edit::{AstNodeEdit, IndentLevel},
7        syntax_factory::SyntaxFactory,
8    },
9    match_ast,
10    syntax_editor::{Element, Position, SyntaxEditor},
11};
12
13use crate::{AssistContext, AssistId, Assists};
14
15// Assist: unwrap_branch
16//
17// This assist removes if...else, for, while and loop control statements to just keep the body.
18//
19// ```
20// fn foo() {
21//     if true {$0
22//         println!("foo");
23//     }
24// }
25// ```
26// ->
27// ```
28// fn foo() {
29//     println!("foo");
30// }
31// ```
32pub(crate) fn unwrap_branch(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
33    let (editor, _) = SyntaxEditor::new(ctx.source_file().syntax().clone());
34    let place = unwrap_branch_place(ctx)?;
35    let target = place.syntax().text_range();
36    let block = wrap_block_raw(&place, editor.make());
37    let mut container = place.syntax().clone();
38    let mut replacement = block.clone();
39    let mut prefer_container = None;
40
41    let from_indent = place.indent_level();
42    let into_indent = loop {
43        let parent = container.parent()?;
44        container = match_ast! {
45            match parent {
46                ast::ForExpr(it) => it.syntax().clone(),
47                ast::LoopExpr(it) => it.syntax().clone(),
48                ast::WhileExpr(it) => it.syntax().clone(),
49                ast::MatchArm(it) => it.parent_match().syntax().clone(),
50                ast::LetElse(it) => it.syntax().parent()?,
51                ast::LetStmt(it) => {
52                    replacement = wrap_let(&it, replacement);
53                    prefer_container = Some(it.syntax().clone());
54                    it.syntax().clone()
55                },
56                ast::IfExpr(it) => {
57                    prefer_container.get_or_insert_with(|| {
58                        if let Some(else_branch) = it.else_branch()
59                            && *else_branch.syntax() == container
60                        {
61                            else_branch.syntax().clone()
62                        } else {
63                            it.syntax().clone()
64                        }
65                    });
66                    it.syntax().clone()
67                },
68                ast::ExprStmt(it) => it.syntax().clone(),
69                ast::StmtList(it) => break it.indent_level(),
70                _ => return None,
71            }
72        };
73        if ast::MatchArm::cast(container.parent()?).is_some() {
74            replacement = editor.make().tail_only_block_expr(replacement.into());
75            prefer_container = Some(container.clone());
76            break IndentLevel::from_node(&container);
77        }
78    };
79    let is_branch =
80        !block.is_standalone() || place.syntax().parent().and_then(ast::MatchArm::cast).is_some();
81    let label = if is_branch { "Unwrap branch" } else { "Unwrap block" };
82    let replacement = replacement.stmt_list()?;
83
84    acc.add(AssistId::refactor_rewrite("unwrap_branch"), label, target, |builder| {
85        let replacement = replacement.dedent(from_indent).indent(into_indent);
86        let mut replacement = extract_statements(replacement);
87        let container = prefer_container.unwrap_or(container);
88
89        if ast::ExprStmt::can_cast(container.kind())
90            && block.tail_expr().is_some_and(|it| !it.is_block_like())
91        {
92            replacement.push(editor.make().token(T![;]).into());
93        }
94
95        editor.replace_with_many(&container, replacement);
96        delete_else_before(container, &editor);
97
98        builder.add_file_edits(ctx.vfs_file_id(), editor);
99    })
100}
101
102// Assist: unwrap_block
103//
104// This assist removes braces and unwrap single expressions block.
105//
106// ```
107// fn foo() {
108//     match () {
109//         _ => {$0
110//             bar()
111//         }
112//     }
113// }
114// ```
115// ->
116// ```
117// fn foo() {
118//     match () {
119//         _ => bar(),
120//     }
121// }
122// ```
123pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
124    let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
125    let block = l_curly_token.parent_ancestors().nth(1).and_then(ast::BlockExpr::cast)?;
126    let target = block.syntax().text_range();
127    let tail_expr = block.tail_expr()?;
128    let stmt_list = block.stmt_list()?;
129    let container = Either::<ast::MatchArm, ast::ClosureExpr>::cast(block.syntax().parent()?)?;
130
131    if stmt_list.statements().next().is_some() {
132        return None;
133    }
134
135    acc.add(AssistId::refactor_rewrite("unwrap_block"), "Unwrap block", target, |builder| {
136        let editor = builder.make_editor(block.syntax());
137        let replacement = stmt_list.dedent(tail_expr.indent_level()).indent(block.indent_level());
138        let mut replacement = extract_statements(replacement);
139
140        if container.left().is_some_and(|it| it.comma_token().is_none())
141            && !tail_expr.is_block_like()
142        {
143            replacement.push(editor.make().token(T![,]).into());
144        }
145
146        editor.replace_with_many(block.syntax(), replacement);
147        builder.add_file_edits(ctx.vfs_file_id(), editor);
148    })
149}
150
151fn delete_else_before(container: SyntaxNode, editor: &SyntaxEditor) {
152    let make = editor.make();
153    let Some(else_token) = container
154        .siblings_with_tokens(syntax::Direction::Prev)
155        .skip(1)
156        .map_while(|it| it.into_token())
157        .find(|it| it.kind() == T![else])
158    else {
159        return;
160    };
161    itertools::chain(else_token.prev_token(), else_token.next_token())
162        .filter(|it| it.kind() == SyntaxKind::WHITESPACE)
163        .for_each(|it| editor.delete(it));
164    let indent = IndentLevel::from_node(&container);
165    let newline = make.whitespace(&format!("\n{indent}"));
166    editor.replace(else_token, newline);
167}
168
169fn wrap_let(assign: &ast::LetStmt, replacement: ast::BlockExpr) -> ast::BlockExpr {
170    let try_wrap_assign = || {
171        let initializer = assign.initializer()?.syntax().syntax_element();
172        let (editor, replacement) = SyntaxEditor::with_ast_node(&replacement);
173        let tail_expr = replacement.tail_expr()?;
174        let before =
175            assign.syntax().children_with_tokens().take_while(|it| *it != initializer).collect();
176        let after = assign
177            .syntax()
178            .children_with_tokens()
179            .skip_while(|it| *it != initializer)
180            .skip(1)
181            .collect();
182
183        editor.insert_all(Position::before(tail_expr.syntax()), before);
184        editor.insert_all(Position::after(tail_expr.syntax()), after);
185        ast::BlockExpr::cast(editor.finish().new_root().clone())
186    };
187    try_wrap_assign().unwrap_or(replacement)
188}
189
190fn unwrap_branch_place(ctx: &AssistContext<'_, '_>) -> Option<ast::Expr> {
191    if let Some(l_curly_token) = ctx.find_token_syntax_at_offset(T!['{']) {
192        let block = l_curly_token.parent_ancestors().nth(1).and_then(ast::BlockExpr::cast)?;
193        Some(block.into())
194    } else if let Some(fat_arrow_token) = ctx.find_token_syntax_at_offset(T![=>]) {
195        let match_arm = fat_arrow_token.parent().and_then(ast::MatchArm::cast)?;
196        match_arm.expr()
197    } else {
198        None
199    }
200}
201
202fn extract_statements(stmt_list: ast::StmtList) -> Vec<SyntaxElement> {
203    let mut elements = stmt_list
204        .syntax()
205        .children_with_tokens()
206        .filter(|it| !matches!(it.kind(), T!['{'] | T!['}']))
207        .skip_while(|it| it.kind() == SyntaxKind::WHITESPACE)
208        .collect::<Vec<_>>();
209    while elements.pop_if(|it| it.kind() == SyntaxKind::WHITESPACE).is_some() {}
210    elements
211}
212
213fn wrap_block_raw(expr: &ast::Expr, make: &SyntaxFactory) -> ast::BlockExpr {
214    if let ast::Expr::BlockExpr(block) = expr {
215        block.clone()
216    } else {
217        make.tail_only_block_expr(expr.indent(1.into()))
218    }
219}
220
221#[cfg(test)]
222mod tests {
223    use crate::tests::{
224        check_assist, check_assist_by_label, check_assist_not_applicable,
225        check_assist_not_applicable_by_label, check_assist_with_label,
226    };
227
228    use super::*;
229
230    #[test]
231    fn unwrap_tail_expr_block() {
232        check_assist(
233            unwrap_branch,
234            r#"
235fn main() {
236    $0{
237        92
238    }
239}
240"#,
241            r#"
242fn main() {
243    92
244}
245"#,
246        )
247    }
248
249    #[test]
250    fn unwrap_stmt_expr_block() {
251        check_assist(
252            unwrap_branch,
253            r#"
254fn main() {
255    $0{
256        92;
257    }
258    ()
259}
260"#,
261            r#"
262fn main() {
263    92;
264    ()
265}
266"#,
267        );
268        check_assist(
269            unwrap_branch,
270            r#"
271fn main() {
272    $0{
273        92
274    }
275    ()
276}
277"#,
278            r#"
279fn main() {
280    92;
281    ()
282}
283"#,
284        );
285    }
286
287    #[test]
288    fn simple_if() {
289        check_assist(
290            unwrap_branch,
291            r#"
292fn main() {
293    bar();
294    if true {$0
295        foo();
296
297        // comment
298        bar();
299    } else {
300        println!("bar");
301    }
302}
303"#,
304            r#"
305fn main() {
306    bar();
307    foo();
308
309    // comment
310    bar();
311}
312"#,
313        );
314    }
315
316    #[test]
317    fn simple_if_else() {
318        check_assist(
319            unwrap_branch,
320            r#"
321fn main() {
322    bar();
323    if true {
324        foo();
325
326        // comment
327        bar();
328    } else {$0
329        println!("bar");
330    }
331}
332"#,
333            r#"
334fn main() {
335    bar();
336    if true {
337        foo();
338
339        // comment
340        bar();
341    }
342    println!("bar");
343}
344"#,
345        );
346    }
347
348    #[test]
349    fn simple_if_else_if() {
350        check_assist(
351            unwrap_branch,
352            r#"
353fn main() {
354    // bar();
355    if true {
356        println!("true");
357
358        // comment
359        // bar();
360    } else if false {$0
361        println!("bar");
362    } else {
363        println!("foo");
364    }
365}
366"#,
367            r#"
368fn main() {
369    // bar();
370    if true {
371        println!("true");
372
373        // comment
374        // bar();
375    }
376    println!("bar");
377}
378"#,
379        );
380    }
381
382    #[test]
383    fn simple_if_else_if_nested() {
384        check_assist(
385            unwrap_branch,
386            r#"
387fn main() {
388    // bar();
389    if true {
390        println!("true");
391
392        // comment
393        // bar();
394    } else if false {
395        println!("bar");
396    } else if true {$0
397        println!("foo");
398    }
399}
400"#,
401            r#"
402fn main() {
403    // bar();
404    if true {
405        println!("true");
406
407        // comment
408        // bar();
409    } else if false {
410        println!("bar");
411    }
412    println!("foo");
413}
414"#,
415        );
416    }
417
418    #[test]
419    fn simple_if_else_if_nested_else() {
420        check_assist(
421            unwrap_branch,
422            r#"
423fn main() {
424    // bar();
425    if true {
426        println!("true");
427
428        // comment
429        // bar();
430    } else if false {
431        println!("bar");
432    } else if true {
433        println!("foo");
434    } else {$0
435        println!("else");
436    }
437}
438"#,
439            r#"
440fn main() {
441    // bar();
442    if true {
443        println!("true");
444
445        // comment
446        // bar();
447    } else if false {
448        println!("bar");
449    } else if true {
450        println!("foo");
451    }
452    println!("else");
453}
454"#,
455        );
456    }
457
458    #[test]
459    fn simple_if_else_if_nested_middle() {
460        check_assist(
461            unwrap_branch,
462            r#"
463fn main() {
464    // bar();
465    if true {
466        println!("true");
467
468        // comment
469        // bar();
470    } else if false {
471        println!("bar");
472    } else if true {$0
473        println!("foo");
474    } else {
475        println!("else");
476    }
477}
478"#,
479            r#"
480fn main() {
481    // bar();
482    if true {
483        println!("true");
484
485        // comment
486        // bar();
487    } else if false {
488        println!("bar");
489    }
490    println!("foo");
491}
492"#,
493        );
494    }
495
496    #[test]
497    fn simple_if_bad_cursor_position() {
498        check_assist_not_applicable(
499            unwrap_branch,
500            r#"
501fn main() {
502    bar();$0
503    if true {
504        foo();
505
506        // comment
507        bar();
508    } else {
509        println!("bar");
510    }
511}
512"#,
513        );
514    }
515
516    #[test]
517    fn simple_for() {
518        check_assist(
519            unwrap_branch,
520            r#"
521fn main() {
522    for i in 0..5 {$0
523        if true {
524            foo();
525
526            // comment
527            bar();
528        } else {
529            println!("bar");
530        }
531    }
532}
533"#,
534            r#"
535fn main() {
536    if true {
537        foo();
538
539        // comment
540        bar();
541    } else {
542        println!("bar");
543    }
544}
545"#,
546        );
547    }
548
549    #[test]
550    fn simple_if_in_for() {
551        check_assist(
552            unwrap_branch,
553            r#"
554fn main() {
555    for i in 0..5 {
556        if true {$0
557            foo();
558
559            // comment
560            bar();
561        } else {
562            println!("bar");
563        }
564    }
565}
566"#,
567            r#"
568fn main() {
569    for i in 0..5 {
570        foo();
571
572        // comment
573        bar();
574    }
575}
576"#,
577        );
578    }
579
580    #[test]
581    fn simple_if_in_match_arm() {
582        check_assist(
583            unwrap_branch,
584            r#"
585fn main() {
586    match 1 {
587        1 => if true {$0
588            foo();
589        }
590        _ => (),
591    }
592}
593"#,
594            r#"
595fn main() {
596    match 1 {
597        1 => {
598            foo();
599        }
600        _ => (),
601    }
602}
603"#,
604        );
605
606        check_assist(
607            unwrap_branch,
608            r#"
609fn main() {
610    match 1 {
611        1 => if true {
612            foo();
613        } else {$0
614            bar();
615        }
616        _ => (),
617    }
618}
619"#,
620            r#"
621fn main() {
622    match 1 {
623        1 => {
624            bar();
625        }
626        _ => (),
627    }
628}
629"#,
630        );
631    }
632
633    #[test]
634    fn simple_match_in_match_arm() {
635        check_assist(
636            unwrap_branch,
637            r#"
638fn main() {
639    match 1 {
640        1 => match () {
641            _ => {$0
642                foo();
643            }
644        }
645        _ => (),
646    }
647}
648"#,
649            r#"
650fn main() {
651    match 1 {
652        1 => {
653            foo();
654        }
655        _ => (),
656    }
657}
658"#,
659        );
660    }
661
662    #[test]
663    fn simple_loop() {
664        check_assist(
665            unwrap_branch,
666            r#"
667fn main() {
668    loop {$0
669        if true {
670            foo();
671
672            // comment
673            bar();
674        } else {
675            println!("bar");
676        }
677    }
678}
679"#,
680            r#"
681fn main() {
682    if true {
683        foo();
684
685        // comment
686        bar();
687    } else {
688        println!("bar");
689    }
690}
691"#,
692        );
693    }
694
695    #[test]
696    fn simple_while() {
697        check_assist(
698            unwrap_branch,
699            r#"
700fn main() {
701    while true {$0
702        if true {
703            foo();
704
705            // comment
706            bar();
707        } else {
708            println!("bar");
709        }
710    }
711}
712"#,
713            r#"
714fn main() {
715    if true {
716        foo();
717
718        // comment
719        bar();
720    } else {
721        println!("bar");
722    }
723}
724"#,
725        );
726    }
727
728    #[test]
729    fn simple_let_else() {
730        check_assist(
731            unwrap_branch,
732            r#"
733fn main() {
734    let Some(2) = None else {$0
735        return;
736    };
737}
738"#,
739            r#"
740fn main() {
741    return;
742}
743"#,
744        );
745        check_assist(
746            unwrap_branch,
747            r#"
748fn main() {
749    let Some(2) = None else {$0
750        return
751    };
752}
753"#,
754            r#"
755fn main() {
756    return
757}
758"#,
759        );
760    }
761
762    #[test]
763    fn unwrap_match_arm() {
764        check_assist(
765            unwrap_branch,
766            r#"
767fn main() {
768    match rel_path {
769        Ok(rel_path) => {$0
770            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
771            Some((*id, rel_path))
772        }
773        Err(_) => None,
774    }
775}
776"#,
777            r#"
778fn main() {
779    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
780    Some((*id, rel_path))
781}
782"#,
783        );
784    }
785
786    #[test]
787    fn unwrap_match_arm_in_let() {
788        check_assist(
789            unwrap_branch,
790            r#"
791fn main() {
792    let value = match rel_path {
793        Ok(rel_path) => {$0
794            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
795            Some((*id, rel_path))
796        }
797        Err(_) => None,
798    };
799}
800"#,
801            r#"
802fn main() {
803    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
804    let value = Some((*id, rel_path));
805}
806"#,
807        );
808    }
809
810    #[test]
811    fn unwrap_match_arm_without_block() {
812        check_assist(
813            unwrap_branch,
814            r#"
815fn main() {
816    match rel_path {
817        Ok(rel_path) $0=> Foo {
818            rel_path,
819        },
820        Err(_) => None,
821    }
822}
823"#,
824            r#"
825fn main() {
826    Foo {
827        rel_path,
828    }
829}
830"#,
831        );
832    }
833
834    #[test]
835    fn simple_if_in_while_bad_cursor_position() {
836        check_assist_not_applicable(
837            unwrap_branch,
838            r#"
839fn main() {
840    while true {
841        if true {
842            foo();$0
843
844            // comment
845            bar();
846        } else {
847            println!("bar");
848        }
849    }
850}
851"#,
852        );
853    }
854
855    #[test]
856    fn simple_single_line() {
857        check_assist(
858            unwrap_branch,
859            r#"
860fn main() {
861    {$0 0 }
862}
863"#,
864            r#"
865fn main() {
866    0
867}
868"#,
869        );
870    }
871
872    #[test]
873    fn simple_nested_block() {
874        check_assist(
875            unwrap_branch,
876            r#"
877fn main() {
878    $0{
879        {
880            3
881        }
882    }
883}
884"#,
885            r#"
886fn main() {
887    {
888        3
889    }
890}
891"#,
892        );
893    }
894
895    #[test]
896    fn nested_single_line() {
897        check_assist(
898            unwrap_branch,
899            r#"
900fn main() {
901    {$0 { println!("foo"); } }
902}
903"#,
904            r#"
905fn main() {
906    { println!("foo"); }
907}
908"#,
909        );
910
911        check_assist(
912            unwrap_branch,
913            r#"
914fn main() {
915    {$0 { 0 } }
916}
917"#,
918            r#"
919fn main() {
920    { 0 }
921}
922"#,
923        );
924    }
925
926    #[test]
927    fn simple_if_single_line() {
928        check_assist(
929            unwrap_branch,
930            r#"
931fn main() {
932    if true {$0 /* foo */ foo() } else { bar() /* bar */}
933}
934"#,
935            r#"
936fn main() {
937    /* foo */ foo()
938}
939"#,
940        );
941    }
942
943    #[test]
944    fn if_single_statement() {
945        check_assist(
946            unwrap_branch,
947            r#"
948fn main() {
949    if true {$0
950        return 3;
951    }
952}
953"#,
954            r#"
955fn main() {
956    return 3;
957}
958"#,
959        );
960    }
961
962    #[test]
963    fn multiple_statements() {
964        check_assist(
965            unwrap_branch,
966            r#"
967fn main() -> i32 {
968    if 2 > 1 {$0
969        let a = 5;
970        return 3;
971    }
972    5
973}
974"#,
975            r#"
976fn main() -> i32 {
977    let a = 5;
978    return 3;
979    5
980}
981"#,
982        );
983    }
984
985    #[test]
986    fn unwrap_block_in_let_initializers() {
987        // https://github.com/rust-lang/rust-analyzer/issues/13679
988        check_assist(
989            unwrap_branch,
990            r#"
991fn main() {
992    let x = {$0
993        bar
994    };
995}
996"#,
997            r#"
998fn main() {
999    let x = bar;
1000}
1001"#,
1002        );
1003        check_assist(
1004            unwrap_branch,
1005            r#"
1006fn main() -> i32 {
1007    let _ = {$01; 2};
1008}
1009"#,
1010            r#"
1011fn main() -> i32 {
1012    1; let _ = 2;
1013}
1014"#,
1015        );
1016        check_assist(
1017            unwrap_branch,
1018            r#"
1019fn main() -> i32 {
1020    let mut a = {$01; 2};
1021}
1022"#,
1023            r#"
1024fn main() -> i32 {
1025    1; let mut a = 2;
1026}
1027"#,
1028        );
1029        check_assist(
1030            unwrap_branch,
1031            r#"
1032fn main() -> i32 {
1033    let mut a = {$0
1034        1;
1035        2;
1036        3
1037    };
1038}
1039"#,
1040            r#"
1041fn main() -> i32 {
1042    1;
1043    2;
1044    let mut a = 3;
1045}
1046"#,
1047        );
1048    }
1049
1050    #[test]
1051    fn unwrap_if_in_let_initializers() {
1052        // https://github.com/rust-lang/rust-analyzer/issues/13679
1053        check_assist(
1054            unwrap_branch,
1055            r#"
1056fn main() {
1057    let a = 1;
1058    let x = if a - 1 == 0 {$0
1059        foo
1060    } else {
1061        bar
1062    };
1063}
1064"#,
1065            r#"
1066fn main() {
1067    let a = 1;
1068    let x = foo;
1069}
1070"#,
1071        );
1072    }
1073
1074    #[test]
1075    fn unwrap_block_with_modifiers() {
1076        // https://github.com/rust-lang/rust-analyzer/issues/17964
1077        check_assist(
1078            unwrap_branch,
1079            r#"
1080fn main() {
1081    unsafe $0{
1082        bar;
1083    }
1084}
1085"#,
1086            r#"
1087fn main() {
1088    bar;
1089}
1090"#,
1091        );
1092        check_assist(
1093            unwrap_branch,
1094            r#"
1095fn main() {
1096    async move $0{
1097        bar;
1098    }
1099}
1100"#,
1101            r#"
1102fn main() {
1103    bar;
1104}
1105"#,
1106        );
1107        check_assist(
1108            unwrap_branch,
1109            r#"
1110fn main() {
1111    try $0{
1112        bar;
1113    }
1114}
1115"#,
1116            r#"
1117fn main() {
1118    bar;
1119}
1120"#,
1121        );
1122    }
1123
1124    #[test]
1125    fn unwrap_block_labels() {
1126        check_assist_with_label(
1127            unwrap_branch,
1128            r#"
1129fn main() {
1130    $0{
1131        bar;
1132    }
1133}
1134"#,
1135            "Unwrap block",
1136        );
1137        check_assist_with_label(
1138            unwrap_branch,
1139            r#"
1140fn main() {
1141    let x = $0{
1142        bar()
1143    };
1144}
1145"#,
1146            "Unwrap block",
1147        );
1148        check_assist_with_label(
1149            unwrap_branch,
1150            r#"
1151fn main() {
1152    let x = if true $0{
1153        bar()
1154    };
1155}
1156"#,
1157            "Unwrap branch",
1158        );
1159        check_assist_with_label(
1160            unwrap_branch,
1161            r#"
1162fn main() {
1163    let x = match () {
1164        () => $0{
1165            bar(),
1166        }
1167    };
1168}
1169"#,
1170            "Unwrap branch",
1171        );
1172        check_assist_with_label(
1173            unwrap_branch,
1174            r#"
1175fn main() {
1176    match () {
1177        () => $0{
1178            bar(),
1179        }
1180    }
1181}
1182"#,
1183            "Unwrap branch",
1184        );
1185    }
1186
1187    #[test]
1188    fn unwrap_block_in_branch() {
1189        check_assist_by_label(
1190            unwrap_block,
1191            r#"
1192fn main() {
1193    match rel_path {
1194        Ok(rel_path) => {$0
1195            if true {
1196                foo()
1197            }
1198        }
1199        Err(_) => None,
1200    }
1201}
1202"#,
1203            r#"
1204fn main() {
1205    match rel_path {
1206        Ok(rel_path) => if true {
1207            foo()
1208        }
1209        Err(_) => None,
1210    }
1211}
1212"#,
1213            "Unwrap block",
1214        );
1215
1216        check_assist_by_label(
1217            unwrap_block,
1218            r#"
1219fn main() {
1220    match rel_path {
1221        Ok(rel_path) => {$0
1222            1 + 2
1223        }
1224        Err(_) => None,
1225    }
1226}
1227"#,
1228            r#"
1229fn main() {
1230    match rel_path {
1231        Ok(rel_path) => 1 + 2,
1232        Err(_) => None,
1233    }
1234}
1235"#,
1236            "Unwrap block",
1237        );
1238    }
1239
1240    #[test]
1241    fn unwrap_block_in_branch_non_standalone() {
1242        check_assist_not_applicable_by_label(
1243            unwrap_block,
1244            r#"
1245fn main() {
1246    match rel_path {
1247        Ok(rel_path) => {
1248            if true {$0
1249                foo()
1250            }
1251        }
1252        Err(_) => None,
1253    }
1254}
1255"#,
1256            "Unwrap block",
1257        );
1258    }
1259
1260    #[test]
1261    fn unwrap_block_in_branch_non_tail_expr_only() {
1262        check_assist_not_applicable_by_label(
1263            unwrap_block,
1264            r#"
1265fn main() {
1266    match rel_path {
1267        Ok(rel_path) => {$0
1268            x;
1269            y
1270        }
1271        Err(_) => None,
1272    }
1273}
1274"#,
1275            "Unwrap block",
1276        );
1277    }
1278
1279    #[test]
1280    fn unwrap_block_in_closure() {
1281        check_assist_by_label(
1282            unwrap_block,
1283            r#"
1284fn main() {
1285    let f = || {$0 foo() };
1286}
1287"#,
1288            r#"
1289fn main() {
1290    let f = || foo();
1291}
1292"#,
1293            "Unwrap block",
1294        );
1295    }
1296}