Skip to content

Commit 6c3ab56

Browse files
committed
Auto merge of rust-lang#13527 - unexge:use-let-else-stmt-in-convert-to-guarded-return-assist, r=jonas-schievink
Use let-else statements in `Convert to guarded return` assist Follow up for rust-lang/rust-analyzer#13516, addresses remaining part of rust-lang/rust-analyzer#13254 (comment)
2 parents af1f48d + 62a6cdf commit 6c3ab56

File tree

2 files changed

+36
-54
lines changed

2 files changed

+36
-54
lines changed

crates/ide-assists/src/handlers/convert_to_guarded_return.rs

+16-54
Original file line numberDiff line numberDiff line change
@@ -129,32 +129,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
129129
}
130130
Some((path, bound_ident)) => {
131131
// If-let.
132-
let match_expr = {
133-
let happy_arm = {
134-
let pat = make::tuple_struct_pat(
135-
path,
136-
once(make::ext::simple_ident_pat(make::name("it")).into()),
137-
);
138-
let expr = {
139-
let path = make::ext::ident_path("it");
140-
make::expr_path(path)
141-
};
142-
make::match_arm(once(pat.into()), None, expr)
143-
};
144-
145-
let sad_arm = make::match_arm(
146-
// FIXME: would be cool to use `None` or `Err(_)` if appropriate
147-
once(make::wildcard_pat().into()),
148-
None,
149-
early_expression,
150-
);
151-
152-
make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm]))
153-
};
154-
155-
let let_stmt = make::let_stmt(bound_ident, None, Some(match_expr));
156-
let let_stmt = let_stmt.indent(if_indent_level);
157-
let_stmt.syntax().clone_for_update()
132+
let pat = make::tuple_struct_pat(path, once(bound_ident));
133+
let let_else_stmt = make::let_else_stmt(
134+
pat.into(),
135+
None,
136+
cond_expr,
137+
ast::make::tail_only_block_expr(early_expression),
138+
);
139+
let let_else_stmt = let_else_stmt.indent(if_indent_level);
140+
let_else_stmt.syntax().clone_for_update()
158141
}
159142
};
160143

@@ -238,10 +221,7 @@ fn main(n: Option<String>) {
238221
r#"
239222
fn main(n: Option<String>) {
240223
bar();
241-
let n = match n {
242-
Some(it) => it,
243-
_ => return,
244-
};
224+
let Some(n) = n else { return };
245225
foo(n);
246226
247227
// comment
@@ -264,10 +244,7 @@ fn main() {
264244
"#,
265245
r#"
266246
fn main() {
267-
let x = match Err(92) {
268-
Ok(it) => it,
269-
_ => return,
270-
};
247+
let Ok(x) = Err(92) else { return };
271248
foo(x);
272249
}
273250
"#,
@@ -292,10 +269,7 @@ fn main(n: Option<String>) {
292269
r#"
293270
fn main(n: Option<String>) {
294271
bar();
295-
let n = match n {
296-
Some(it) => it,
297-
_ => return,
298-
};
272+
let Some(n) = n else { return };
299273
foo(n);
300274
301275
// comment
@@ -323,10 +297,7 @@ fn main(n: Option<String>) {
323297
r#"
324298
fn main(n: Option<String>) {
325299
bar();
326-
let mut n = match n {
327-
Some(it) => it,
328-
_ => return,
329-
};
300+
let Some(mut n) = n else { return };
330301
foo(n);
331302
332303
// comment
@@ -354,10 +325,7 @@ fn main(n: Option<&str>) {
354325
r#"
355326
fn main(n: Option<&str>) {
356327
bar();
357-
let ref n = match n {
358-
Some(it) => it,
359-
_ => return,
360-
};
328+
let Some(ref n) = n else { return };
361329
foo(n);
362330
363331
// comment
@@ -412,10 +380,7 @@ fn main() {
412380
r#"
413381
fn main() {
414382
while true {
415-
let n = match n {
416-
Some(it) => it,
417-
_ => continue,
418-
};
383+
let Some(n) = n else { continue };
419384
foo(n);
420385
bar();
421386
}
@@ -469,10 +434,7 @@ fn main() {
469434
r#"
470435
fn main() {
471436
loop {
472-
let n = match n {
473-
Some(it) => it,
474-
_ => continue,
475-
};
437+
let Some(n) = n else { continue };
476438
foo(n);
477439
bar();
478440
}

crates/syntax/src/ast/make.rs

+20
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ pub fn block_expr(
334334
ast_from_text(&format!("fn f() {buf}"))
335335
}
336336

337+
pub fn tail_only_block_expr(tail_expr: ast::Expr) -> ast::BlockExpr {
338+
ast_from_text(&format!("fn f() {{ {tail_expr} }}"))
339+
}
340+
337341
/// Ideally this function wouldn't exist since it involves manual indenting.
338342
/// It differs from `make::block_expr` by also supporting comments.
339343
///
@@ -656,6 +660,22 @@ pub fn let_stmt(
656660
};
657661
ast_from_text(&format!("fn f() {{ {text} }}"))
658662
}
663+
664+
pub fn let_else_stmt(
665+
pattern: ast::Pat,
666+
ty: Option<ast::Type>,
667+
expr: ast::Expr,
668+
diverging: ast::BlockExpr,
669+
) -> ast::LetStmt {
670+
let mut text = String::new();
671+
format_to!(text, "let {pattern}");
672+
if let Some(ty) = ty {
673+
format_to!(text, ": {ty}");
674+
}
675+
format_to!(text, " = {expr} else {diverging};");
676+
ast_from_text(&format!("fn f() {{ {text} }}"))
677+
}
678+
659679
pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
660680
let semi = if expr.is_block_like() { "" } else { ";" };
661681
ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))

0 commit comments

Comments
 (0)