1use std::iter::once;
2
3use either::Either;
4use hir::{Semantics, TypeInfo};
5use ide_db::{RootDatabase, ty_filter::TryEnum};
6use syntax::{
7 AstNode,
8 SyntaxKind::{CLOSURE_EXPR, FN, FOR_EXPR, LOOP_EXPR, WHILE_EXPR, WHITESPACE},
9 SyntaxNode, T,
10 ast::{
11 self,
12 edit::{AstNodeEdit, IndentLevel},
13 make,
14 },
15};
16
17use crate::{
18 AssistId,
19 assist_context::{AssistContext, Assists},
20 utils::{invert_boolean_expression_legacy, is_never_block},
21};
22
23pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
46 match ctx.find_node_at_offset::<Either<ast::LetStmt, ast::IfExpr>>()? {
47 Either::Left(let_stmt) => let_stmt_to_guarded_return(let_stmt, acc, ctx),
48 Either::Right(if_expr) => if_expr_to_guarded_return(if_expr, acc, ctx),
49 }
50}
51
52fn if_expr_to_guarded_return(
53 if_expr: ast::IfExpr,
54 acc: &mut Assists,
55 ctx: &AssistContext<'_>,
56) -> Option<()> {
57 let else_block = match if_expr.else_branch() {
58 Some(ast::ElseBranch::Block(block_expr)) if is_never_block(&ctx.sema, &block_expr) => {
59 Some(block_expr)
60 }
61 Some(_) => return None,
62 _ => None,
63 };
64
65 let cond = if_expr.condition()?;
66
67 let if_token_range = if_expr.if_token()?.text_range();
68 let if_cond_range = cond.syntax().text_range();
69
70 let cursor_in_range =
71 if_token_range.cover(if_cond_range).contains_range(ctx.selection_trimmed());
72 if !cursor_in_range {
73 return None;
74 }
75
76 let let_chains = flat_let_chain(cond);
77
78 let then_branch = if_expr.then_branch()?;
79 let then_block = then_branch.stmt_list()?;
80
81 let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
82
83 if parent_block.tail_expr()? != if_expr.clone().into() {
84 return None;
85 }
86
87 if is_early_block(&then_block) || is_never_block(&ctx.sema, &then_branch) {
89 return None;
90 }
91
92 let parent_container = parent_block.syntax().parent()?;
93
94 let early_expression = else_block
95 .or_else(|| {
96 early_expression(parent_container, &ctx.sema).map(ast::make::tail_only_block_expr)
97 })?
98 .reset_indent();
99
100 then_block.syntax().first_child_or_token().map(|t| t.kind() == T!['{'])?;
101
102 then_block.syntax().last_child_or_token().filter(|t| t.kind() == T!['}'])?;
103
104 let then_block_items = then_block.dedent(IndentLevel(1));
105
106 let end_of_then = then_block_items.syntax().last_child_or_token()?;
107 let end_of_then = if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
108 end_of_then.prev_sibling_or_token()?
109 } else {
110 end_of_then
111 };
112
113 let target = if_expr.syntax().text_range();
114 acc.add(
115 AssistId::refactor_rewrite("convert_to_guarded_return"),
116 "Convert to guarded return",
117 target,
118 |edit| {
119 let if_indent_level = IndentLevel::from_node(if_expr.syntax());
120 let replacement = let_chains.into_iter().map(|expr| {
121 if let ast::Expr::LetExpr(let_expr) = &expr
122 && let (Some(pat), Some(expr)) = (let_expr.pat(), let_expr.expr())
123 {
124 let let_else_stmt =
126 make::let_else_stmt(pat, None, expr, early_expression.clone());
127 let let_else_stmt = let_else_stmt.indent(if_indent_level);
128 let_else_stmt.syntax().clone()
129 } else {
130 let new_expr = {
132 let then_branch = clean_stmt_block(&early_expression);
133 let cond = invert_boolean_expression_legacy(expr);
134 make::expr_if(cond, then_branch, None).indent(if_indent_level)
135 };
136 new_expr.syntax().clone()
137 }
138 });
139
140 let newline = &format!("\n{if_indent_level}");
141 let then_statements = replacement
142 .enumerate()
143 .flat_map(|(i, node)| {
144 (i != 0)
145 .then(|| make::tokens::whitespace(newline).into())
146 .into_iter()
147 .chain(node.children_with_tokens())
148 })
149 .chain(
150 then_block_items
151 .syntax()
152 .children_with_tokens()
153 .skip(1)
154 .take_while(|i| *i != end_of_then),
155 )
156 .collect();
157 let mut editor = edit.make_editor(if_expr.syntax());
158 editor.replace_with_many(if_expr.syntax(), then_statements);
159 edit.add_file_edits(ctx.vfs_file_id(), editor);
160 },
161 )
162}
163
164fn let_stmt_to_guarded_return(
165 let_stmt: ast::LetStmt,
166 acc: &mut Assists,
167 ctx: &AssistContext<'_>,
168) -> Option<()> {
169 let pat = let_stmt.pat()?;
170 let expr = let_stmt.initializer()?;
171
172 let let_token_range = let_stmt.let_token()?.text_range();
173 let let_pattern_range = pat.syntax().text_range();
174 let cursor_in_range =
175 let_token_range.cover(let_pattern_range).contains_range(ctx.selection_trimmed());
176
177 if !cursor_in_range || let_stmt.let_else().is_some() {
178 return None;
179 }
180
181 let try_enum =
182 ctx.sema.type_of_expr(&expr).and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))?;
183
184 let happy_pattern = try_enum.happy_pattern(pat);
185 let target = let_stmt.syntax().text_range();
186
187 let early_expression: ast::Expr = {
188 let parent_block =
189 let_stmt.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
190 let parent_container = parent_block.syntax().parent()?;
191
192 early_expression(parent_container, &ctx.sema)?
193 };
194
195 acc.add(
196 AssistId::refactor_rewrite("convert_to_guarded_return"),
197 "Convert to guarded return",
198 target,
199 |edit| {
200 let let_indent_level = IndentLevel::from_node(let_stmt.syntax());
201
202 let replacement = {
203 let let_else_stmt = make::let_else_stmt(
204 happy_pattern,
205 let_stmt.ty(),
206 expr,
207 ast::make::tail_only_block_expr(early_expression),
208 );
209 let let_else_stmt = let_else_stmt.indent(let_indent_level);
210 let_else_stmt.syntax().clone()
211 };
212 let mut editor = edit.make_editor(let_stmt.syntax());
213 editor.replace(let_stmt.syntax(), replacement);
214 edit.add_file_edits(ctx.vfs_file_id(), editor);
215 },
216 )
217}
218
219fn early_expression(
220 parent_container: SyntaxNode,
221 sema: &Semantics<'_, RootDatabase>,
222) -> Option<ast::Expr> {
223 let return_none_expr = || {
224 let none_expr = make::expr_path(make::ext::ident_path("None"));
225 make::expr_return(Some(none_expr))
226 };
227 if let Some(fn_) = ast::Fn::cast(parent_container.clone())
228 && let Some(fn_def) = sema.to_def(&fn_)
229 && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &fn_def.ret_type(sema.db))
230 {
231 return Some(return_none_expr());
232 }
233 if let Some(body) = ast::ClosureExpr::cast(parent_container.clone()).and_then(|it| it.body())
234 && let Some(ret_ty) = sema.type_of_expr(&body).map(TypeInfo::original)
235 && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &ret_ty)
236 {
237 return Some(return_none_expr());
238 }
239
240 Some(match parent_container.kind() {
241 WHILE_EXPR | LOOP_EXPR | FOR_EXPR => make::expr_continue(None),
242 FN | CLOSURE_EXPR => make::expr_return(None),
243 _ => return None,
244 })
245}
246
247fn flat_let_chain(mut expr: ast::Expr) -> Vec<ast::Expr> {
248 let mut chains = vec![];
249 let mut reduce_cond = |rhs| {
250 if !matches!(rhs, ast::Expr::LetExpr(_))
251 && let Some(last) = chains.pop_if(|last| !matches!(last, ast::Expr::LetExpr(_)))
252 {
253 chains.push(make::expr_bin_op(rhs, ast::BinaryOp::LogicOp(ast::LogicOp::And), last));
254 } else {
255 chains.push(rhs);
256 }
257 };
258
259 while let ast::Expr::BinExpr(bin_expr) = &expr
260 && bin_expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And))
261 && let (Some(lhs), Some(rhs)) = (bin_expr.lhs(), bin_expr.rhs())
262 {
263 reduce_cond(rhs);
264 expr = lhs;
265 }
266
267 reduce_cond(expr);
268 chains.reverse();
269 chains
270}
271
272fn clean_stmt_block(block: &ast::BlockExpr) -> ast::BlockExpr {
273 if block.statements().next().is_none()
274 && let Some(tail_expr) = block.tail_expr()
275 && block.modifier().is_none()
276 {
277 make::block_expr(once(make::expr_stmt(tail_expr).into()), None)
278 } else {
279 block.clone()
280 }
281}
282
283fn is_early_block(then_block: &ast::StmtList) -> bool {
284 let is_early_expr =
285 |expr| matches!(expr, ast::Expr::ReturnExpr(_) | ast::Expr::ContinueExpr(_));
286 let into_expr = |stmt| match stmt {
287 ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(),
288 _ => None,
289 };
290 then_block.tail_expr().is_some_and(is_early_expr)
291 || then_block.statements().filter_map(into_expr).any(is_early_expr)
292}
293
294#[cfg(test)]
295mod tests {
296 use crate::tests::{check_assist, check_assist_not_applicable};
297
298 use super::*;
299
300 #[test]
301 fn convert_inside_fn() {
302 check_assist(
303 convert_to_guarded_return,
304 r#"
305fn main() {
306 bar();
307 if$0 true {
308 foo();
309
310 // comment
311 bar();
312 }
313}
314"#,
315 r#"
316fn main() {
317 bar();
318 if false {
319 return;
320 }
321 foo();
322
323 // comment
324 bar();
325}
326"#,
327 );
328 }
329
330 #[test]
331 fn convert_inside_fn_return_option() {
332 check_assist(
333 convert_to_guarded_return,
334 r#"
335//- minicore: option
336fn ret_option() -> Option<()> {
337 bar();
338 if$0 true {
339 foo();
340
341 // comment
342 bar();
343 }
344}
345"#,
346 r#"
347fn ret_option() -> Option<()> {
348 bar();
349 if false {
350 return None;
351 }
352 foo();
353
354 // comment
355 bar();
356}
357"#,
358 );
359 }
360
361 #[test]
362 fn convert_inside_closure() {
363 check_assist(
364 convert_to_guarded_return,
365 r#"
366fn main() {
367 let _f = || {
368 bar();
369 if$0 true {
370 foo();
371
372 // comment
373 bar();
374 }
375 }
376}
377"#,
378 r#"
379fn main() {
380 let _f = || {
381 bar();
382 if false {
383 return;
384 }
385 foo();
386
387 // comment
388 bar();
389 }
390}
391"#,
392 );
393 }
394
395 #[test]
396 fn convert_let_inside_fn() {
397 check_assist(
398 convert_to_guarded_return,
399 r#"
400fn main(n: Option<String>) {
401 bar();
402 if$0 let Some(n) = n {
403 foo(n);
404
405 // comment
406 bar();
407 }
408}
409"#,
410 r#"
411fn main(n: Option<String>) {
412 bar();
413 let Some(n) = n else { return };
414 foo(n);
415
416 // comment
417 bar();
418}
419"#,
420 );
421 }
422
423 #[test]
424 fn convert_if_let_result() {
425 check_assist(
426 convert_to_guarded_return,
427 r#"
428fn main() {
429 if$0 let Ok(x) = Err(92) {
430 foo(x);
431 }
432}
433"#,
434 r#"
435fn main() {
436 let Ok(x) = Err(92) else { return };
437 foo(x);
438}
439"#,
440 );
441 }
442
443 #[test]
444 fn convert_if_let_has_never_type_else_block() {
445 check_assist(
446 convert_to_guarded_return,
447 r#"
448fn main() {
449 if$0 let Ok(x) = Err(92) {
450 foo(x);
451 } else {
452 // needless comment
453 return;
454 }
455}
456"#,
457 r#"
458fn main() {
459 let Ok(x) = Err(92) else {
460 // needless comment
461 return;
462 };
463 foo(x);
464}
465"#,
466 );
467
468 check_assist(
469 convert_to_guarded_return,
470 r#"
471fn main() {
472 if$0 let Ok(x) = Err(92) {
473 foo(x);
474 } else {
475 return
476 }
477}
478"#,
479 r#"
480fn main() {
481 let Ok(x) = Err(92) else {
482 return
483 };
484 foo(x);
485}
486"#,
487 );
488 }
489
490 #[test]
491 fn convert_if_let_result_inside_let() {
492 check_assist(
493 convert_to_guarded_return,
494 r#"
495fn main() {
496 let _x = loop {
497 if$0 let Ok(x) = Err(92) {
498 foo(x);
499 }
500 };
501}
502"#,
503 r#"
504fn main() {
505 let _x = loop {
506 let Ok(x) = Err(92) else { continue };
507 foo(x);
508 };
509}
510"#,
511 );
512 }
513
514 #[test]
515 fn convert_if_let_chain_result() {
516 check_assist(
517 convert_to_guarded_return,
518 r#"
519fn main() {
520 if$0 let Ok(x) = Err(92)
521 && x < 30
522 && let Some(y) = Some(8)
523 {
524 foo(x, y);
525 }
526}
527"#,
528 r#"
529fn main() {
530 let Ok(x) = Err(92) else { return };
531 if x >= 30 {
532 return;
533 }
534 let Some(y) = Some(8) else { return };
535 foo(x, y);
536}
537"#,
538 );
539
540 check_assist(
541 convert_to_guarded_return,
542 r#"
543fn main() {
544 if$0 let Ok(x) = Err(92)
545 && x < 30
546 && y < 20
547 && let Some(y) = Some(8)
548 {
549 foo(x, y);
550 }
551}
552"#,
553 r#"
554fn main() {
555 let Ok(x) = Err(92) else { return };
556 if !(x < 30 && y < 20) {
557 return;
558 }
559 let Some(y) = Some(8) else { return };
560 foo(x, y);
561}
562"#,
563 );
564
565 check_assist(
566 convert_to_guarded_return,
567 r#"
568fn main() {
569 if$0 let Ok(x) = Err(92)
570 && let Ok(y) = Ok(37)
571 && x < 30
572 && let Some(y) = Some(8)
573 {
574 foo(x, y);
575 }
576}
577"#,
578 r#"
579fn main() {
580 let Ok(x) = Err(92) else { return };
581 let Ok(y) = Ok(37) else { return };
582 if x >= 30 {
583 return;
584 }
585 let Some(y) = Some(8) else { return };
586 foo(x, y);
587}
588"#,
589 );
590
591 check_assist(
592 convert_to_guarded_return,
593 r#"
594fn main() {
595 if$0 cond
596 && let Ok(x) = Err(92)
597 && let Ok(y) = Ok(37)
598 && x < 30
599 && let Some(y) = Some(8)
600 {
601 foo(x, y);
602 }
603}
604"#,
605 r#"
606fn main() {
607 if !cond {
608 return;
609 }
610 let Ok(x) = Err(92) else { return };
611 let Ok(y) = Ok(37) else { return };
612 if x >= 30 {
613 return;
614 }
615 let Some(y) = Some(8) else { return };
616 foo(x, y);
617}
618"#,
619 );
620
621 check_assist(
622 convert_to_guarded_return,
623 r#"
624fn main() {
625 if$0 cond
626 && foo()
627 && let Ok(x) = Err(92)
628 && let Ok(y) = Ok(37)
629 && x < 30
630 && let Some(y) = Some(8)
631 {
632 foo(x, y);
633 }
634}
635"#,
636 r#"
637fn main() {
638 if !(cond && foo()) {
639 return;
640 }
641 let Ok(x) = Err(92) else { return };
642 let Ok(y) = Ok(37) else { return };
643 if x >= 30 {
644 return;
645 }
646 let Some(y) = Some(8) else { return };
647 foo(x, y);
648}
649"#,
650 );
651 }
652
653 #[test]
654 fn convert_let_ok_inside_fn() {
655 check_assist(
656 convert_to_guarded_return,
657 r#"
658fn main(n: Option<String>) {
659 bar();
660 if$0 let Some(n) = n {
661 foo(n);
662
663 // comment
664 bar();
665 }
666}
667"#,
668 r#"
669fn main(n: Option<String>) {
670 bar();
671 let Some(n) = n else { return };
672 foo(n);
673
674 // comment
675 bar();
676}
677"#,
678 );
679 }
680
681 #[test]
682 fn convert_let_mut_ok_inside_fn() {
683 check_assist(
684 convert_to_guarded_return,
685 r#"
686fn main(n: Option<String>) {
687 bar();
688 if$0 let Some(mut n) = n {
689 foo(n);
690
691 // comment
692 bar();
693 }
694}
695"#,
696 r#"
697fn main(n: Option<String>) {
698 bar();
699 let Some(mut n) = n else { return };
700 foo(n);
701
702 // comment
703 bar();
704}
705"#,
706 );
707 }
708
709 #[test]
710 fn convert_let_ref_ok_inside_fn() {
711 check_assist(
712 convert_to_guarded_return,
713 r#"
714fn main(n: Option<&str>) {
715 bar();
716 if$0 let Some(ref n) = n {
717 foo(n);
718
719 // comment
720 bar();
721 }
722}
723"#,
724 r#"
725fn main(n: Option<&str>) {
726 bar();
727 let Some(ref n) = n else { return };
728 foo(n);
729
730 // comment
731 bar();
732}
733"#,
734 );
735 }
736
737 #[test]
738 fn convert_inside_while() {
739 check_assist(
740 convert_to_guarded_return,
741 r#"
742fn main() {
743 while true {
744 if$0 true {
745 foo();
746 bar();
747 }
748 }
749}
750"#,
751 r#"
752fn main() {
753 while true {
754 if false {
755 continue;
756 }
757 foo();
758 bar();
759 }
760}
761"#,
762 );
763 }
764
765 #[test]
766 fn convert_let_inside_while() {
767 check_assist(
768 convert_to_guarded_return,
769 r#"
770fn main() {
771 while true {
772 if$0 let Some(n) = n {
773 foo(n);
774 bar();
775 }
776 }
777}
778"#,
779 r#"
780fn main() {
781 while true {
782 let Some(n) = n else { continue };
783 foo(n);
784 bar();
785 }
786}
787"#,
788 );
789 }
790
791 #[test]
792 fn convert_inside_loop() {
793 check_assist(
794 convert_to_guarded_return,
795 r#"
796fn main() {
797 loop {
798 if$0 true {
799 foo();
800 bar();
801 }
802 }
803}
804"#,
805 r#"
806fn main() {
807 loop {
808 if false {
809 continue;
810 }
811 foo();
812 bar();
813 }
814}
815"#,
816 );
817 }
818
819 #[test]
820 fn convert_let_inside_loop() {
821 check_assist(
822 convert_to_guarded_return,
823 r#"
824fn main() {
825 loop {
826 if$0 let Some(n) = n {
827 foo(n);
828 bar();
829 }
830 }
831}
832"#,
833 r#"
834fn main() {
835 loop {
836 let Some(n) = n else { continue };
837 foo(n);
838 bar();
839 }
840}
841"#,
842 );
843 }
844
845 #[test]
846 fn convert_let_inside_for() {
847 check_assist(
848 convert_to_guarded_return,
849 r#"
850fn main() {
851 for n in ns {
852 if$0 let Some(n) = n {
853 foo(n);
854 bar();
855 }
856 }
857}
858"#,
859 r#"
860fn main() {
861 for n in ns {
862 let Some(n) = n else { continue };
863 foo(n);
864 bar();
865 }
866}
867"#,
868 );
869 }
870
871 #[test]
872 fn convert_let_stmt_inside_fn() {
873 check_assist(
874 convert_to_guarded_return,
875 r#"
876//- minicore: option
877fn foo() -> Option<i32> {
878 None
879}
880
881fn main() {
882 let x$0 = foo();
883}
884"#,
885 r#"
886fn foo() -> Option<i32> {
887 None
888}
889
890fn main() {
891 let Some(x) = foo() else { return };
892}
893"#,
894 );
895 }
896
897 #[test]
898 fn convert_let_stmt_inside_fn_return_option() {
899 check_assist(
900 convert_to_guarded_return,
901 r#"
902//- minicore: option
903fn foo() -> Option<i32> {
904 None
905}
906
907fn ret_option() -> Option<i32> {
908 let x$0 = foo();
909}
910"#,
911 r#"
912fn foo() -> Option<i32> {
913 None
914}
915
916fn ret_option() -> Option<i32> {
917 let Some(x) = foo() else { return None };
918}
919"#,
920 );
921 }
922
923 #[test]
924 fn convert_let_stmt_inside_loop() {
925 check_assist(
926 convert_to_guarded_return,
927 r#"
928//- minicore: option
929fn foo() -> Option<i32> {
930 None
931}
932
933fn main() {
934 loop {
935 let x$0 = foo();
936 }
937}
938"#,
939 r#"
940fn foo() -> Option<i32> {
941 None
942}
943
944fn main() {
945 loop {
946 let Some(x) = foo() else { continue };
947 }
948}
949"#,
950 );
951 }
952
953 #[test]
954 fn convert_arbitrary_if_let_patterns() {
955 check_assist(
956 convert_to_guarded_return,
957 r#"
958fn main() {
959 $0if let None = Some(92) {
960 foo();
961 }
962}
963"#,
964 r#"
965fn main() {
966 let None = Some(92) else { return };
967 foo();
968}
969"#,
970 );
971
972 check_assist(
973 convert_to_guarded_return,
974 r#"
975fn main() {
976 $0if let [1, x] = [1, 92] {
977 foo(x);
978 }
979}
980"#,
981 r#"
982fn main() {
983 let [1, x] = [1, 92] else { return };
984 foo(x);
985}
986"#,
987 );
988
989 check_assist(
990 convert_to_guarded_return,
991 r#"
992fn main() {
993 $0if let (Some(x), None) = (Some(92), None) {
994 foo(x);
995 }
996}
997"#,
998 r#"
999fn main() {
1000 let (Some(x), None) = (Some(92), None) else { return };
1001 foo(x);
1002}
1003"#,
1004 );
1005 }
1006
1007 #[test]
1008 fn ignore_already_converted_if() {
1009 check_assist_not_applicable(
1010 convert_to_guarded_return,
1011 r#"
1012fn main() {
1013 if$0 true {
1014 return;
1015 }
1016}
1017"#,
1018 );
1019 }
1020
1021 #[test]
1022 fn ignore_already_converted_loop() {
1023 check_assist_not_applicable(
1024 convert_to_guarded_return,
1025 r#"
1026fn main() {
1027 loop {
1028 if$0 true {
1029 continue;
1030 }
1031 }
1032}
1033"#,
1034 );
1035 }
1036
1037 #[test]
1038 fn ignore_return() {
1039 check_assist_not_applicable(
1040 convert_to_guarded_return,
1041 r#"
1042fn main() {
1043 if$0 true {
1044 return
1045 }
1046}
1047"#,
1048 );
1049 }
1050
1051 #[test]
1052 fn ignore_else_branch() {
1053 check_assist_not_applicable(
1054 convert_to_guarded_return,
1055 r#"
1056fn main() {
1057 if$0 true {
1058 foo();
1059 } else {
1060 bar()
1061 }
1062}
1063"#,
1064 );
1065 }
1066
1067 #[test]
1068 fn ignore_let_else_branch() {
1069 check_assist_not_applicable(
1070 convert_to_guarded_return,
1071 r#"
1072//- minicore: option
1073fn main() {
1074 let$0 Some(x) = Some(2) else { return };
1075}
1076"#,
1077 );
1078 }
1079
1080 #[test]
1081 fn ignore_statements_after_if() {
1082 check_assist_not_applicable(
1083 convert_to_guarded_return,
1084 r#"
1085fn main() {
1086 if$0 true {
1087 foo();
1088 }
1089 bar();
1090}
1091"#,
1092 );
1093 }
1094
1095 #[test]
1096 fn ignore_statements_inside_if() {
1097 check_assist_not_applicable(
1098 convert_to_guarded_return,
1099 r#"
1100fn main() {
1101 if false {
1102 if$0 true {
1103 foo();
1104 }
1105 }
1106}
1107"#,
1108 );
1109 }
1110
1111 #[test]
1112 fn ignore_inside_if_stmt() {
1113 check_assist_not_applicable(
1114 convert_to_guarded_return,
1115 r#"
1116fn main() {
1117 if false {
1118 foo()$0;
1119 }
1120}
1121"#,
1122 );
1123 }
1124
1125 #[test]
1126 fn ignore_inside_let_initializer() {
1127 check_assist_not_applicable(
1128 convert_to_guarded_return,
1129 r#"
1130//- minicore: option
1131fn foo() -> Option<i32> {
1132 None
1133}
1134
1135fn main() {
1136 let x = foo()$0;
1137}
1138"#,
1139 );
1140 }
1141}