Skip to content

Commit 9fa9d16

Browse files
Merge #8800
8800: feat: Make "pull assignments up" assist work in more cases r=Jesse-Bakker a=Jesse-Bakker Fixes #8771 Co-authored-by: Jesse Bakker <[email protected]>
2 parents 7751899 + 5f37e34 commit 9fa9d16

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

crates/ide_assists/src/handlers/pull_assignment_up.rs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
6060
return None;
6161
};
6262

63+
if let Some(parent) = tgt.syntax().parent() {
64+
if matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) {
65+
return None;
66+
}
67+
}
68+
6369
acc.add(
6470
AssistId("pull_assignment_up", AssistKind::RefactorExtract),
6571
"Pull assignment up",
@@ -74,7 +80,13 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
7480
let tgt = edit.make_ast_mut(tgt);
7581

7682
for (stmt, rhs) in assignments {
77-
ted::replace(stmt.syntax(), rhs.syntax());
83+
let mut stmt = stmt.syntax().clone();
84+
if let Some(parent) = stmt.parent() {
85+
if ast::ExprStmt::cast(parent.clone()).is_some() {
86+
stmt = parent.clone();
87+
}
88+
}
89+
ted::replace(stmt, rhs.syntax());
7890
}
7991
let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone());
8092
let assign_stmt = make::expr_stmt(assign_expr);
@@ -87,14 +99,15 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
8799
struct AssignmentsCollector<'a> {
88100
sema: &'a hir::Semantics<'a, ide_db::RootDatabase>,
89101
common_lhs: ast::Expr,
90-
assignments: Vec<(ast::ExprStmt, ast::Expr)>,
102+
assignments: Vec<(ast::BinExpr, ast::Expr)>,
91103
}
92104

93105
impl<'a> AssignmentsCollector<'a> {
94106
fn collect_match(&mut self, match_expr: &ast::MatchExpr) -> Option<()> {
95107
for arm in match_expr.match_arm_list()?.arms() {
96108
match arm.expr()? {
97109
ast::Expr::BlockExpr(block) => self.collect_block(&block)?,
110+
ast::Expr::BinExpr(expr) => self.collect_expr(&expr)?,
98111
_ => return None,
99112
}
100113
}
@@ -114,24 +127,30 @@ impl<'a> AssignmentsCollector<'a> {
114127
}
115128
}
116129
fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> {
117-
if block.tail_expr().is_some() {
118-
return None;
119-
}
120-
121-
let last_stmt = block.statements().last()?;
122-
if let ast::Stmt::ExprStmt(stmt) = last_stmt {
123-
if let ast::Expr::BinExpr(expr) = stmt.expr()? {
124-
if expr.op_kind()? == ast::BinOp::Assignment
125-
&& is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs)
126-
{
127-
self.assignments.push((stmt, expr.rhs()?));
128-
return Some(());
129-
}
130+
let last_expr = block.tail_expr().or_else(|| {
131+
if let ast::Stmt::ExprStmt(stmt) = block.statements().last()? {
132+
stmt.expr()
133+
} else {
134+
None
130135
}
136+
})?;
137+
138+
if let ast::Expr::BinExpr(expr) = last_expr {
139+
return self.collect_expr(&expr);
131140
}
132141

133142
None
134143
}
144+
145+
fn collect_expr(&mut self, expr: &ast::BinExpr) -> Option<()> {
146+
if expr.op_kind()? == ast::BinOp::Assignment
147+
&& is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs)
148+
{
149+
self.assignments.push((expr.clone(), expr.rhs()?));
150+
return Some(());
151+
}
152+
None
153+
}
135154
}
136155

137156
fn is_equivalent(
@@ -241,7 +260,6 @@ fn foo() {
241260
}
242261

243262
#[test]
244-
#[ignore]
245263
fn test_pull_assignment_up_assignment_expressions() {
246264
check_assist(
247265
pull_assignment_up,

0 commit comments

Comments
 (0)