Skip to content

Commit

Permalink
Auto merge of rust-lang#13527 - unexge:use-let-else-stmt-in-convert-t…
Browse files Browse the repository at this point in the history
…o-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)
  • Loading branch information
bors committed Nov 2, 2022
2 parents af1f48d + 62a6cdf commit 6c3ab56
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 54 deletions.
70 changes: 16 additions & 54 deletions crates/ide-assists/src/handlers/convert_to_guarded_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,32 +129,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
}
Some((path, bound_ident)) => {
// If-let.
let match_expr = {
let happy_arm = {
let pat = make::tuple_struct_pat(
path,
once(make::ext::simple_ident_pat(make::name("it")).into()),
);
let expr = {
let path = make::ext::ident_path("it");
make::expr_path(path)
};
make::match_arm(once(pat.into()), None, expr)
};

let sad_arm = make::match_arm(
// FIXME: would be cool to use `None` or `Err(_)` if appropriate
once(make::wildcard_pat().into()),
None,
early_expression,
);

make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm]))
};

let let_stmt = make::let_stmt(bound_ident, None, Some(match_expr));
let let_stmt = let_stmt.indent(if_indent_level);
let_stmt.syntax().clone_for_update()
let pat = make::tuple_struct_pat(path, once(bound_ident));
let let_else_stmt = make::let_else_stmt(
pat.into(),
None,
cond_expr,
ast::make::tail_only_block_expr(early_expression),
);
let let_else_stmt = let_else_stmt.indent(if_indent_level);
let_else_stmt.syntax().clone_for_update()
}
};

Expand Down Expand Up @@ -238,10 +221,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
let n = match n {
Some(it) => it,
_ => return,
};
let Some(n) = n else { return };
foo(n);
// comment
Expand All @@ -264,10 +244,7 @@ fn main() {
"#,
r#"
fn main() {
let x = match Err(92) {
Ok(it) => it,
_ => return,
};
let Ok(x) = Err(92) else { return };
foo(x);
}
"#,
Expand All @@ -292,10 +269,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
let n = match n {
Some(it) => it,
_ => return,
};
let Some(n) = n else { return };
foo(n);
// comment
Expand Down Expand Up @@ -323,10 +297,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
let mut n = match n {
Some(it) => it,
_ => return,
};
let Some(mut n) = n else { return };
foo(n);
// comment
Expand Down Expand Up @@ -354,10 +325,7 @@ fn main(n: Option<&str>) {
r#"
fn main(n: Option<&str>) {
bar();
let ref n = match n {
Some(it) => it,
_ => return,
};
let Some(ref n) = n else { return };
foo(n);
// comment
Expand Down Expand Up @@ -412,10 +380,7 @@ fn main() {
r#"
fn main() {
while true {
let n = match n {
Some(it) => it,
_ => continue,
};
let Some(n) = n else { continue };
foo(n);
bar();
}
Expand Down Expand Up @@ -469,10 +434,7 @@ fn main() {
r#"
fn main() {
loop {
let n = match n {
Some(it) => it,
_ => continue,
};
let Some(n) = n else { continue };
foo(n);
bar();
}
Expand Down
20 changes: 20 additions & 0 deletions crates/syntax/src/ast/make.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ pub fn block_expr(
ast_from_text(&format!("fn f() {buf}"))
}

pub fn tail_only_block_expr(tail_expr: ast::Expr) -> ast::BlockExpr {
ast_from_text(&format!("fn f() {{ {tail_expr} }}"))
}

/// Ideally this function wouldn't exist since it involves manual indenting.
/// It differs from `make::block_expr` by also supporting comments.
///
Expand Down Expand Up @@ -656,6 +660,22 @@ pub fn let_stmt(
};
ast_from_text(&format!("fn f() {{ {text} }}"))
}

pub fn let_else_stmt(
pattern: ast::Pat,
ty: Option<ast::Type>,
expr: ast::Expr,
diverging: ast::BlockExpr,
) -> ast::LetStmt {
let mut text = String::new();
format_to!(text, "let {pattern}");
if let Some(ty) = ty {
format_to!(text, ": {ty}");
}
format_to!(text, " = {expr} else {diverging};");
ast_from_text(&format!("fn f() {{ {text} }}"))
}

pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
let semi = if expr.is_block_like() { "" } else { ";" };
ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))
Expand Down

0 comments on commit 6c3ab56

Please sign in to comment.