Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20702 from A4-Tacks/else-not-before-else
Fix `else` completion before else keyword
Shoyu Vanilla (Flint) 7 months ago
parent 81ea457 · parent c976f99 · commit a943034
-rw-r--r--crates/ide-completion/src/completions/expr.rs3
-rw-r--r--crates/ide-completion/src/context.rs1
-rw-r--r--crates/ide-completion/src/context/analysis.rs4
-rw-r--r--crates/ide-completion/src/tests/expression.rs128
4 files changed, 133 insertions, 3 deletions
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index a7df0ab386..080875e016 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -59,6 +59,7 @@ pub(crate) fn complete_expr_path(
in_block_expr,
in_breakable,
after_if_expr,
+ before_else_kw,
in_condition,
incomplete_let,
after_incomplete_let,
@@ -386,7 +387,7 @@ pub(crate) fn complete_expr_path(
add_keyword("let", "let $1 = $0;");
}
- if after_if_expr || after_incomplete_let {
+ if !before_else_kw && (after_if_expr || after_incomplete_let) {
add_keyword("else", "else {\n $0\n}");
}
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index 007475688d..9deaaf6631 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -144,6 +144,7 @@ pub(crate) struct PathExprCtx<'db> {
pub(crate) in_block_expr: bool,
pub(crate) in_breakable: BreakableKind,
pub(crate) after_if_expr: bool,
+ pub(crate) before_else_kw: bool,
/// Whether this expression is the direct condition of an if or while expression
pub(crate) in_condition: bool,
pub(crate) incomplete_let: bool,
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index b33a547dee..7b78a9700e 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -1282,11 +1282,12 @@ fn classify_name_ref<'db>(
let after_incomplete_let = after_incomplete_let(it.clone()).is_some();
let incomplete_expr_stmt =
it.parent().and_then(ast::ExprStmt::cast).map(|it| it.semicolon_token().is_none());
+ let before_else_kw = before_else_kw(it);
let incomplete_let = it
.parent()
.and_then(ast::LetStmt::cast)
.is_some_and(|it| it.semicolon_token().is_none())
- || after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw(it);
+ || after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw;
let in_value = it.parent().and_then(Either::<ast::LetStmt, ast::ArgList>::cast).is_some();
let impl_ = fetch_immediate_impl(sema, original_file, expr.syntax());
@@ -1302,6 +1303,7 @@ fn classify_name_ref<'db>(
in_block_expr,
in_breakable: in_loop_body,
after_if_expr,
+ before_else_kw,
in_condition,
ref_expr_parent,
after_amp,
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
index 5cc72ef845..c420953036 100644
--- a/crates/ide-completion/src/tests/expression.rs
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -1673,7 +1673,133 @@ fn foo() { let x = if foo {} $0 else {}; }
kw async
kw const
kw crate::
- kw else
+ kw else if
+ kw enum
+ kw extern
+ kw false
+ kw fn
+ kw for
+ kw if
+ kw if let
+ kw impl
+ kw impl for
+ kw let
+ kw letm
+ kw loop
+ kw match
+ kw mod
+ kw return
+ kw self::
+ kw static
+ kw struct
+ kw trait
+ kw true
+ kw type
+ kw union
+ kw unsafe
+ kw use
+ kw while
+ kw while let
+ sn macro_rules
+ sn pd
+ sn ppd
+ "#]],
+ );
+ check(
+ r#"
+fn foo() { let x = if foo {} $0 else if true {}; }
+"#,
+ expect![[r#"
+ fn foo fn()
+ bt u32 u32
+ kw async
+ kw const
+ kw crate::
+ kw else if
+ kw enum
+ kw extern
+ kw false
+ kw fn
+ kw for
+ kw if
+ kw if let
+ kw impl
+ kw impl for
+ kw let
+ kw letm
+ kw loop
+ kw match
+ kw mod
+ kw return
+ kw self::
+ kw static
+ kw struct
+ kw trait
+ kw true
+ kw type
+ kw union
+ kw unsafe
+ kw use
+ kw while
+ kw while let
+ sn macro_rules
+ sn pd
+ sn ppd
+ "#]],
+ );
+ check(
+ r#"
+fn foo() { let x = if foo {} el$0 else if true {} else {}; }
+"#,
+ expect![[r#"
+ fn foo() fn()
+ lc x ()
+ bt u32 u32
+ kw async
+ kw const
+ kw crate::
+ kw else if
+ kw enum
+ kw extern
+ kw false
+ kw fn
+ kw for
+ kw if
+ kw if let
+ kw impl
+ kw impl for
+ kw let
+ kw letm
+ kw loop
+ kw match
+ kw mod
+ kw return
+ kw self::
+ kw static
+ kw struct
+ kw trait
+ kw true
+ kw type
+ kw union
+ kw unsafe
+ kw use
+ kw while
+ kw while let
+ sn macro_rules
+ sn pd
+ sn ppd
+ "#]],
+ );
+ check(
+ r#"
+fn foo() { let x = if foo {} $0 else if true {} else {}; }
+"#,
+ expect![[r#"
+ fn foo fn()
+ bt u32 u32
+ kw async
+ kw const
+ kw crate::
kw else if
kw enum
kw extern