diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 2133291b1de1..a84927f6e2c0 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -61,6 +61,7 @@ pub(crate) fn complete_expr_path( after_if_expr, in_condition, incomplete_let, + in_value, ref ref_expr_parent, after_amp, ref is_func_update, @@ -361,10 +362,16 @@ pub(crate) fn complete_expr_path( add_keyword("loop", "loop {\n $0\n}"); if in_match_guard { add_keyword("if", "if $0"); + } else if in_value { + add_keyword("if", "if $1 {\n $2\n} else {\n $0\n}"); } else { add_keyword("if", "if $1 {\n $0\n}"); } - add_keyword("if let", "if let $1 = $2 {\n $0\n}"); + if in_value { + add_keyword("if let", "if let $1 = $2 {\n $3\n} else {\n $0\n}"); + } else { + add_keyword("if let", "if let $1 = $2 {\n $0\n}"); + } add_keyword("for", "for $1 in $2 {\n $0\n}"); add_keyword("true", "true"); add_keyword("false", "false"); diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs index 64bb1fce6ba0..aea4e119f207 100644 --- a/crates/ide-completion/src/completions/keyword.rs +++ b/crates/ide-completion/src/completions/keyword.rs @@ -238,6 +238,8 @@ fn main() { r#" fn main() { let x = if $1 { + $2 +} else { $0 }; let y = 92; @@ -335,6 +337,120 @@ fn main() { ) } + #[test] + fn if_completion_in_parameter() { + check_edit( + "if", + r" +fn main() { + foo($0) +} +", + r" +fn main() { + foo(if $1 { + $2 +} else { + $0 +}) +} +", + ); + + check_edit( + "if", + r" +fn main() { + foo($0, 2) +} +", + r" +fn main() { + foo(if $1 { + $2 +} else { + $0 +}, 2) +} +", + ); + + check_edit( + "if", + r" +fn main() { + foo(2, $0) +} +", + r" +fn main() { + foo(2, if $1 { + $2 +} else { + $0 +}) +} +", + ); + + check_edit( + "if let", + r" +fn main() { + foo(2, $0) +} +", + r" +fn main() { + foo(2, if let $1 = $2 { + $3 +} else { + $0 +}) +} +", + ); + } + + #[test] + fn if_completion_in_let_statement() { + check_edit( + "if", + r" +fn main() { + let x = $0; +} +", + r" +fn main() { + let x = if $1 { + $2 +} else { + $0 +}; +} +", + ); + + check_edit( + "if let", + r" +fn main() { + let x = $0; +} +", + r" +fn main() { + let x = if let $1 = $2 { + $3 +} else { + $0 +}; +} +", + ); + } + #[test] fn completes_let_in_block() { check_edit( diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index cfd7f80d40b3..bb6b13b8fb96 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -147,6 +147,7 @@ pub(crate) struct PathExprCtx<'db> { /// Whether this expression is the direct condition of an if or while expression pub(crate) in_condition: bool, pub(crate) incomplete_let: bool, + pub(crate) in_value: bool, pub(crate) ref_expr_parent: Option, pub(crate) after_amp: bool, /// The surrounding RecordExpression we are completing a functional update diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index ea5fb39338b2..59077237e753 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -1245,6 +1245,7 @@ fn classify_name_ref<'db>( .parent() .and_then(ast::LetStmt::cast) .is_some_and(|it| it.semicolon_token().is_none()); + let in_value = it.parent().and_then(Either::::cast).is_some(); let impl_ = fetch_immediate_impl(sema, original_file, expr.syntax()); let in_match_guard = match it.parent().and_then(ast::MatchArm::cast) { @@ -1265,6 +1266,7 @@ fn classify_name_ref<'db>( is_func_update, innermost_ret_ty, self_param, + in_value, incomplete_let, impl_, in_match_guard,