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