@@ -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
8799struct 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
93105impl < ' 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
137156fn 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