Auto merge of #14037 - Veykril:if-let-match, r=Veykril
Handle boolean scrutinees in match <-> if let replacement assists better
This commit is contained in:
commit
2935a89f3f
@ -13,7 +13,7 @@
|
|||||||
edit::{AstNodeEdit, IndentLevel},
|
edit::{AstNodeEdit, IndentLevel},
|
||||||
make, HasName,
|
make, HasName,
|
||||||
},
|
},
|
||||||
AstNode, TextRange,
|
AstNode, TextRange, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -96,8 +96,9 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
|
|||||||
cond_bodies.push((cond, body));
|
cond_bodies.push((cond, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pat_seen {
|
if !pat_seen && cond_bodies.len() != 1 {
|
||||||
// Don't offer turning an if (chain) without patterns into a match
|
// Don't offer turning an if (chain) without patterns into a match,
|
||||||
|
// unless its a simple `if cond { .. } (else { .. })`
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +115,11 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
|
|||||||
Either::Left(pat) => {
|
Either::Left(pat) => {
|
||||||
make::match_arm(iter::once(pat), None, unwrap_trivial_block(body))
|
make::match_arm(iter::once(pat), None, unwrap_trivial_block(body))
|
||||||
}
|
}
|
||||||
|
Either::Right(_) if !pat_seen => make::match_arm(
|
||||||
|
iter::once(make::literal_pat("true").into()),
|
||||||
|
None,
|
||||||
|
unwrap_trivial_block(body),
|
||||||
|
),
|
||||||
Either::Right(expr) => make::match_arm(
|
Either::Right(expr) => make::match_arm(
|
||||||
iter::once(make::wildcard_pat().into()),
|
iter::once(make::wildcard_pat().into()),
|
||||||
Some(expr),
|
Some(expr),
|
||||||
@ -144,17 +150,15 @@ fn make_else_arm(
|
|||||||
else_block: Option<ast::BlockExpr>,
|
else_block: Option<ast::BlockExpr>,
|
||||||
conditionals: &[(Either<ast::Pat, ast::Expr>, ast::BlockExpr)],
|
conditionals: &[(Either<ast::Pat, ast::Expr>, ast::BlockExpr)],
|
||||||
) -> ast::MatchArm {
|
) -> ast::MatchArm {
|
||||||
if let Some(else_block) = else_block {
|
let (pattern, expr) = if let Some(else_block) = else_block {
|
||||||
let pattern = if let [(Either::Left(pat), _)] = conditionals {
|
let pattern = match conditionals {
|
||||||
ctx.sema
|
[(Either::Right(_), _)] => make::literal_pat("false").into(),
|
||||||
|
[(Either::Left(pat), _)] => match ctx
|
||||||
|
.sema
|
||||||
.type_of_pat(pat)
|
.type_of_pat(pat)
|
||||||
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
|
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
|
||||||
.zip(Some(pat))
|
{
|
||||||
} else {
|
Some(it) => {
|
||||||
None
|
|
||||||
};
|
|
||||||
let pattern = match pattern {
|
|
||||||
Some((it, pat)) => {
|
|
||||||
if does_pat_match_variant(pat, &it.sad_pattern()) {
|
if does_pat_match_variant(pat, &it.sad_pattern()) {
|
||||||
it.happy_pattern_wildcard()
|
it.happy_pattern_wildcard()
|
||||||
} else if does_nested_pattern(pat) {
|
} else if does_nested_pattern(pat) {
|
||||||
@ -164,11 +168,18 @@ fn make_else_arm(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => make::wildcard_pat().into(),
|
None => make::wildcard_pat().into(),
|
||||||
|
},
|
||||||
|
_ => make::wildcard_pat().into(),
|
||||||
};
|
};
|
||||||
make::match_arm(iter::once(pattern), None, unwrap_trivial_block(else_block))
|
(pattern, unwrap_trivial_block(else_block))
|
||||||
} else {
|
} else {
|
||||||
make::match_arm(iter::once(make::wildcard_pat().into()), None, make::expr_unit())
|
let pattern = match conditionals {
|
||||||
}
|
[(Either::Right(_), _)] => make::literal_pat("false").into(),
|
||||||
|
_ => make::wildcard_pat().into(),
|
||||||
|
};
|
||||||
|
(pattern, make::expr_unit())
|
||||||
|
};
|
||||||
|
make::match_arm(iter::once(pattern), None, expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assist: replace_match_with_if_let
|
// Assist: replace_match_with_if_let
|
||||||
@ -231,7 +242,19 @@ fn make_block_expr(expr: ast::Expr) -> ast::BlockExpr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let condition = make::expr_let(if_let_pat, scrutinee);
|
let condition = match if_let_pat {
|
||||||
|
ast::Pat::LiteralPat(p)
|
||||||
|
if p.literal().map_or(false, |it| it.token().kind() == T![true]) =>
|
||||||
|
{
|
||||||
|
scrutinee
|
||||||
|
}
|
||||||
|
ast::Pat::LiteralPat(p)
|
||||||
|
if p.literal().map_or(false, |it| it.token().kind() == T![false]) =>
|
||||||
|
{
|
||||||
|
make::expr_prefix(T![!], scrutinee)
|
||||||
|
}
|
||||||
|
_ => make::expr_let(if_let_pat, scrutinee).into(),
|
||||||
|
};
|
||||||
let then_block = make_block_expr(then_expr.reset_indent());
|
let then_block = make_block_expr(then_expr.reset_indent());
|
||||||
let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
|
let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
|
||||||
let if_let_expr = make::expr_if(
|
let if_let_expr = make::expr_if(
|
||||||
@ -327,6 +350,58 @@ fn main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_if_with_match_no_else() {
|
||||||
|
check_assist(
|
||||||
|
replace_if_let_with_match,
|
||||||
|
r#"
|
||||||
|
pub fn foo(foo: bool) {
|
||||||
|
if foo$0 {
|
||||||
|
self.foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
pub fn foo(foo: bool) {
|
||||||
|
match foo {
|
||||||
|
true => {
|
||||||
|
self.foo();
|
||||||
|
}
|
||||||
|
false => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_if_with_match_with_else() {
|
||||||
|
check_assist(
|
||||||
|
replace_if_let_with_match,
|
||||||
|
r#"
|
||||||
|
pub fn foo(foo: bool) {
|
||||||
|
if foo$0 {
|
||||||
|
self.foo();
|
||||||
|
} else {
|
||||||
|
self.bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
pub fn foo(foo: bool) {
|
||||||
|
match foo {
|
||||||
|
true => {
|
||||||
|
self.foo();
|
||||||
|
}
|
||||||
|
false => {
|
||||||
|
self.bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_if_let_with_match_no_else() {
|
fn test_if_let_with_match_no_else() {
|
||||||
check_assist(
|
check_assist(
|
||||||
@ -993,6 +1068,66 @@ fn main() {
|
|||||||
code()
|
code()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_replace_match_with_if_bool() {
|
||||||
|
check_assist(
|
||||||
|
replace_match_with_if_let,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
match$0 b {
|
||||||
|
true => (),
|
||||||
|
_ => code(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
if b {
|
||||||
|
()
|
||||||
|
} else {
|
||||||
|
code()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
replace_match_with_if_let,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
match$0 b {
|
||||||
|
false => code(),
|
||||||
|
true => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
if !b {
|
||||||
|
code()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
replace_match_with_if_let,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
match$0 b {
|
||||||
|
false => (),
|
||||||
|
true => code(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
if b {
|
||||||
|
code()
|
||||||
|
}
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user