Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #14848 - bm-w:fix/highlight-let-else-return, r=Veykril
Fix `preorder_expr` skipping the `else` block of let-else statements Fixes exit/yield points not getting highlighted in such blocks for `highlight_related` (#14813; and possibly other bugs in features that use `preorder_expr`).
bors 2023-05-19
parent e110696 · parent c0519da · commit e8ae2d3
-rw-r--r--crates/ide-db/src/syntax_helpers/node_ext.rs4
-rw-r--r--crates/ide/src/highlight_related.rs43
2 files changed, 46 insertions, 1 deletions
diff --git a/crates/ide-db/src/syntax_helpers/node_ext.rs b/crates/ide-db/src/syntax_helpers/node_ext.rs
index a34dc1b695..22ced69d81 100644
--- a/crates/ide-db/src/syntax_helpers/node_ext.rs
+++ b/crates/ide-db/src/syntax_helpers/node_ext.rs
@@ -52,7 +52,9 @@ pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent<ast::Expr>)
}
};
if let Some(let_stmt) = node.parent().and_then(ast::LetStmt::cast) {
- if Some(node.clone()) != let_stmt.initializer().map(|it| it.syntax().clone()) {
+ if let_stmt.initializer().map(|it| it.syntax() != &node).unwrap_or(true)
+ && let_stmt.let_else().map(|it| it.syntax() != &node).unwrap_or(true)
+ {
// skipping potential const pat expressions in let statements
preorder.skip_subtree();
continue;
diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs
index ff73d5ec9f..7e545491f8 100644
--- a/crates/ide/src/highlight_related.rs
+++ b/crates/ide/src/highlight_related.rs
@@ -693,6 +693,29 @@ pub async$0 fn foo() {
}
#[test]
+ fn test_hl_let_else_yield_points() {
+ check(
+ r#"
+pub async fn foo() {
+ // ^^^^^
+ let x = foo()
+ .await$0
+ // ^^^^^
+ .await;
+ // ^^^^^
+ || { 0.await };
+ let Some(_) = None else {
+ foo().await
+ // ^^^^^
+ };
+ (async { 0.await }).await
+ // ^^^^^
+}
+"#,
+ );
+ }
+
+ #[test]
fn test_hl_yield_nested_fn() {
check(
r#"
@@ -789,6 +812,26 @@ async fn foo() {
}
#[test]
+ fn test_hl_let_else_exit_points() {
+ check(
+ r#"
+ fn$0 foo() -> u32 {
+//^^
+ let Some(bar) = None else {
+ return 0;
+ // ^^^^^^
+ };
+
+ 0?;
+ // ^
+ 0xDEAD_BEEF
+ // ^^^^^^^^^^^
+}
+"#,
+ );
+ }
+
+ #[test]
fn test_hl_prefer_ref_over_tail_exit() {
check(
r#"