Skip to content

Commit 7ee1a77

Browse files
committed
fix(assist): fix #10566 and #10567
Signed-off-by: Benjamin Coenen <[email protected]>
1 parent 401daa5 commit 7ee1a77

File tree

1 file changed

+79
-15
lines changed

1 file changed

+79
-15
lines changed

crates/ide_assists/src/handlers/unwrap_result_return_type.rs

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use ide_db::helpers::{for_each_tail_expr, node_ext::walk_expr, FamousDefs};
22
use syntax::{
33
ast::{self, Expr},
4-
match_ast, AstNode,
4+
match_ast, AstNode, TextRange, TextSize,
55
};
66

77
use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -60,25 +60,45 @@ pub(crate) fn unwrap_result_return_type(acc: &mut Assists, ctx: &AssistContext)
6060
});
6161
for_each_tail_expr(&body, tail_cb);
6262

63-
for ret_expr_arg in exprs_to_unwrap {
64-
let new_ret_expr = ret_expr_arg.to_string();
65-
let new_ret_expr =
66-
new_ret_expr.trim_start_matches("Ok(").trim_start_matches("Err(");
67-
builder.replace(
68-
ret_expr_arg.syntax().text_range(),
69-
new_ret_expr.strip_suffix(')').unwrap_or(new_ret_expr),
70-
)
71-
}
72-
63+
let mut is_unit_type = false;
7364
if let Some((_, inner_type)) = type_ref.to_string().split_once('<') {
7465
let inner_type = match inner_type.split_once(',') {
7566
Some((success_inner_type, _)) => success_inner_type,
7667
None => inner_type,
7768
};
78-
builder.replace(
79-
type_ref.syntax().text_range(),
80-
inner_type.strip_suffix('>').unwrap_or(inner_type),
81-
)
69+
let new_ret_type = inner_type.strip_suffix('>').unwrap_or(inner_type);
70+
if new_ret_type == "()" {
71+
is_unit_type = true;
72+
let text_range = TextRange::new(
73+
ret_type.syntax().text_range().start(),
74+
ret_type.syntax().text_range().end() + TextSize::from(1u32),
75+
);
76+
builder.replace(text_range, "")
77+
} else {
78+
builder.replace(
79+
type_ref.syntax().text_range(),
80+
inner_type.strip_suffix('>').unwrap_or(inner_type),
81+
)
82+
}
83+
}
84+
85+
for ret_expr_arg in exprs_to_unwrap {
86+
let ret_expr_str = ret_expr_arg.to_string();
87+
if ret_expr_str.starts_with("Ok(") || ret_expr_str.starts_with("Err(") {
88+
let arg_list = ret_expr_arg.syntax().children().find_map(ast::ArgList::cast);
89+
if let Some(arg_list) = arg_list {
90+
if is_unit_type {
91+
builder.replace(ret_expr_arg.syntax().text_range(), "");
92+
} else {
93+
let new_ret_expr = arg_list
94+
.args()
95+
.map(|arg| arg.to_string())
96+
.collect::<Vec<String>>()
97+
.join(", ");
98+
builder.replace(ret_expr_arg.syntax().text_range(), new_ret_expr);
99+
}
100+
}
101+
}
82102
}
83103
},
84104
)
@@ -126,6 +146,50 @@ fn foo() -> i32 {
126146
);
127147
}
128148

149+
#[test]
150+
fn unwrap_result_return_type_unit_type() {
151+
check_assist(
152+
unwrap_result_return_type,
153+
r#"
154+
//- minicore: result
155+
fn foo() -> Result<(), Box<dyn Error$0>> {
156+
Ok(())
157+
}
158+
"#,
159+
r#"
160+
fn foo() {
161+
162+
}
163+
"#,
164+
);
165+
}
166+
167+
#[test]
168+
fn unwrap_result_return_type_ending_with_parent() {
169+
check_assist(
170+
unwrap_result_return_type,
171+
r#"
172+
//- minicore: result
173+
fn foo() -> Result<i32, Box<dyn Error$0>> {
174+
if true {
175+
Ok(42)
176+
} else {
177+
foo()
178+
}
179+
}
180+
"#,
181+
r#"
182+
fn foo() -> i32 {
183+
if true {
184+
42
185+
} else {
186+
foo()
187+
}
188+
}
189+
"#,
190+
);
191+
}
192+
129193
#[test]
130194
fn unwrap_return_type_break_split_tail() {
131195
check_assist(

0 commit comments

Comments
 (0)