@@ -173,6 +173,9 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
173
173
if let Some ( edit) = assign_expr ( file, offset) {
174
174
return Some ( edit) ;
175
175
}
176
+ if let Some ( edit) = assign_to_eq ( file, offset) {
177
+ return Some ( edit) ;
178
+ }
176
179
177
180
return None ;
178
181
@@ -182,13 +185,13 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
182
185
return None ;
183
186
}
184
187
188
+ // Parent must be `ExprStmt` or `StmtList` for `;` to be valid.
185
189
if let Some ( expr_stmt) = ast:: ExprStmt :: cast ( binop. syntax ( ) . parent ( ) ?) {
186
190
if expr_stmt. semicolon_token ( ) . is_some ( ) {
187
191
return None ;
188
192
}
189
193
} else {
190
194
if !ast:: StmtList :: can_cast ( binop. syntax ( ) . parent ( ) ?. kind ( ) ) {
191
- // Parent must be `ExprStmt` or `StmtList` for `;` to be valid.
192
195
return None ;
193
196
}
194
197
}
@@ -205,6 +208,25 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
205
208
Some ( TextEdit :: insert ( offset, ";" . to_string ( ) ) )
206
209
}
207
210
211
+ /// `a =$0 b;` removes the semicolon if an expression is valid in this context.
212
+ fn assign_to_eq ( file : & SourceFile , offset : TextSize ) -> Option < TextEdit > {
213
+ let binop: ast:: BinExpr = find_node_at_offset ( file. syntax ( ) , offset) ?;
214
+ if !matches ! ( binop. op_kind( ) , Some ( ast:: BinaryOp :: CmpOp ( ast:: CmpOp :: Eq { negated: false } ) ) )
215
+ {
216
+ return None ;
217
+ }
218
+
219
+ let expr_stmt = ast:: ExprStmt :: cast ( binop. syntax ( ) . parent ( ) ?) ?;
220
+ let semi = expr_stmt. semicolon_token ( ) ?;
221
+
222
+ if expr_stmt. syntax ( ) . next_sibling ( ) . is_some ( ) {
223
+ // Not the last statement in the list.
224
+ return None ;
225
+ }
226
+
227
+ Some ( TextEdit :: delete ( semi. text_range ( ) ) )
228
+ }
229
+
208
230
fn let_stmt ( file : & SourceFile , offset : TextSize ) -> Option < TextEdit > {
209
231
let let_stmt: ast:: LetStmt = find_node_at_offset ( file. syntax ( ) , offset) ?;
210
232
if let_stmt. semicolon_token ( ) . is_some ( ) {
@@ -424,6 +446,53 @@ fn f() {
424
446
) ;
425
447
}
426
448
449
+ #[ test]
450
+ fn assign_to_eq ( ) {
451
+ type_char (
452
+ '=' ,
453
+ r#"
454
+ fn f(a: u8) {
455
+ a =$0 0;
456
+ }
457
+ "# ,
458
+ r#"
459
+ fn f(a: u8) {
460
+ a == 0
461
+ }
462
+ "# ,
463
+ ) ;
464
+ type_char (
465
+ '=' ,
466
+ r#"
467
+ fn f(a: u8) {
468
+ a $0= 0;
469
+ }
470
+ "# ,
471
+ r#"
472
+ fn f(a: u8) {
473
+ a == 0
474
+ }
475
+ "# ,
476
+ ) ;
477
+ type_char_noop (
478
+ '=' ,
479
+ r#"
480
+ fn f(a: u8) {
481
+ let e = a =$0 0;
482
+ }
483
+ "# ,
484
+ ) ;
485
+ type_char_noop (
486
+ '=' ,
487
+ r#"
488
+ fn f(a: u8) {
489
+ let e = a =$0 0;
490
+ e
491
+ }
492
+ "# ,
493
+ ) ;
494
+ }
495
+
427
496
#[ test]
428
497
fn indents_new_chain_call ( ) {
429
498
type_char (
0 commit comments