2021-07-01 17:20:27 -05:00
|
|
|
use std::iter::{self, successors};
|
2020-12-05 08:41:36 -06:00
|
|
|
|
2021-07-01 17:58:56 -05:00
|
|
|
use either::Either;
|
2022-02-21 00:15:21 -06:00
|
|
|
use ide_db::{
|
|
|
|
defs::NameClass,
|
2022-03-06 12:01:30 -06:00
|
|
|
syntax_helpers::node_ext::{is_pattern_cond, single_let},
|
2022-02-21 00:15:21 -06:00
|
|
|
ty_filter::TryEnum,
|
|
|
|
RootDatabase,
|
|
|
|
};
|
2020-08-12 11:26:51 -05:00
|
|
|
use syntax::{
|
2020-05-09 07:40:11 -05:00
|
|
|
ast::{
|
|
|
|
self,
|
|
|
|
edit::{AstNodeEdit, IndentLevel},
|
2021-09-27 05:54:24 -05:00
|
|
|
make, HasName,
|
2020-05-09 07:40:11 -05:00
|
|
|
},
|
2021-09-17 15:27:24 -05:00
|
|
|
AstNode, TextRange,
|
2020-02-05 03:50:07 -06:00
|
|
|
};
|
2019-01-08 05:21:29 -06:00
|
|
|
|
2021-01-22 16:31:19 -06:00
|
|
|
use crate::{
|
2021-10-13 08:02:39 -05:00
|
|
|
utils::{does_nested_pattern, does_pat_match_variant, unwrap_trivial_block},
|
2021-01-22 16:31:19 -06:00
|
|
|
AssistContext, AssistId, AssistKind, Assists,
|
|
|
|
};
|
2019-01-08 05:21:29 -06:00
|
|
|
|
2019-10-27 04:22:53 -05:00
|
|
|
// Assist: replace_if_let_with_match
|
|
|
|
//
|
2021-07-01 17:20:27 -05:00
|
|
|
// Replaces a `if let` expression with a `match` expression.
|
2019-10-27 04:22:53 -05:00
|
|
|
//
|
|
|
|
// ```
|
|
|
|
// enum Action { Move { distance: u32 }, Stop }
|
|
|
|
//
|
|
|
|
// fn handle(action: Action) {
|
2021-01-06 14:15:48 -06:00
|
|
|
// $0if let Action::Move { distance } = action {
|
2019-10-27 04:22:53 -05:00
|
|
|
// foo(distance)
|
|
|
|
// } else {
|
|
|
|
// bar()
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ```
|
|
|
|
// ->
|
|
|
|
// ```
|
|
|
|
// enum Action { Move { distance: u32 }, Stop }
|
|
|
|
//
|
|
|
|
// fn handle(action: Action) {
|
|
|
|
// match action {
|
|
|
|
// Action::Move { distance } => foo(distance),
|
|
|
|
// _ => bar(),
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ```
|
2020-05-06 11:45:35 -05:00
|
|
|
pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
2019-10-27 03:48:40 -05:00
|
|
|
let if_expr: ast::IfExpr = ctx.find_node_at_offset()?;
|
2021-09-17 15:27:24 -05:00
|
|
|
let available_range = TextRange::new(
|
|
|
|
if_expr.syntax().text_range().start(),
|
|
|
|
if_expr.then_branch()?.syntax().text_range().start(),
|
|
|
|
);
|
2021-10-12 07:41:59 -05:00
|
|
|
let cursor_in_range = available_range.contains_range(ctx.selection_trimmed());
|
2021-09-17 15:27:24 -05:00
|
|
|
if !cursor_in_range {
|
|
|
|
return None;
|
|
|
|
}
|
2021-07-01 17:20:27 -05:00
|
|
|
let mut else_block = None;
|
|
|
|
let if_exprs = successors(Some(if_expr.clone()), |expr| match expr.else_branch()? {
|
|
|
|
ast::ElseBranch::IfExpr(expr) => Some(expr),
|
|
|
|
ast::ElseBranch::Block(block) => {
|
|
|
|
else_block = Some(block);
|
|
|
|
None
|
|
|
|
}
|
|
|
|
});
|
2022-01-23 16:37:59 -06:00
|
|
|
let scrutinee_to_be_expr = if_expr.condition()?;
|
2022-02-21 00:15:21 -06:00
|
|
|
let scrutinee_to_be_expr = match single_let(scrutinee_to_be_expr.clone()) {
|
2022-01-23 16:37:59 -06:00
|
|
|
Some(cond) => cond.expr()?,
|
|
|
|
None => scrutinee_to_be_expr,
|
|
|
|
};
|
2021-07-01 17:20:27 -05:00
|
|
|
|
2021-07-01 17:58:56 -05:00
|
|
|
let mut pat_seen = false;
|
|
|
|
let mut cond_bodies = Vec::new();
|
2021-07-01 17:20:27 -05:00
|
|
|
for if_expr in if_exprs {
|
|
|
|
let cond = if_expr.condition()?;
|
2022-02-21 00:15:21 -06:00
|
|
|
let cond = match single_let(cond.clone()) {
|
2022-01-23 16:37:59 -06:00
|
|
|
Some(let_) => {
|
|
|
|
let pat = let_.pat()?;
|
|
|
|
let expr = let_.expr()?;
|
|
|
|
// FIXME: If one `let` is wrapped in parentheses and the second is not,
|
|
|
|
// we'll exit here.
|
2021-07-01 17:58:56 -05:00
|
|
|
if scrutinee_to_be_expr.syntax().text() != expr.syntax().text() {
|
|
|
|
// Only if all condition expressions are equal we can merge them into a match
|
|
|
|
return None;
|
|
|
|
}
|
2021-07-01 18:44:54 -05:00
|
|
|
pat_seen = true;
|
|
|
|
Either::Left(pat)
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
2022-01-23 16:37:59 -06:00
|
|
|
// Multiple `let`, unsupported.
|
2022-02-21 00:15:21 -06:00
|
|
|
None if is_pattern_cond(cond.clone()) => return None,
|
2022-01-23 16:37:59 -06:00
|
|
|
None => Either::Right(cond),
|
2021-07-01 17:58:56 -05:00
|
|
|
};
|
2021-07-01 17:20:27 -05:00
|
|
|
let body = if_expr.then_branch()?;
|
2021-07-01 17:58:56 -05:00
|
|
|
cond_bodies.push((cond, body));
|
|
|
|
}
|
|
|
|
|
|
|
|
if !pat_seen {
|
|
|
|
// Don't offer turning an if (chain) without patterns into a match
|
|
|
|
return None;
|
2021-07-01 17:20:27 -05:00
|
|
|
}
|
2019-01-08 05:21:29 -06:00
|
|
|
|
2020-06-28 17:36:05 -05:00
|
|
|
acc.add(
|
2020-07-02 16:48:35 -05:00
|
|
|
AssistId("replace_if_let_with_match", AssistKind::RefactorRewrite),
|
2021-07-10 10:41:25 -05:00
|
|
|
"Replace if let with match",
|
2021-09-17 15:27:24 -05:00
|
|
|
available_range,
|
2020-06-28 17:36:05 -05:00
|
|
|
move |edit| {
|
|
|
|
let match_expr = {
|
2021-07-31 07:29:15 -05:00
|
|
|
let else_arm = make_else_arm(ctx, else_block, &cond_bodies);
|
2021-07-02 12:50:37 -05:00
|
|
|
let make_match_arm = |(pat, body): (_, ast::BlockExpr)| {
|
|
|
|
let body = body.reset_indent().indent(IndentLevel(1));
|
|
|
|
match pat {
|
|
|
|
Either::Left(pat) => {
|
|
|
|
make::match_arm(iter::once(pat), None, unwrap_trivial_block(body))
|
2021-07-01 17:20:27 -05:00
|
|
|
}
|
2021-07-02 12:50:37 -05:00
|
|
|
Either::Right(expr) => make::match_arm(
|
2021-07-01 17:20:27 -05:00
|
|
|
iter::once(make::wildcard_pat().into()),
|
2021-07-02 12:50:37 -05:00
|
|
|
Some(expr),
|
|
|
|
unwrap_trivial_block(body),
|
2021-07-01 17:20:27 -05:00
|
|
|
),
|
|
|
|
}
|
2020-06-28 17:36:05 -05:00
|
|
|
};
|
2021-07-02 12:50:37 -05:00
|
|
|
let arms = cond_bodies.into_iter().map(make_match_arm).chain(iter::once(else_arm));
|
2021-07-01 17:20:27 -05:00
|
|
|
let match_expr = make::expr_match(scrutinee_to_be_expr, make::match_arm_list(arms));
|
2020-06-28 17:36:05 -05:00
|
|
|
match_expr.indent(IndentLevel::from_node(if_expr.syntax()))
|
2020-02-05 03:50:07 -06:00
|
|
|
};
|
2019-01-08 05:21:29 -06:00
|
|
|
|
2021-07-01 17:58:56 -05:00
|
|
|
let has_preceding_if_expr =
|
|
|
|
if_expr.syntax().parent().map_or(false, |it| ast::IfExpr::can_cast(it.kind()));
|
|
|
|
let expr = if has_preceding_if_expr {
|
|
|
|
// make sure we replace the `else if let ...` with a block so we don't end up with `else expr`
|
|
|
|
make::block_expr(None, Some(match_expr)).into()
|
|
|
|
} else {
|
|
|
|
match_expr
|
|
|
|
};
|
2021-07-01 17:20:27 -05:00
|
|
|
edit.replace_ast::<ast::Expr>(if_expr.into(), expr);
|
2020-06-28 17:36:05 -05:00
|
|
|
},
|
|
|
|
)
|
2019-01-08 05:21:29 -06:00
|
|
|
}
|
|
|
|
|
2021-07-02 12:50:37 -05:00
|
|
|
fn make_else_arm(
|
|
|
|
ctx: &AssistContext,
|
2021-07-31 07:29:15 -05:00
|
|
|
else_block: Option<ast::BlockExpr>,
|
|
|
|
conditionals: &[(Either<ast::Pat, ast::Expr>, ast::BlockExpr)],
|
2021-07-02 12:50:37 -05:00
|
|
|
) -> ast::MatchArm {
|
|
|
|
if let Some(else_block) = else_block {
|
2021-07-31 07:29:15 -05:00
|
|
|
let pattern = if let [(Either::Left(pat), _)] = conditionals {
|
2021-07-02 12:50:37 -05:00
|
|
|
ctx.sema
|
2021-09-13 11:50:19 -05:00
|
|
|
.type_of_pat(pat)
|
2021-08-03 10:28:51 -05:00
|
|
|
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
|
2021-07-02 12:50:37 -05:00
|
|
|
.zip(Some(pat))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let pattern = match pattern {
|
|
|
|
Some((it, pat)) => {
|
2021-09-13 11:50:19 -05:00
|
|
|
if does_pat_match_variant(pat, &it.sad_pattern()) {
|
2021-10-06 13:11:00 -05:00
|
|
|
it.happy_pattern_wildcard()
|
2021-10-13 08:02:39 -05:00
|
|
|
} else if does_nested_pattern(pat) {
|
|
|
|
make::wildcard_pat().into()
|
2021-07-02 12:50:37 -05:00
|
|
|
} else {
|
|
|
|
it.sad_pattern()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => make::wildcard_pat().into(),
|
|
|
|
};
|
|
|
|
make::match_arm(iter::once(pattern), None, unwrap_trivial_block(else_block))
|
|
|
|
} else {
|
2021-09-13 11:50:19 -05:00
|
|
|
make::match_arm(iter::once(make::wildcard_pat().into()), None, make::expr_unit())
|
2021-07-02 12:50:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-05 08:41:36 -06:00
|
|
|
// Assist: replace_match_with_if_let
|
|
|
|
//
|
|
|
|
// Replaces a binary `match` with a wildcard pattern and no guards with an `if let` expression.
|
|
|
|
//
|
|
|
|
// ```
|
|
|
|
// enum Action { Move { distance: u32 }, Stop }
|
|
|
|
//
|
|
|
|
// fn handle(action: Action) {
|
2021-01-06 14:15:48 -06:00
|
|
|
// $0match action {
|
2020-12-05 08:41:36 -06:00
|
|
|
// Action::Move { distance } => foo(distance),
|
|
|
|
// _ => bar(),
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ```
|
|
|
|
// ->
|
|
|
|
// ```
|
|
|
|
// enum Action { Move { distance: u32 }, Stop }
|
|
|
|
//
|
|
|
|
// fn handle(action: Action) {
|
|
|
|
// if let Action::Move { distance } = action {
|
|
|
|
// foo(distance)
|
|
|
|
// } else {
|
|
|
|
// bar()
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ```
|
|
|
|
pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
|
|
|
let match_expr: ast::MatchExpr = ctx.find_node_at_offset()?;
|
2021-07-02 14:05:10 -05:00
|
|
|
|
2020-12-05 08:41:36 -06:00
|
|
|
let mut arms = match_expr.match_arm_list()?.arms();
|
2021-07-02 14:05:10 -05:00
|
|
|
let (first_arm, second_arm) = (arms.next()?, arms.next()?);
|
2020-12-05 08:41:36 -06:00
|
|
|
if arms.next().is_some() || first_arm.guard().is_some() || second_arm.guard().is_some() {
|
|
|
|
return None;
|
|
|
|
}
|
2021-07-02 14:05:10 -05:00
|
|
|
|
|
|
|
let (if_let_pat, then_expr, else_expr) = pick_pattern_and_expr_order(
|
|
|
|
&ctx.sema,
|
|
|
|
first_arm.pat()?,
|
|
|
|
second_arm.pat()?,
|
|
|
|
first_arm.expr()?,
|
|
|
|
second_arm.expr()?,
|
|
|
|
)?;
|
|
|
|
let scrutinee = match_expr.expr()?;
|
2020-12-05 08:41:36 -06:00
|
|
|
|
|
|
|
let target = match_expr.syntax().text_range();
|
|
|
|
acc.add(
|
|
|
|
AssistId("replace_match_with_if_let", AssistKind::RefactorRewrite),
|
2021-07-10 10:41:25 -05:00
|
|
|
"Replace match with if let",
|
2020-12-05 08:41:36 -06:00
|
|
|
target,
|
|
|
|
move |edit| {
|
2022-01-03 04:20:59 -06:00
|
|
|
fn make_block_expr(expr: ast::Expr) -> ast::BlockExpr {
|
|
|
|
// Blocks with modifiers (unsafe, async, etc.) are parsed as BlockExpr, but are
|
|
|
|
// formatted without enclosing braces. If we encounter such block exprs,
|
|
|
|
// wrap them in another BlockExpr.
|
|
|
|
match expr {
|
|
|
|
ast::Expr::BlockExpr(block) if block.modifier().is_none() => block,
|
|
|
|
expr => make::block_expr(iter::empty(), Some(expr)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-23 16:37:59 -06:00
|
|
|
let condition = make::expr_let(if_let_pat, scrutinee);
|
2022-01-03 04:20:59 -06:00
|
|
|
let then_block = make_block_expr(then_expr.reset_indent());
|
2021-10-02 07:24:32 -05:00
|
|
|
let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
|
2020-12-05 08:41:36 -06:00
|
|
|
let if_let_expr = make::expr_if(
|
2022-01-23 16:37:59 -06:00
|
|
|
condition.into(),
|
2020-12-05 08:41:36 -06:00
|
|
|
then_block,
|
2022-01-03 04:20:59 -06:00
|
|
|
else_expr.map(make_block_expr).map(ast::ElseBranch::Block),
|
2020-12-05 08:41:36 -06:00
|
|
|
)
|
|
|
|
.indent(IndentLevel::from_node(match_expr.syntax()));
|
|
|
|
|
|
|
|
edit.replace_ast::<ast::Expr>(match_expr.into(), if_let_expr);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-07-02 14:05:10 -05:00
|
|
|
/// Pick the pattern for the if let condition and return the expressions for the `then` body and `else` body in that order.
|
|
|
|
fn pick_pattern_and_expr_order(
|
|
|
|
sema: &hir::Semantics<RootDatabase>,
|
|
|
|
pat: ast::Pat,
|
|
|
|
pat2: ast::Pat,
|
|
|
|
expr: ast::Expr,
|
|
|
|
expr2: ast::Expr,
|
|
|
|
) -> Option<(ast::Pat, ast::Expr, ast::Expr)> {
|
|
|
|
let res = match (pat, pat2) {
|
|
|
|
(ast::Pat::WildcardPat(_), _) => return None,
|
2022-06-04 18:02:24 -05:00
|
|
|
(pat, ast::Pat::WildcardPat(_)) => (pat, expr, expr2),
|
2021-08-21 04:00:43 -05:00
|
|
|
(pat, _) if is_empty_expr(&expr2) => (pat, expr, expr2),
|
|
|
|
(_, pat) if is_empty_expr(&expr) => (pat, expr2, expr),
|
2021-08-21 04:11:27 -05:00
|
|
|
(pat, pat2) => match (binds_name(sema, &pat), binds_name(sema, &pat2)) {
|
2021-08-21 04:00:43 -05:00
|
|
|
(true, true) => return None,
|
2021-07-02 14:05:10 -05:00
|
|
|
(true, false) => (pat, expr, expr2),
|
|
|
|
(false, true) => (pat2, expr2, expr),
|
2021-08-20 08:20:54 -05:00
|
|
|
_ if is_sad_pat(sema, &pat) => (pat2, expr2, expr),
|
2021-07-02 14:05:10 -05:00
|
|
|
(false, false) => (pat, expr, expr2),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
Some(res)
|
|
|
|
}
|
|
|
|
|
2021-08-21 04:00:43 -05:00
|
|
|
fn is_empty_expr(expr: &ast::Expr) -> bool {
|
|
|
|
match expr {
|
2021-10-02 07:26:02 -05:00
|
|
|
ast::Expr::BlockExpr(expr) => match expr.stmt_list() {
|
|
|
|
Some(it) => it.statements().next().is_none() && it.tail_expr().is_none(),
|
|
|
|
None => true,
|
|
|
|
},
|
2021-08-21 04:00:43 -05:00
|
|
|
ast::Expr::TupleExpr(expr) => expr.fields().next().is_none(),
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-21 04:11:27 -05:00
|
|
|
fn binds_name(sema: &hir::Semantics<RootDatabase>, pat: &ast::Pat) -> bool {
|
2021-09-13 11:50:19 -05:00
|
|
|
let binds_name_v = |pat| binds_name(sema, &pat);
|
2021-07-02 14:05:10 -05:00
|
|
|
match pat {
|
2021-08-21 05:02:21 -05:00
|
|
|
ast::Pat::IdentPat(pat) => !matches!(
|
|
|
|
pat.name().and_then(|name| NameClass::classify(sema, &name)),
|
|
|
|
Some(NameClass::ConstReference(_))
|
|
|
|
),
|
2021-07-02 14:05:10 -05:00
|
|
|
ast::Pat::MacroPat(_) => true,
|
|
|
|
ast::Pat::OrPat(pat) => pat.pats().any(binds_name_v),
|
|
|
|
ast::Pat::SlicePat(pat) => pat.pats().any(binds_name_v),
|
|
|
|
ast::Pat::TuplePat(it) => it.fields().any(binds_name_v),
|
|
|
|
ast::Pat::TupleStructPat(it) => it.fields().any(binds_name_v),
|
|
|
|
ast::Pat::RecordPat(it) => it
|
|
|
|
.record_pat_field_list()
|
|
|
|
.map_or(false, |rpfl| rpfl.fields().flat_map(|rpf| rpf.pat()).any(binds_name_v)),
|
|
|
|
ast::Pat::RefPat(pat) => pat.pat().map_or(false, binds_name_v),
|
|
|
|
ast::Pat::BoxPat(pat) => pat.pat().map_or(false, binds_name_v),
|
|
|
|
ast::Pat::ParenPat(pat) => pat.pat().map_or(false, binds_name_v),
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2021-07-02 14:10:38 -05:00
|
|
|
|
2021-07-02 14:05:10 -05:00
|
|
|
fn is_sad_pat(sema: &hir::Semantics<RootDatabase>, pat: &ast::Pat) -> bool {
|
2021-06-12 22:54:16 -05:00
|
|
|
sema.type_of_pat(pat)
|
2021-08-03 10:28:51 -05:00
|
|
|
.and_then(|ty| TryEnum::from_ty(sema, &ty.adjusted()))
|
2021-07-02 14:10:38 -05:00
|
|
|
.map_or(false, |it| does_pat_match_variant(pat, &it.sad_pattern()))
|
2020-12-05 08:41:36 -06:00
|
|
|
}
|
|
|
|
|
2019-01-08 05:21:29 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2020-04-29 04:57:06 -05:00
|
|
|
|
2021-07-01 17:58:56 -05:00
|
|
|
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_if_let_with_match_unapplicable_for_simple_ifs() {
|
|
|
|
check_assist_not_applicable(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if $0true {} else if false {} else {}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
2019-01-08 05:21:29 -06:00
|
|
|
|
|
|
|
#[test]
|
2021-07-01 17:20:27 -05:00
|
|
|
fn test_if_let_with_match_no_else() {
|
2019-01-08 05:21:29 -06:00
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
2020-05-20 16:50:29 -05:00
|
|
|
r#"
|
2019-01-08 05:21:29 -06:00
|
|
|
impl VariantData {
|
2021-07-01 17:20:27 -05:00
|
|
|
pub fn foo(&self) {
|
2021-01-06 14:15:48 -06:00
|
|
|
if $0let VariantData::Struct(..) = *self {
|
2021-07-01 17:20:27 -05:00
|
|
|
self.foo();
|
2019-01-08 05:21:29 -06:00
|
|
|
}
|
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2020-05-20 16:50:29 -05:00
|
|
|
r#"
|
2019-01-08 05:21:29 -06:00
|
|
|
impl VariantData {
|
2021-07-01 17:20:27 -05:00
|
|
|
pub fn foo(&self) {
|
2020-05-20 16:50:29 -05:00
|
|
|
match *self {
|
2021-07-01 17:20:27 -05:00
|
|
|
VariantData::Struct(..) => {
|
|
|
|
self.foo();
|
|
|
|
}
|
|
|
|
_ => (),
|
2019-01-08 05:21:29 -06:00
|
|
|
}
|
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2019-01-08 05:21:29 -06:00
|
|
|
)
|
|
|
|
}
|
2019-02-08 17:34:05 -06:00
|
|
|
|
2021-09-17 15:27:24 -05:00
|
|
|
#[test]
|
|
|
|
fn test_if_let_with_match_available_range_left() {
|
|
|
|
check_assist_not_applicable(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn foo(&self) {
|
|
|
|
$0 if let VariantData::Struct(..) = *self {
|
|
|
|
self.foo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_if_let_with_match_available_range_right() {
|
|
|
|
check_assist_not_applicable(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn foo(&self) {
|
|
|
|
if let VariantData::Struct(..) = *self {$0
|
|
|
|
self.foo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-23 20:50:07 -06:00
|
|
|
#[test]
|
|
|
|
fn test_if_let_with_match_let_chain() {
|
|
|
|
check_assist_not_applicable(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if $0let true = true && let Some(1) = None {}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-11-20 12:01:06 -06:00
|
|
|
#[test]
|
2021-07-01 17:20:27 -05:00
|
|
|
fn test_if_let_with_match_basic() {
|
2019-11-20 12:01:06 -06:00
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
2020-05-20 16:50:29 -05:00
|
|
|
r#"
|
2021-07-01 17:20:27 -05:00
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
if $0let VariantData::Struct(..) = *self {
|
|
|
|
true
|
|
|
|
} else if let VariantData::Tuple(..) = *self {
|
|
|
|
false
|
2021-07-01 17:58:56 -05:00
|
|
|
} else if cond() {
|
|
|
|
true
|
2021-07-01 17:20:27 -05:00
|
|
|
} else {
|
2019-11-20 12:01:06 -06:00
|
|
|
bar(
|
|
|
|
123
|
|
|
|
)
|
|
|
|
}
|
2021-07-01 17:20:27 -05:00
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2021-07-01 17:20:27 -05:00
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
VariantData::Struct(..) => true,
|
|
|
|
VariantData::Tuple(..) => false,
|
2021-07-01 17:58:56 -05:00
|
|
|
_ if cond() => true,
|
2021-07-01 17:20:27 -05:00
|
|
|
_ => {
|
|
|
|
bar(
|
|
|
|
123
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2019-11-20 12:01:06 -06:00
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2019-11-20 12:01:06 -06:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-02-08 17:34:05 -06:00
|
|
|
#[test]
|
2021-07-01 17:20:27 -05:00
|
|
|
fn test_if_let_with_match_on_tail_if_let() {
|
|
|
|
check_assist(
|
2019-02-08 17:34:05 -06:00
|
|
|
replace_if_let_with_match,
|
2020-05-20 16:50:29 -05:00
|
|
|
r#"
|
2019-02-08 17:34:05 -06:00
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
2021-07-01 17:20:27 -05:00
|
|
|
if let VariantData::Struct(..) = *self {
|
2019-02-08 17:34:05 -06:00
|
|
|
true
|
2021-07-01 17:20:27 -05:00
|
|
|
} else if let$0 VariantData::Tuple(..) = *self {
|
|
|
|
false
|
2019-02-08 17:34:05 -06:00
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2021-07-01 17:20:27 -05:00
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
if let VariantData::Struct(..) = *self {
|
2019-02-08 17:34:05 -06:00
|
|
|
true
|
|
|
|
} else {
|
2021-07-01 17:20:27 -05:00
|
|
|
match *self {
|
|
|
|
VariantData::Tuple(..) => false,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-01 17:58:56 -05:00
|
|
|
}
|
|
|
|
"#,
|
2021-07-01 17:20:27 -05:00
|
|
|
)
|
2019-02-08 17:34:05 -06:00
|
|
|
}
|
2020-04-29 04:57:06 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn special_case_option() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: option
|
2020-04-29 04:57:06 -05:00
|
|
|
fn foo(x: Option<i32>) {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0if let Some(x) = x {
|
2020-04-29 04:57:06 -05:00
|
|
|
println!("{}", x)
|
|
|
|
} else {
|
|
|
|
println!("none")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-04-29 04:57:06 -05:00
|
|
|
r#"
|
|
|
|
fn foo(x: Option<i32>) {
|
2020-05-20 16:50:29 -05:00
|
|
|
match x {
|
2020-04-29 04:57:06 -05:00
|
|
|
Some(x) => println!("{}", x),
|
|
|
|
None => println!("none"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-04-29 04:57:06 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-22 16:29:51 -06:00
|
|
|
#[test]
|
|
|
|
fn special_case_inverted_option() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: option
|
2021-01-22 16:29:51 -06:00
|
|
|
fn foo(x: Option<i32>) {
|
|
|
|
$0if let None = x {
|
|
|
|
println!("none")
|
|
|
|
} else {
|
|
|
|
println!("some")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2021-01-22 16:29:51 -06:00
|
|
|
r#"
|
|
|
|
fn foo(x: Option<i32>) {
|
|
|
|
match x {
|
|
|
|
None => println!("none"),
|
|
|
|
Some(_) => println!("some"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2021-01-22 16:29:51 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-04-29 04:57:06 -05:00
|
|
|
#[test]
|
|
|
|
fn special_case_result() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: result
|
2020-04-29 04:57:06 -05:00
|
|
|
fn foo(x: Result<i32, ()>) {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0if let Ok(x) = x {
|
2020-04-29 04:57:06 -05:00
|
|
|
println!("{}", x)
|
|
|
|
} else {
|
|
|
|
println!("none")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-04-29 04:57:06 -05:00
|
|
|
r#"
|
|
|
|
fn foo(x: Result<i32, ()>) {
|
2020-05-20 16:50:29 -05:00
|
|
|
match x {
|
2020-04-29 04:57:06 -05:00
|
|
|
Ok(x) => println!("{}", x),
|
|
|
|
Err(_) => println!("none"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-04-29 04:57:06 -05:00
|
|
|
);
|
|
|
|
}
|
2020-06-09 05:38:47 -05:00
|
|
|
|
2021-01-22 16:29:51 -06:00
|
|
|
#[test]
|
|
|
|
fn special_case_inverted_result() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: result
|
2021-01-22 16:29:51 -06:00
|
|
|
fn foo(x: Result<i32, ()>) {
|
|
|
|
$0if let Err(x) = x {
|
|
|
|
println!("{}", x)
|
|
|
|
} else {
|
|
|
|
println!("ok")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2021-01-22 16:29:51 -06:00
|
|
|
r#"
|
|
|
|
fn foo(x: Result<i32, ()>) {
|
|
|
|
match x {
|
|
|
|
Err(x) => println!("{}", x),
|
|
|
|
Ok(_) => println!("ok"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2021-01-22 16:29:51 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-09 05:38:47 -05:00
|
|
|
#[test]
|
|
|
|
fn nested_indent() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if true {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0if let Ok(rel_path) = path.strip_prefix(root_path) {
|
2020-06-09 05:38:47 -05:00
|
|
|
let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
|
|
|
|
Some((*id, rel_path))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if true {
|
|
|
|
match path.strip_prefix(root_path) {
|
|
|
|
Ok(rel_path) => {
|
|
|
|
let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
|
|
|
|
Some((*id, rel_path))
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-05 08:41:36 -06:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-10-13 07:03:01 -05:00
|
|
|
#[test]
|
|
|
|
fn nested_type() {
|
|
|
|
check_assist(
|
|
|
|
replace_if_let_with_match,
|
|
|
|
r#"
|
|
|
|
//- minicore: result
|
|
|
|
fn foo(x: Result<i32, ()>) {
|
|
|
|
let bar: Result<_, ()> = Ok(Some(1));
|
|
|
|
$0if let Ok(Some(_)) = bar {
|
|
|
|
()
|
|
|
|
} else {
|
|
|
|
()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn foo(x: Result<i32, ()>) {
|
|
|
|
let bar: Result<_, ()> = Ok(Some(1));
|
|
|
|
match bar {
|
|
|
|
Ok(Some(_)) => (),
|
|
|
|
_ => (),
|
|
|
|
}
|
2021-10-13 08:02:39 -05:00
|
|
|
}
|
2021-10-13 07:03:01 -05:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-12-05 08:41:36 -06:00
|
|
|
#[test]
|
|
|
|
fn test_replace_match_with_if_let_unwraps_simple_expressions() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match *self {
|
2020-12-05 08:41:36 -06:00
|
|
|
VariantData::Struct(..) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
if let VariantData::Struct(..) = *self {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_replace_match_with_if_let_doesnt_unwrap_multiline_expressions() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match a {
|
2020-12-05 08:41:36 -06:00
|
|
|
VariantData::Struct(..) => {
|
|
|
|
bar(
|
|
|
|
123
|
|
|
|
)
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if let VariantData::Struct(..) = a {
|
|
|
|
bar(
|
|
|
|
123
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_target() {
|
|
|
|
check_assist_target(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match *self {
|
2020-12-05 08:41:36 -06:00
|
|
|
VariantData::Struct(..) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
r#"match *self {
|
|
|
|
VariantData::Struct(..) => true,
|
|
|
|
_ => false,
|
|
|
|
}"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn special_case_option_match_to_if_let() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: option
|
2020-12-05 08:41:36 -06:00
|
|
|
fn foo(x: Option<i32>) {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match x {
|
2020-12-05 08:41:36 -06:00
|
|
|
Some(x) => println!("{}", x),
|
|
|
|
None => println!("none"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-12-05 08:41:36 -06:00
|
|
|
r#"
|
|
|
|
fn foo(x: Option<i32>) {
|
|
|
|
if let Some(x) = x {
|
|
|
|
println!("{}", x)
|
|
|
|
} else {
|
|
|
|
println!("none")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-12-05 08:41:36 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn special_case_result_match_to_if_let() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
2021-06-18 15:28:37 -05:00
|
|
|
//- minicore: result
|
2020-12-05 08:41:36 -06:00
|
|
|
fn foo(x: Result<i32, ()>) {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match x {
|
2020-12-05 08:41:36 -06:00
|
|
|
Ok(x) => println!("{}", x),
|
|
|
|
Err(_) => println!("none"),
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-12-05 08:41:36 -06:00
|
|
|
r#"
|
|
|
|
fn foo(x: Result<i32, ()>) {
|
|
|
|
if let Ok(x) = x {
|
|
|
|
println!("{}", x)
|
|
|
|
} else {
|
|
|
|
println!("none")
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 15:28:37 -05:00
|
|
|
"#,
|
2020-12-05 08:41:36 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nested_indent_match_to_if_let() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if true {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match path.strip_prefix(root_path) {
|
2020-12-05 08:41:36 -06:00
|
|
|
Ok(rel_path) => {
|
|
|
|
let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
|
|
|
|
Some((*id, rel_path))
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if true {
|
|
|
|
if let Ok(rel_path) = path.strip_prefix(root_path) {
|
|
|
|
let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
|
|
|
|
Some((*id, rel_path))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_empty_wildcard_expr() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
2021-01-06 14:15:48 -06:00
|
|
|
$0match path.strip_prefix(root_path) {
|
2020-12-05 08:41:36 -06:00
|
|
|
Ok(rel_path) => println!("{}", rel_path),
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if let Ok(rel_path) = path.strip_prefix(root_path) {
|
|
|
|
println!("{}", rel_path)
|
|
|
|
}
|
|
|
|
}
|
2020-06-09 05:38:47 -05:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
2021-07-02 14:05:10 -05:00
|
|
|
|
2021-08-21 04:00:43 -05:00
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_number_body() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
$0match Ok(()) {
|
|
|
|
Ok(()) => {},
|
|
|
|
Err(_) => 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if let Err(_) = Ok(()) {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-07-02 14:05:10 -05:00
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_exhaustive() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn print_source(def_source: ModuleSource) {
|
|
|
|
match def_so$0urce {
|
|
|
|
ModuleSource::SourceFile(..) => { println!("source file"); }
|
|
|
|
ModuleSource::Module(..) => { println!("module"); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn print_source(def_source: ModuleSource) {
|
|
|
|
if let ModuleSource::SourceFile(..) = def_source { println!("source file"); } else { println!("module"); }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_prefer_name_bind() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match $0Foo(0) {
|
|
|
|
Foo(_) => (),
|
|
|
|
Bar(bar) => println!("bar {}", bar),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if let Bar(bar) = Foo(0) {
|
|
|
|
println!("bar {}", bar)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match $0Foo(0) {
|
|
|
|
Bar(bar) => println!("bar {}", bar),
|
|
|
|
Foo(_) => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if let Bar(bar) = Foo(0) {
|
|
|
|
println!("bar {}", bar)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-08-20 08:20:54 -05:00
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_prefer_nonempty_body() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match $0Ok(0) {
|
|
|
|
Ok(value) => {},
|
|
|
|
Err(err) => eprintln!("{}", err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if let Err(err) = Ok(0) {
|
|
|
|
eprintln!("{}", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match $0Ok(0) {
|
|
|
|
Err(err) => eprintln!("{}", err),
|
|
|
|
Ok(value) => {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if let Err(err) = Ok(0) {
|
|
|
|
eprintln!("{}", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-07-02 14:05:10 -05:00
|
|
|
#[test]
|
|
|
|
fn replace_match_with_if_let_rejects_double_name_bindings() {
|
|
|
|
check_assist_not_applicable(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match $0Foo(0) {
|
|
|
|
Foo(foo) => println!("bar {}", foo),
|
|
|
|
Bar(bar) => println!("bar {}", bar),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2022-01-03 04:20:59 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_replace_match_with_if_let_keeps_unsafe_block() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
$0match *self {
|
|
|
|
VariantData::Struct(..) => true,
|
|
|
|
_ => unsafe { unreachable_unchecked() },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
r#"
|
|
|
|
impl VariantData {
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
if let VariantData::Struct(..) = *self {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
unsafe { unreachable_unchecked() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} "#,
|
|
|
|
)
|
|
|
|
}
|
2022-06-04 18:02:24 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_replace_match_with_if_let_forces_else() {
|
|
|
|
check_assist(
|
|
|
|
replace_match_with_if_let,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
match$0 0 {
|
|
|
|
0 => (),
|
|
|
|
_ => code(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
if let 0 = 0 {
|
|
|
|
()
|
|
|
|
} else {
|
|
|
|
code()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
2019-01-08 05:21:29 -06:00
|
|
|
}
|