Skip to content

Commit 5871b61

Browse files
committed
Auto merge of rust-lang#16333 - roife:fix/issue-14371, r=Veykril
Preserve comments for extracted block expression in 'extract_function' Fix rust-lang#14371 Preserve comments for extracted block expression in 'extract_function'. In the original implementation, `block.statements()` was used to construct a new function, removing the comments within the block. In the updated implementation, we use manual traversal of nodes and `hacky_block_expr` to generate a new block, thereby preserving the comments.
2 parents f31b1fc + d327f30 commit 5871b61

File tree

1 file changed

+49
-3
lines changed

1 file changed

+49
-3
lines changed

crates/ide-assists/src/handlers/extract_function.rs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax::{
2525
edit::{AstNodeEdit, IndentLevel},
2626
AstNode, HasGenericParams,
2727
},
28-
match_ast, ted, SyntaxElement,
28+
match_ast, ted, AstToken, SyntaxElement,
2929
SyntaxKind::{self, COMMENT},
3030
SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T,
3131
};
@@ -1733,8 +1733,23 @@ fn make_body(
17331733
ast::Expr::BlockExpr(block) => {
17341734
// If the extracted expression is itself a block, there is no need to wrap it inside another block.
17351735
let block = block.dedent(old_indent);
1736-
// Recreate the block for formatting consistency with other extracted functions.
1737-
make::block_expr(block.statements(), block.tail_expr())
1736+
let elements = block.stmt_list().map_or_else(
1737+
|| Either::Left(iter::empty()),
1738+
|stmt_list| {
1739+
let elements = stmt_list.syntax().children_with_tokens().filter_map(
1740+
|node_or_token| match &node_or_token {
1741+
syntax::NodeOrToken::Node(node) => {
1742+
ast::Stmt::cast(node.clone()).map(|_| node_or_token)
1743+
}
1744+
syntax::NodeOrToken::Token(token) => {
1745+
ast::Comment::cast(token.clone()).map(|_| node_or_token)
1746+
}
1747+
},
1748+
);
1749+
Either::Right(elements)
1750+
},
1751+
);
1752+
make::hacky_block_expr(elements, block.tail_expr())
17381753
}
17391754
_ => {
17401755
let expr = expr.dedent(old_indent).indent(IndentLevel(1));
@@ -5961,6 +5976,37 @@ fn $0fun_name() -> ControlFlow<()> {
59615976
);
59625977
}
59635978

5979+
#[test]
5980+
fn comments_in_block_expr() {
5981+
check_assist(
5982+
extract_function,
5983+
r#"
5984+
fn f() {
5985+
let c = $0{
5986+
// comment 1
5987+
let a = 2 + 3;
5988+
// comment 2
5989+
let b = 5;
5990+
a + b
5991+
}$0;
5992+
}
5993+
"#,
5994+
r#"
5995+
fn f() {
5996+
let c = fun_name();
5997+
}
5998+
5999+
fn $0fun_name() -> i32 {
6000+
// comment 1
6001+
let a = 2 + 3;
6002+
// comment 2
6003+
let b = 5;
6004+
a + b
6005+
}
6006+
"#,
6007+
);
6008+
}
6009+
59646010
#[test]
59656011
fn in_left_curly_is_not_applicable() {
59666012
cov_mark::check!(extract_function_in_braces_is_not_applicable);

0 commit comments

Comments
 (0)