Skip to content

Commit a943034

Browse files
authored
Merge pull request #20702 from A4-Tacks/else-not-before-else
Fix `else` completion before else keyword
2 parents 81ea457 + c976f99 commit a943034

File tree

4 files changed

+133
-3
lines changed

4 files changed

+133
-3
lines changed

crates/ide-completion/src/completions/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub(crate) fn complete_expr_path(
5959
in_block_expr,
6060
in_breakable,
6161
after_if_expr,
62+
before_else_kw,
6263
in_condition,
6364
incomplete_let,
6465
after_incomplete_let,
@@ -386,7 +387,7 @@ pub(crate) fn complete_expr_path(
386387
add_keyword("let", "let $1 = $0;");
387388
}
388389

389-
if after_if_expr || after_incomplete_let {
390+
if !before_else_kw && (after_if_expr || after_incomplete_let) {
390391
add_keyword("else", "else {\n $0\n}");
391392
}
392393

crates/ide-completion/src/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub(crate) struct PathExprCtx<'db> {
144144
pub(crate) in_block_expr: bool,
145145
pub(crate) in_breakable: BreakableKind,
146146
pub(crate) after_if_expr: bool,
147+
pub(crate) before_else_kw: bool,
147148
/// Whether this expression is the direct condition of an if or while expression
148149
pub(crate) in_condition: bool,
149150
pub(crate) incomplete_let: bool,

crates/ide-completion/src/context/analysis.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,11 +1282,12 @@ fn classify_name_ref<'db>(
12821282
let after_incomplete_let = after_incomplete_let(it.clone()).is_some();
12831283
let incomplete_expr_stmt =
12841284
it.parent().and_then(ast::ExprStmt::cast).map(|it| it.semicolon_token().is_none());
1285+
let before_else_kw = before_else_kw(it);
12851286
let incomplete_let = it
12861287
.parent()
12871288
.and_then(ast::LetStmt::cast)
12881289
.is_some_and(|it| it.semicolon_token().is_none())
1289-
|| after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw(it);
1290+
|| after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw;
12901291
let in_value = it.parent().and_then(Either::<ast::LetStmt, ast::ArgList>::cast).is_some();
12911292
let impl_ = fetch_immediate_impl(sema, original_file, expr.syntax());
12921293

@@ -1302,6 +1303,7 @@ fn classify_name_ref<'db>(
13021303
in_block_expr,
13031304
in_breakable: in_loop_body,
13041305
after_if_expr,
1306+
before_else_kw,
13051307
in_condition,
13061308
ref_expr_parent,
13071309
after_amp,

crates/ide-completion/src/tests/expression.rs

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,133 @@ fn foo() { let x = if foo {} $0 else {}; }
16731673
kw async
16741674
kw const
16751675
kw crate::
1676-
kw else
1676+
kw else if
1677+
kw enum
1678+
kw extern
1679+
kw false
1680+
kw fn
1681+
kw for
1682+
kw if
1683+
kw if let
1684+
kw impl
1685+
kw impl for
1686+
kw let
1687+
kw letm
1688+
kw loop
1689+
kw match
1690+
kw mod
1691+
kw return
1692+
kw self::
1693+
kw static
1694+
kw struct
1695+
kw trait
1696+
kw true
1697+
kw type
1698+
kw union
1699+
kw unsafe
1700+
kw use
1701+
kw while
1702+
kw while let
1703+
sn macro_rules
1704+
sn pd
1705+
sn ppd
1706+
"#]],
1707+
);
1708+
check(
1709+
r#"
1710+
fn foo() { let x = if foo {} $0 else if true {}; }
1711+
"#,
1712+
expect![[r#"
1713+
fn foo fn()
1714+
bt u32 u32
1715+
kw async
1716+
kw const
1717+
kw crate::
1718+
kw else if
1719+
kw enum
1720+
kw extern
1721+
kw false
1722+
kw fn
1723+
kw for
1724+
kw if
1725+
kw if let
1726+
kw impl
1727+
kw impl for
1728+
kw let
1729+
kw letm
1730+
kw loop
1731+
kw match
1732+
kw mod
1733+
kw return
1734+
kw self::
1735+
kw static
1736+
kw struct
1737+
kw trait
1738+
kw true
1739+
kw type
1740+
kw union
1741+
kw unsafe
1742+
kw use
1743+
kw while
1744+
kw while let
1745+
sn macro_rules
1746+
sn pd
1747+
sn ppd
1748+
"#]],
1749+
);
1750+
check(
1751+
r#"
1752+
fn foo() { let x = if foo {} el$0 else if true {} else {}; }
1753+
"#,
1754+
expect![[r#"
1755+
fn foo() fn()
1756+
lc x ()
1757+
bt u32 u32
1758+
kw async
1759+
kw const
1760+
kw crate::
1761+
kw else if
1762+
kw enum
1763+
kw extern
1764+
kw false
1765+
kw fn
1766+
kw for
1767+
kw if
1768+
kw if let
1769+
kw impl
1770+
kw impl for
1771+
kw let
1772+
kw letm
1773+
kw loop
1774+
kw match
1775+
kw mod
1776+
kw return
1777+
kw self::
1778+
kw static
1779+
kw struct
1780+
kw trait
1781+
kw true
1782+
kw type
1783+
kw union
1784+
kw unsafe
1785+
kw use
1786+
kw while
1787+
kw while let
1788+
sn macro_rules
1789+
sn pd
1790+
sn ppd
1791+
"#]],
1792+
);
1793+
check(
1794+
r#"
1795+
fn foo() { let x = if foo {} $0 else if true {} else {}; }
1796+
"#,
1797+
expect![[r#"
1798+
fn foo fn()
1799+
bt u32 u32
1800+
kw async
1801+
kw const
1802+
kw crate::
16771803
kw else if
16781804
kw enum
16791805
kw extern

0 commit comments

Comments
 (0)