about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-02 14:08:56 +0000
committerbors <bors@rust-lang.org>2022-08-02 14:08:56 +0000
commit113f1dbc9102d8eb693fefc1f369868c2a497910 (patch)
treee2b04d05171ed6481389567f032b461d262f2b0e
parentc6c0ac26456093b71837e20b0ff51655e0c230f7 (diff)
parentc16e4f260fb6b915767d18a59ab395cb46d82449 (diff)
downloadrust-113f1dbc9102d8eb693fefc1f369868c2a497910.tar.gz
rust-113f1dbc9102d8eb693fefc1f369868c2a497910.zip
Auto merge of #12880 - palango:while-fixup, r=Veykril
Add syntax fixup for while loops

Part of https://github.com/rust-lang/rust-analyzer/issues/12777

This is a first iteration to gather some feedback. In particular I'm not sure if the curly braces should be added here, but I couldn't get the test to work without them. Any hints welcome!
-rw-r--r--crates/hir-expand/src/fixup.rs110
1 files changed, 108 insertions, 2 deletions
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index 9999790fae7..e46f43a878f 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -5,7 +5,7 @@ use std::mem;
 use mbe::{SyntheticToken, SyntheticTokenId, TokenMap};
 use rustc_hash::FxHashMap;
 use syntax::{
-    ast::{self, AstNode},
+    ast::{self, AstNode, HasLoopBody},
     match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
 };
 use tt::Subtree;
@@ -142,8 +142,59 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                         ]);
                     }
                 },
+                ast::WhileExpr(it) => {
+                    if it.condition().is_none() {
+                        // insert placeholder token after the while token
+                        let while_token = match it.while_token() {
+                            Some(t) => t,
+                            None => continue,
+                        };
+                        append.insert(while_token.into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::IDENT,
+                                text: "__ra_fixup".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                    if it.loop_body().is_none() {
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
+                ast::LoopExpr(it) => {
+                    if it.loop_body().is_none() {
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
                 // FIXME: foo::
-                // FIXME: for, loop, match etc.
+                // FIXME: for, match etc.
                 _ => (),
             }
         }
@@ -379,4 +430,59 @@ fn foo () {if {} {}}
 "#]],
         )
     }
+
+    #[test]
+    fn fixup_while_1() {
+        check(
+            r#"
+fn foo() {
+    while
+}
+"#,
+            expect![[r#"
+fn foo () {while __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn fixup_while_2() {
+        check(
+            r#"
+fn foo() {
+    while foo
+}
+"#,
+            expect![[r#"
+fn foo () {while foo {}}
+"#]],
+        )
+    }
+    #[test]
+    fn fixup_while_3() {
+        check(
+            r#"
+fn foo() {
+    while {}
+}
+"#,
+            expect![[r#"
+fn foo () {while __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn fixup_loop() {
+        check(
+            r#"
+fn foo() {
+    loop
+}
+"#,
+            expect![[r#"
+fn foo () {loop {}}
+"#]],
+        )
+    }
 }