about summary refs log tree commit diff
diff options
context:
space:
mode:
authorfprasx <felix725@gmail.com>2022-08-03 15:51:30 -0400
committerfprasx <felix725@gmail.com>2022-08-03 15:59:17 -0400
commitd513b4c8baaf2c71e5f13ce790bd0083ccb81a64 (patch)
tree40fbf0de1946481452b814c7743bc35dfcf63104
parent5cb3e7a41b89b5612cefe9c688f0ffdff18d4df4 (diff)
downloadrust-d513b4c8baaf2c71e5f13ce790bd0083ccb81a64.tar.gz
rust-d513b4c8baaf2c71e5f13ce790bd0083ccb81a64.zip
Added fixup for for loops w/ missing parts
-rw-r--r--crates/hir-expand/src/fixup.rs78
1 files changed, 77 insertions, 1 deletions
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index c875b23b2dc..ade28f27bf1 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -193,7 +193,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                     }
                 },
                 // FIXME: foo::
-                // FIXME: for, match etc.
                 ast::MatchExpr(it) => {
                     if it.expr().is_none() {
                         let match_token = match it.match_token() {
@@ -257,6 +256,42 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                         ]);
                     }
                 },
+                ast::ForExpr(it) => {
+                    let for_token = match it.for_token() {
+                        Some(token) => token,
+                        None => continue
+                    };
+
+                    let [pat, in_token, iter] = [
+                        (SyntaxKind::UNDERSCORE, "_"), 
+                        (SyntaxKind::IN_KW, "in"), 
+                        (SyntaxKind::IDENT, "__ra_fixup")
+                    ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
+
+                    if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
+                        append.insert(for_token.into(), vec![pat, in_token, iter]);
+                    } 
+
+                    // Tricky: add logic to add in just a pattern or iterable if not all
+                    // the pieces are missing
+
+                    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,
+                            },
+                        ]);
+                    }
+                },
                 _ => (),
             }
         }
@@ -349,6 +384,47 @@ mod tests {
         assert_eq!(tt.to_string(), original_as_tt.to_string());
     }
 
+    #[test]
+    fn for_no_iter_no_body() {
+        check(
+            r#"
+fn foo() {
+    for
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_iter() {
+        check(
+            r#"
+fn foo() {
+    for {}
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_body() {
+        check(
+            r#"
+fn foo() {
+    for bar in qux
+}
+"#,
+            expect![[r#"
+fn foo () {for bar in qux {}}
+"#]],
+        )
+    }
 
     #[test]
     fn match_no_expr_no_arms() {