about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastiaan Marinus van de Weerd <bvandeweerd@forte.io>2023-05-18 18:30:27 -0400
committerBastiaan Marinus van de Weerd <bvandeweerd@forte.io>2023-05-18 18:30:27 -0400
commit585783604749ea290083ef5769e82c82b14d83c1 (patch)
treee0fd4306713451cf0e92197e31cfc985676767d5
parent54129fa1132afa50afb4159673132c654244571d (diff)
downloadrust-585783604749ea290083ef5769e82c82b14d83c1.tar.gz
rust-585783604749ea290083ef5769e82c82b14d83c1.zip
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`).
-rw-r--r--crates/ide-db/src/syntax_helpers/node_ext.rs5
-rw-r--r--crates/ide/src/highlight_related.rs43
2 files changed, 47 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 a34dc1b6950..85d39d719ea 100644
--- a/crates/ide-db/src/syntax_helpers/node_ext.rs
+++ b/crates/ide-db/src/syntax_helpers/node_ext.rs
@@ -52,7 +52,10 @@ 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()) {
+            let node = Some(node.clone());
+            if node != let_stmt.initializer().map(|it| it.syntax().clone())
+                && node != let_stmt.let_else().map(|it| it.syntax().clone())
+            {
                 // 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 ff73d5ec9fc..7e545491f8e 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#"