aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/change_return_type_to_result.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/change_return_type_to_result.rs')
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs961
1 files changed, 961 insertions, 0 deletions
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
new file mode 100644
index 000000000..c6baa0a57
--- /dev/null
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -0,0 +1,961 @@
1use ra_syntax::{
2 ast::{self, BlockExpr, Expr, LoopBodyOwner},
3 AstNode, SyntaxNode,
4};
5
6use crate::{AssistContext, AssistId, Assists};
7
8// Assist: change_return_type_to_result
9//
10// Change the function's return type to Result.
11//
12// ```
13// fn foo() -> i32<|> { 42i32 }
14// ```
15// ->
16// ```
17// fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
18// ```
19pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
20 let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
21 // FIXME: extend to lambdas as well
22 let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?;
23
24 let type_ref = &ret_type.type_ref()?;
25 if type_ref.syntax().text().to_string().starts_with("Result<") {
26 return None;
27 }
28
29 let block_expr = &fn_def.body()?;
30
31 acc.add(
32 AssistId("change_return_type_to_result"),
33 "Change return type to Result",
34 type_ref.syntax().text_range(),
35 |builder| {
36 let mut tail_return_expr_collector = TailReturnCollector::new();
37 tail_return_expr_collector.collect_jump_exprs(block_expr, false);
38 tail_return_expr_collector.collect_tail_exprs(block_expr);
39
40 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
41 builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg));
42 }
43
44 match ctx.config.snippet_cap {
45 Some(cap) => {
46 let snippet = format!("Result<{}, ${{0:_}}>", type_ref);
47 builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet)
48 }
49 None => builder
50 .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)),
51 }
52 },
53 )
54}
55
56struct TailReturnCollector {
57 exprs_to_wrap: Vec<SyntaxNode>,
58}
59
60impl TailReturnCollector {
61 fn new() -> Self {
62 Self { exprs_to_wrap: vec![] }
63 }
64 /// Collect all`return` expression
65 fn collect_jump_exprs(&mut self, block_expr: &BlockExpr, collect_break: bool) {
66 let statements = block_expr.statements();
67 for stmt in statements {
68 let expr = match &stmt {
69 ast::Stmt::ExprStmt(stmt) => stmt.expr(),
70 ast::Stmt::LetStmt(stmt) => stmt.initializer(),
71 };
72 if let Some(expr) = &expr {
73 self.handle_exprs(expr, collect_break);
74 }
75 }
76
77 // Browse tail expressions for each block
78 if let Some(expr) = block_expr.expr() {
79 if let Some(last_exprs) = get_tail_expr_from_block(&expr) {
80 for last_expr in last_exprs {
81 let last_expr = match last_expr {
82 NodeType::Node(expr) | NodeType::Leaf(expr) => expr,
83 };
84
85 if let Some(last_expr) = Expr::cast(last_expr.clone()) {
86 self.handle_exprs(&last_expr, collect_break);
87 } else if let Some(expr_stmt) = ast::Stmt::cast(last_expr) {
88 let expr_stmt = match &expr_stmt {
89 ast::Stmt::ExprStmt(stmt) => stmt.expr(),
90 ast::Stmt::LetStmt(stmt) => stmt.initializer(),
91 };
92 if let Some(expr) = &expr_stmt {
93 self.handle_exprs(expr, collect_break);
94 }
95 }
96 }
97 }
98 }
99 }
100
101 fn handle_exprs(&mut self, expr: &Expr, collect_break: bool) {
102 match expr {
103 Expr::BlockExpr(block_expr) => {
104 self.collect_jump_exprs(&block_expr, collect_break);
105 }
106 Expr::ReturnExpr(ret_expr) => {
107 if let Some(ret_expr_arg) = &ret_expr.expr() {
108 self.exprs_to_wrap.push(ret_expr_arg.syntax().clone());
109 }
110 }
111 Expr::BreakExpr(break_expr) if collect_break => {
112 if let Some(break_expr_arg) = &break_expr.expr() {
113 self.exprs_to_wrap.push(break_expr_arg.syntax().clone());
114 }
115 }
116 Expr::IfExpr(if_expr) => {
117 for block in if_expr.blocks() {
118 self.collect_jump_exprs(&block, collect_break);
119 }
120 }
121 Expr::LoopExpr(loop_expr) => {
122 if let Some(block_expr) = loop_expr.loop_body() {
123 self.collect_jump_exprs(&block_expr, collect_break);
124 }
125 }
126 Expr::ForExpr(for_expr) => {
127 if let Some(block_expr) = for_expr.loop_body() {
128 self.collect_jump_exprs(&block_expr, collect_break);
129 }
130 }
131 Expr::WhileExpr(while_expr) => {
132 if let Some(block_expr) = while_expr.loop_body() {
133 self.collect_jump_exprs(&block_expr, collect_break);
134 }
135 }
136 Expr::MatchExpr(match_expr) => {
137 if let Some(arm_list) = match_expr.match_arm_list() {
138 arm_list.arms().filter_map(|match_arm| match_arm.expr()).for_each(|expr| {
139 self.handle_exprs(&expr, collect_break);
140 });
141 }
142 }
143 _ => {}
144 }
145 }
146
147 fn collect_tail_exprs(&mut self, block: &BlockExpr) {
148 if let Some(expr) = block.expr() {
149 self.handle_exprs(&expr, true);
150 self.fetch_tail_exprs(&expr);
151 }
152 }
153
154 fn fetch_tail_exprs(&mut self, expr: &Expr) {
155 if let Some(exprs) = get_tail_expr_from_block(expr) {
156 for node_type in &exprs {
157 match node_type {
158 NodeType::Leaf(expr) => {
159 self.exprs_to_wrap.push(expr.clone());
160 }
161 NodeType::Node(expr) => match &Expr::cast(expr.clone()) {
162 Some(last_expr) => {
163 self.fetch_tail_exprs(last_expr);
164 }
165 None => {
166 self.exprs_to_wrap.push(expr.clone());
167 }
168 },
169 }
170 }
171 }
172 }
173}
174
175#[derive(Debug)]
176enum NodeType {
177 Leaf(SyntaxNode),
178 Node(SyntaxNode),
179}
180
181/// Get a tail expression inside a block
182fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> {
183 match expr {
184 Expr::IfExpr(if_expr) => {
185 let mut nodes = vec![];
186 for block in if_expr.blocks() {
187 if let Some(block_expr) = block.expr() {
188 if let Some(tail_exprs) = get_tail_expr_from_block(&block_expr) {
189 nodes.extend(tail_exprs);
190 }
191 } else if let Some(last_expr) = block.syntax().last_child() {
192 nodes.push(NodeType::Node(last_expr));
193 } else {
194 nodes.push(NodeType::Node(block.syntax().clone()));
195 }
196 }
197 Some(nodes)
198 }
199 Expr::LoopExpr(loop_expr) => {
200 loop_expr.syntax().last_child().map(|lc| vec![NodeType::Node(lc)])
201 }
202 Expr::ForExpr(for_expr) => {
203 for_expr.syntax().last_child().map(|lc| vec![NodeType::Node(lc)])
204 }
205 Expr::WhileExpr(while_expr) => {
206 while_expr.syntax().last_child().map(|lc| vec![NodeType::Node(lc)])
207 }
208 Expr::BlockExpr(block_expr) => {
209 block_expr.expr().map(|lc| vec![NodeType::Node(lc.syntax().clone())])
210 }
211 Expr::MatchExpr(match_expr) => {
212 let arm_list = match_expr.match_arm_list()?;
213 let arms: Vec<NodeType> = arm_list
214 .arms()
215 .filter_map(|match_arm| match_arm.expr())
216 .map(|expr| match expr {
217 Expr::ReturnExpr(ret_expr) => NodeType::Node(ret_expr.syntax().clone()),
218 Expr::BreakExpr(break_expr) => NodeType::Node(break_expr.syntax().clone()),
219 _ => match expr.syntax().last_child() {
220 Some(last_expr) => NodeType::Node(last_expr),
221 None => NodeType::Node(expr.syntax().clone()),
222 },
223 })
224 .collect();
225
226 Some(arms)
227 }
228 Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e.syntax().clone())]),
229 Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]),
230 Expr::CallExpr(call_expr) => Some(vec![NodeType::Leaf(call_expr.syntax().clone())]),
231 Expr::Literal(lit_expr) => Some(vec![NodeType::Leaf(lit_expr.syntax().clone())]),
232 Expr::TupleExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
233 Expr::ArrayExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
234 Expr::ParenExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
235 Expr::PathExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
236 Expr::Label(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
237 Expr::RecordLit(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
238 Expr::IndexExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
239 Expr::MethodCallExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
240 Expr::AwaitExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
241 Expr::CastExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
242 Expr::RefExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
243 Expr::PrefixExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
244 Expr::RangeExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
245 Expr::BinExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
246 Expr::MacroCall(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
247 Expr::BoxExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]),
248 _ => None,
249 }
250}
251
252#[cfg(test)]
253mod tests {
254 use crate::tests::{check_assist, check_assist_not_applicable};
255
256 use super::*;
257
258 #[test]
259 fn change_return_type_to_result_simple() {
260 check_assist(
261 change_return_type_to_result,
262 r#"fn foo() -> i3<|>2 {
263 let test = "test";
264 return 42i32;
265 }"#,
266 r#"fn foo() -> Result<i32, ${0:_}> {
267 let test = "test";
268 return Ok(42i32);
269 }"#,
270 );
271 }
272
273 #[test]
274 fn change_return_type_to_result_simple_return_type() {
275 check_assist(
276 change_return_type_to_result,
277 r#"fn foo() -> i32<|> {
278 let test = "test";
279 return 42i32;
280 }"#,
281 r#"fn foo() -> Result<i32, ${0:_}> {
282 let test = "test";
283 return Ok(42i32);
284 }"#,
285 );
286 }
287
288 #[test]
289 fn change_return_type_to_result_simple_return_type_bad_cursor() {
290 check_assist_not_applicable(
291 change_return_type_to_result,
292 r#"fn foo() -> i32 {
293 let test = "test";<|>
294 return 42i32;
295 }"#,
296 );
297 }
298
299 #[test]
300 fn change_return_type_to_result_simple_with_cursor() {
301 check_assist(
302 change_return_type_to_result,
303 r#"fn foo() -> <|>i32 {
304 let test = "test";
305 return 42i32;
306 }"#,
307 r#"fn foo() -> Result<i32, ${0:_}> {
308 let test = "test";
309 return Ok(42i32);
310 }"#,
311 );
312 }
313
314 #[test]
315 fn change_return_type_to_result_simple_with_tail() {
316 check_assist(
317 change_return_type_to_result,
318 r#"fn foo() -><|> i32 {
319 let test = "test";
320 42i32
321 }"#,
322 r#"fn foo() -> Result<i32, ${0:_}> {
323 let test = "test";
324 Ok(42i32)
325 }"#,
326 );
327 }
328
329 #[test]
330 fn change_return_type_to_result_simple_with_tail_only() {
331 check_assist(
332 change_return_type_to_result,
333 r#"fn foo() -> i32<|> {
334 42i32
335 }"#,
336 r#"fn foo() -> Result<i32, ${0:_}> {
337 Ok(42i32)
338 }"#,
339 );
340 }
341 #[test]
342 fn change_return_type_to_result_simple_with_tail_block_like() {
343 check_assist(
344 change_return_type_to_result,
345 r#"fn foo() -> i32<|> {
346 if true {
347 42i32
348 } else {
349 24i32
350 }
351 }"#,
352 r#"fn foo() -> Result<i32, ${0:_}> {
353 if true {
354 Ok(42i32)
355 } else {
356 Ok(24i32)
357 }
358 }"#,
359 );
360 }
361
362 #[test]
363 fn change_return_type_to_result_simple_with_nested_if() {
364 check_assist(
365 change_return_type_to_result,
366 r#"fn foo() -> i32<|> {
367 if true {
368 if false {
369 1
370 } else {
371 2
372 }
373 } else {
374 24i32
375 }
376 }"#,
377 r#"fn foo() -> Result<i32, ${0:_}> {
378 if true {
379 if false {
380 Ok(1)
381 } else {
382 Ok(2)
383 }
384 } else {
385 Ok(24i32)
386 }
387 }"#,
388 );
389 }
390
391 #[test]
392 fn change_return_type_to_result_simple_with_await() {
393 check_assist(
394 change_return_type_to_result,
395 r#"async fn foo() -> i<|>32 {
396 if true {
397 if false {
398 1.await
399 } else {
400 2.await
401 }
402 } else {
403 24i32.await
404 }
405 }"#,
406 r#"async fn foo() -> Result<i32, ${0:_}> {
407 if true {
408 if false {
409 Ok(1.await)
410 } else {
411 Ok(2.await)
412 }
413 } else {
414 Ok(24i32.await)
415 }
416 }"#,
417 );
418 }
419
420 #[test]
421 fn change_return_type_to_result_simple_with_array() {
422 check_assist(
423 change_return_type_to_result,
424 r#"fn foo() -> [i32;<|> 3] {
425 [1, 2, 3]
426 }"#,
427 r#"fn foo() -> Result<[i32; 3], ${0:_}> {
428 Ok([1, 2, 3])
429 }"#,
430 );
431 }
432
433 #[test]
434 fn change_return_type_to_result_simple_with_cast() {
435 check_assist(
436 change_return_type_to_result,
437 r#"fn foo() -<|>> i32 {
438 if true {
439 if false {
440 1 as i32
441 } else {
442 2 as i32
443 }
444 } else {
445 24 as i32
446 }
447 }"#,
448 r#"fn foo() -> Result<i32, ${0:_}> {
449 if true {
450 if false {
451 Ok(1 as i32)
452 } else {
453 Ok(2 as i32)
454 }
455 } else {
456 Ok(24 as i32)
457 }
458 }"#,
459 );
460 }
461
462 #[test]
463 fn change_return_type_to_result_simple_with_tail_block_like_match() {
464 check_assist(
465 change_return_type_to_result,
466 r#"fn foo() -> i32<|> {
467 let my_var = 5;
468 match my_var {
469 5 => 42i32,
470 _ => 24i32,
471 }
472 }"#,
473 r#"fn foo() -> Result<i32, ${0:_}> {
474 let my_var = 5;
475 match my_var {
476 5 => Ok(42i32),
477 _ => Ok(24i32),
478 }
479 }"#,
480 );
481 }
482
483 #[test]
484 fn change_return_type_to_result_simple_with_loop_with_tail() {
485 check_assist(
486 change_return_type_to_result,
487 r#"fn foo() -> i32<|> {
488 let my_var = 5;
489 loop {
490 println!("test");
491 5
492 }
493
494 my_var
495 }"#,
496 r#"fn foo() -> Result<i32, ${0:_}> {
497 let my_var = 5;
498 loop {
499 println!("test");
500 5
501 }
502
503 Ok(my_var)
504 }"#,
505 );
506 }
507
508 #[test]
509 fn change_return_type_to_result_simple_with_loop_in_let_stmt() {
510 check_assist(
511 change_return_type_to_result,
512 r#"fn foo() -> i32<|> {
513 let my_var = let x = loop {
514 break 1;
515 };
516
517 my_var
518 }"#,
519 r#"fn foo() -> Result<i32, ${0:_}> {
520 let my_var = let x = loop {
521 break 1;
522 };
523
524 Ok(my_var)
525 }"#,
526 );
527 }
528
529 #[test]
530 fn change_return_type_to_result_simple_with_tail_block_like_match_return_expr() {
531 check_assist(
532 change_return_type_to_result,
533 r#"fn foo() -> i32<|> {
534 let my_var = 5;
535 let res = match my_var {
536 5 => 42i32,
537 _ => return 24i32,
538 };
539
540 res
541 }"#,
542 r#"fn foo() -> Result<i32, ${0:_}> {
543 let my_var = 5;
544 let res = match my_var {
545 5 => 42i32,
546 _ => return Ok(24i32),
547 };
548
549 Ok(res)
550 }"#,
551 );
552
553 check_assist(
554 change_return_type_to_result,
555 r#"fn foo() -> i32<|> {
556 let my_var = 5;
557 let res = if my_var == 5 {
558 42i32
559 } else {
560 return 24i32;
561 };
562
563 res
564 }"#,
565 r#"fn foo() -> Result<i32, ${0:_}> {
566 let my_var = 5;
567 let res = if my_var == 5 {
568 42i32
569 } else {
570 return Ok(24i32);
571 };
572
573 Ok(res)
574 }"#,
575 );
576 }
577
578 #[test]
579 fn change_return_type_to_result_simple_with_tail_block_like_match_deeper() {
580 check_assist(
581 change_return_type_to_result,
582 r#"fn foo() -> i32<|> {
583 let my_var = 5;
584 match my_var {
585 5 => {
586 if true {
587 42i32
588 } else {
589 25i32
590 }
591 },
592 _ => {
593 let test = "test";
594 if test == "test" {
595 return bar();
596 }
597 53i32
598 },
599 }
600 }"#,
601 r#"fn foo() -> Result<i32, ${0:_}> {
602 let my_var = 5;
603 match my_var {
604 5 => {
605 if true {
606 Ok(42i32)
607 } else {
608 Ok(25i32)
609 }
610 },
611 _ => {
612 let test = "test";
613 if test == "test" {
614 return Ok(bar());
615 }
616 Ok(53i32)
617 },
618 }
619 }"#,
620 );
621 }
622
623 #[test]
624 fn change_return_type_to_result_simple_with_tail_block_like_early_return() {
625 check_assist(
626 change_return_type_to_result,
627 r#"fn foo() -> i<|>32 {
628 let test = "test";
629 if test == "test" {
630 return 24i32;
631 }
632 53i32
633 }"#,
634 r#"fn foo() -> Result<i32, ${0:_}> {
635 let test = "test";
636 if test == "test" {
637 return Ok(24i32);
638 }
639 Ok(53i32)
640 }"#,
641 );
642 }
643
644 #[test]
645 fn change_return_type_to_result_simple_with_closure() {
646 check_assist(
647 change_return_type_to_result,
648 r#"fn foo(the_field: u32) -><|> u32 {
649 let true_closure = || {
650 return true;
651 };
652 if the_field < 5 {
653 let mut i = 0;
654
655
656 if true_closure() {
657 return 99;
658 } else {
659 return 0;
660 }
661 }
662
663 the_field
664 }"#,
665 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
666 let true_closure = || {
667 return true;
668 };
669 if the_field < 5 {
670 let mut i = 0;
671
672
673 if true_closure() {
674 return Ok(99);
675 } else {
676 return Ok(0);
677 }
678 }
679
680 Ok(the_field)
681 }"#,
682 );
683
684 check_assist(
685 change_return_type_to_result,
686 r#"fn foo(the_field: u32) -> u32<|> {
687 let true_closure = || {
688 return true;
689 };
690 if the_field < 5 {
691 let mut i = 0;
692
693
694 if true_closure() {
695 return 99;
696 } else {
697 return 0;
698 }
699 }
700 let t = None;
701
702 t.unwrap_or_else(|| the_field)
703 }"#,
704 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
705 let true_closure = || {
706 return true;
707 };
708 if the_field < 5 {
709 let mut i = 0;
710
711
712 if true_closure() {
713 return Ok(99);
714 } else {
715 return Ok(0);
716 }
717 }
718 let t = None;
719
720 Ok(t.unwrap_or_else(|| the_field))
721 }"#,
722 );
723 }
724
725 #[test]
726 fn change_return_type_to_result_simple_with_weird_forms() {
727 check_assist(
728 change_return_type_to_result,
729 r#"fn foo() -> i32<|> {
730 let test = "test";
731 if test == "test" {
732 return 24i32;
733 }
734 let mut i = 0;
735 loop {
736 if i == 1 {
737 break 55;
738 }
739 i += 1;
740 }
741 }"#,
742 r#"fn foo() -> Result<i32, ${0:_}> {
743 let test = "test";
744 if test == "test" {
745 return Ok(24i32);
746 }
747 let mut i = 0;
748 loop {
749 if i == 1 {
750 break Ok(55);
751 }
752 i += 1;
753 }
754 }"#,
755 );
756
757 check_assist(
758 change_return_type_to_result,
759 r#"fn foo() -> i32<|> {
760 let test = "test";
761 if test == "test" {
762 return 24i32;
763 }
764 let mut i = 0;
765 loop {
766 loop {
767 if i == 1 {
768 break 55;
769 }
770 i += 1;
771 }
772 }
773 }"#,
774 r#"fn foo() -> Result<i32, ${0:_}> {
775 let test = "test";
776 if test == "test" {
777 return Ok(24i32);
778 }
779 let mut i = 0;
780 loop {
781 loop {
782 if i == 1 {
783 break Ok(55);
784 }
785 i += 1;
786 }
787 }
788 }"#,
789 );
790
791 check_assist(
792 change_return_type_to_result,
793 r#"fn foo() -> i3<|>2 {
794 let test = "test";
795 let other = 5;
796 if test == "test" {
797 let res = match other {
798 5 => 43,
799 _ => return 56,
800 };
801 }
802 let mut i = 0;
803 loop {
804 loop {
805 if i == 1 {
806 break 55;
807 }
808 i += 1;
809 }
810 }
811 }"#,
812 r#"fn foo() -> Result<i32, ${0:_}> {
813 let test = "test";
814 let other = 5;
815 if test == "test" {
816 let res = match other {
817 5 => 43,
818 _ => return Ok(56),
819 };
820 }
821 let mut i = 0;
822 loop {
823 loop {
824 if i == 1 {
825 break Ok(55);
826 }
827 i += 1;
828 }
829 }
830 }"#,
831 );
832
833 check_assist(
834 change_return_type_to_result,
835 r#"fn foo(the_field: u32) -> u32<|> {
836 if the_field < 5 {
837 let mut i = 0;
838 loop {
839 if i > 5 {
840 return 55u32;
841 }
842 i += 3;
843 }
844
845 match i {
846 5 => return 99,
847 _ => return 0,
848 };
849 }
850
851 the_field
852 }"#,
853 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
854 if the_field < 5 {
855 let mut i = 0;
856 loop {
857 if i > 5 {
858 return Ok(55u32);
859 }
860 i += 3;
861 }
862
863 match i {
864 5 => return Ok(99),
865 _ => return Ok(0),
866 };
867 }
868
869 Ok(the_field)
870 }"#,
871 );
872
873 check_assist(
874 change_return_type_to_result,
875 r#"fn foo(the_field: u32) -> u3<|>2 {
876 if the_field < 5 {
877 let mut i = 0;
878
879 match i {
880 5 => return 99,
881 _ => return 0,
882 }
883 }
884
885 the_field
886 }"#,
887 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
888 if the_field < 5 {
889 let mut i = 0;
890
891 match i {
892 5 => return Ok(99),
893 _ => return Ok(0),
894 }
895 }
896
897 Ok(the_field)
898 }"#,
899 );
900
901 check_assist(
902 change_return_type_to_result,
903 r#"fn foo(the_field: u32) -> u32<|> {
904 if the_field < 5 {
905 let mut i = 0;
906
907 if i == 5 {
908 return 99
909 } else {
910 return 0
911 }
912 }
913
914 the_field
915 }"#,
916 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
917 if the_field < 5 {
918 let mut i = 0;
919
920 if i == 5 {
921 return Ok(99)
922 } else {
923 return Ok(0)
924 }
925 }
926
927 Ok(the_field)
928 }"#,
929 );
930
931 check_assist(
932 change_return_type_to_result,
933 r#"fn foo(the_field: u32) -> <|>u32 {
934 if the_field < 5 {
935 let mut i = 0;
936
937 if i == 5 {
938 return 99;
939 } else {
940 return 0;
941 }
942 }
943
944 the_field
945 }"#,
946 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
947 if the_field < 5 {
948 let mut i = 0;
949
950 if i == 5 {
951 return Ok(99);
952 } else {
953 return Ok(0);
954 }
955 }
956
957 Ok(the_field)
958 }"#,
959 );
960 }
961}