about summary refs log tree commit diff
diff options
context:
space:
mode:
authorfeniljain <fkjainco@gmail.com>2022-12-09 18:30:30 +0530
committerfeniljain <fkjainco@gmail.com>2022-12-09 18:30:30 +0530
commitd7183fb5d08cbd021f23c4e0c9a858e0c6e77a4a (patch)
tree65ee41397cf3fbdad8703da9ad02bf3186ba0a60
parent6e8a54d0f68702cf7981c8299357838eb0f4d5b2 (diff)
downloadrust-d7183fb5d08cbd021f23c4e0c9a858e0c6e77a4a.tar.gz
rust-d7183fb5d08cbd021f23c4e0c9a858e0c6e77a4a.zip
fix: make make_body respect comments in extract_function
-rw-r--r--crates/ide-assists/src/handlers/extract_function.rs67
1 files changed, 63 insertions, 4 deletions
diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs
index 0483cfdc646..4ee9d4638bb 100644
--- a/crates/ide-assists/src/handlers/extract_function.rs
+++ b/crates/ide-assists/src/handlers/extract_function.rs
@@ -1799,7 +1799,6 @@ fn make_body(
                 })
                 .collect::<Vec<SyntaxElement>>();
             let tail_expr = tail_expr.map(|expr| expr.dedent(old_indent).indent(body_indent));
-
             make::hacky_block_expr_with_comments(elements, tail_expr)
         }
     };
@@ -1860,9 +1859,29 @@ fn with_default_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::B
 }
 
 fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr {
-    let stmt_tail = block.tail_expr().map(|expr| make::expr_stmt(expr).into());
-    let stmts = block.statements().chain(stmt_tail);
-    make::block_expr(stmts, Some(tail_expr))
+    let stmt_tail_opt: Option<ast::Stmt> =
+        block.tail_expr().map(|expr| make::expr_stmt(expr).into());
+
+    let mut elements: Vec<SyntaxElement> = vec![];
+
+    block.statements().for_each(|stmt| {
+        elements.push(syntax::NodeOrToken::Node(stmt.syntax().clone()));
+    });
+
+    if let Some(stmt_list) = block.stmt_list() {
+        stmt_list.syntax().children_with_tokens().for_each(|node_or_token| {
+            match &node_or_token {
+                syntax::NodeOrToken::Token(_) => elements.push(node_or_token),
+                _ => (),
+            };
+        });
+    }
+
+    if let Some(stmt_tail) = stmt_tail_opt {
+        elements.push(syntax::NodeOrToken::Node(stmt_tail.syntax().clone()));
+    }
+
+    make::hacky_block_expr_with_comments(elements, Some(tail_expr))
 }
 
 fn format_type(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> String {
@@ -5747,4 +5766,44 @@ fn $0fun_name() -> Option<()> {
 "#,
         );
     }
+
+    #[test]
+    fn non_tail_expr_with_comment_of_tail_expr_loop() {
+        check_assist(
+            extract_function,
+            r#"
+pub fn f() {
+    loop {
+        $0// A comment
+        if true {
+            continue;
+        }$0
+        if false {
+            break;
+        }
+    }
+}
+"#,
+            r#"
+pub fn f() {
+    loop {
+        if let ControlFlow::Break(_) = fun_name() {
+            continue;
+        }
+        if false {
+            break;
+        }
+    }
+}
+
+fn $0fun_name() -> ControlFlow<()> {
+    // A comment
+    if true {
+        return ControlFlow::Break(());
+    }
+    ControlFlow::Continue(())
+}
+"#,
+        );
+    }
 }