Skip to content

Commit 63bacc1

Browse files
committed
fix: incorrect highlighting of try blocks with control flow kws
1 parent 9ede853 commit 63bacc1

File tree

2 files changed

+242
-138
lines changed

2 files changed

+242
-138
lines changed

src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,35 @@ pub fn walk_expr(expr: &ast::Expr, cb: &mut dyn FnMut(ast::Expr)) {
3636
})
3737
}
3838

39+
pub fn is_closure_or_blk_with_modif(expr: &ast::Expr) -> bool {
40+
match expr {
41+
ast::Expr::BlockExpr(block_expr) => {
42+
matches!(
43+
block_expr.modifier(),
44+
Some(
45+
ast::BlockModifier::Async(_)
46+
| ast::BlockModifier::Try(_)
47+
| ast::BlockModifier::Const(_)
48+
)
49+
)
50+
}
51+
ast::Expr::ClosureExpr(_) => true,
52+
_ => false,
53+
}
54+
}
55+
3956
/// Preorder walk all the expression's child expressions preserving events.
4057
/// If the callback returns true on an [`WalkEvent::Enter`], the subtree of the expression will be skipped.
4158
/// Note that the subtree may already be skipped due to the context analysis this function does.
4259
pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent<ast::Expr>) -> bool) {
60+
preorder_expr_with_ctx_checker(start, &is_closure_or_blk_with_modif, cb);
61+
}
62+
63+
pub fn preorder_expr_with_ctx_checker(
64+
start: &ast::Expr,
65+
check_ctx: &dyn Fn(&ast::Expr) -> bool,
66+
cb: &mut dyn FnMut(WalkEvent<ast::Expr>) -> bool,
67+
) {
4368
let mut preorder = start.syntax().preorder();
4469
while let Some(event) = preorder.next() {
4570
let node = match event {
@@ -71,20 +96,7 @@ pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent<ast::Expr>)
7196
if ast::GenericArg::can_cast(node.kind()) {
7297
preorder.skip_subtree();
7398
} else if let Some(expr) = ast::Expr::cast(node) {
74-
let is_different_context = match &expr {
75-
ast::Expr::BlockExpr(block_expr) => {
76-
matches!(
77-
block_expr.modifier(),
78-
Some(
79-
ast::BlockModifier::Async(_)
80-
| ast::BlockModifier::Try(_)
81-
| ast::BlockModifier::Const(_)
82-
)
83-
)
84-
}
85-
ast::Expr::ClosureExpr(_) => true,
86-
_ => false,
87-
} && expr.syntax() != start.syntax();
99+
let is_different_context = check_ctx(&expr) && expr.syntax() != start.syntax();
88100
let skip = cb(WalkEvent::Enter(expr));
89101
if skip || is_different_context {
90102
preorder.skip_subtree();
@@ -394,7 +406,7 @@ fn for_each_break_expr(
394406
}
395407
}
396408

397-
fn eq_label_lt(lt1: &Option<ast::Lifetime>, lt2: &Option<ast::Lifetime>) -> bool {
409+
pub fn eq_label_lt(lt1: &Option<ast::Lifetime>, lt2: &Option<ast::Lifetime>) -> bool {
398410
lt1.as_ref().zip(lt2.as_ref()).map_or(false, |(lt, lbl)| lt.text() == lbl.text())
399411
}
400412

0 commit comments

Comments
 (0)