Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_assists/src/handlers/replace_if_let_with_match.rs')
| -rw-r--r-- | crates/ide_assists/src/handlers/replace_if_let_with_match.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs index 7790934792..b594c64c41 100644 --- a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs @@ -1,7 +1,12 @@ use std::iter::{self, successors}; use either::Either; -use ide_db::{defs::NameClass, ty_filter::TryEnum, RootDatabase}; +use ide_db::{ + defs::NameClass, + helpers::node_ext::{is_pattern_cond, single_let}, + ty_filter::TryEnum, + RootDatabase, +}; use syntax::{ ast::{ self, @@ -60,15 +65,22 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) None } }); - let scrutinee_to_be_expr = if_expr.condition()?.expr()?; + let scrutinee_to_be_expr = if_expr.condition()?; + let scrutinee_to_be_expr = match single_let(scrutinee_to_be_expr.clone()) { + Some(cond) => cond.expr()?, + None => scrutinee_to_be_expr, + }; let mut pat_seen = false; let mut cond_bodies = Vec::new(); for if_expr in if_exprs { let cond = if_expr.condition()?; - let expr = cond.expr()?; - let cond = match cond.pat() { - Some(pat) => { + let cond = match single_let(cond.clone()) { + 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. 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; @@ -76,7 +88,9 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) pat_seen = true; Either::Left(pat) } - None => Either::Right(expr), + // Multiple `let`, unsupported. + None if is_pattern_cond(cond.clone()) => return None, + None => Either::Right(cond), }; let body = if_expr.then_branch()?; cond_bodies.push((cond, body)); @@ -217,11 +231,11 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext) } } - let condition = make::condition(scrutinee, Some(if_let_pat)); + let condition = make::expr_let(if_let_pat, scrutinee); 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 if_let_expr = make::expr_if( - condition, + condition.into(), then_block, else_expr.map(make_block_expr).map(ast::ElseBranch::Block), ) @@ -373,6 +387,18 @@ impl VariantData { } #[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 {} +} +"#, + ) + } + + #[test] fn test_if_let_with_match_basic() { check_assist( replace_if_let_with_match, |