@@ -263,6 +263,11 @@ fn replace_usages(
263
263
fn find_assignment_usage ( name_ref : & ast:: NameRef ) -> Option < ast:: Expr > {
264
264
let bin_expr = name_ref. syntax ( ) . ancestors ( ) . find_map ( ast:: BinExpr :: cast) ?;
265
265
266
+ if !bin_expr. lhs ( ) ?. syntax ( ) . descendants ( ) . contains ( name_ref. syntax ( ) ) {
267
+ cov_mark:: hit!( dont_assign_incorrect_ref) ;
268
+ return None ;
269
+ }
270
+
266
271
if let Some ( ast:: BinaryOp :: Assignment { op : None } ) = bin_expr. op_kind ( ) {
267
272
bin_expr. rhs ( )
268
273
} else {
@@ -273,6 +278,11 @@ fn find_assignment_usage(name_ref: &ast::NameRef) -> Option<ast::Expr> {
273
278
fn find_negated_usage ( name_ref : & ast:: NameRef ) -> Option < ( ast:: PrefixExpr , ast:: Expr ) > {
274
279
let prefix_expr = name_ref. syntax ( ) . ancestors ( ) . find_map ( ast:: PrefixExpr :: cast) ?;
275
280
281
+ if !matches ! ( prefix_expr. expr( ) ?, ast:: Expr :: PathExpr ( _) | ast:: Expr :: FieldExpr ( _) ) {
282
+ cov_mark:: hit!( dont_overwrite_expression_inside_negation) ;
283
+ return None ;
284
+ }
285
+
276
286
if let Some ( ast:: UnaryOp :: Not ) = prefix_expr. op_kind ( ) {
277
287
let inner_expr = prefix_expr. expr ( ) ?;
278
288
Some ( ( prefix_expr, inner_expr) )
@@ -285,7 +295,12 @@ fn find_record_expr_usage(name_ref: &ast::NameRef) -> Option<(ast::RecordExprFie
285
295
let record_field = name_ref. syntax ( ) . ancestors ( ) . find_map ( ast:: RecordExprField :: cast) ?;
286
296
let initializer = record_field. expr ( ) ?;
287
297
288
- Some ( ( record_field, initializer) )
298
+ if record_field. field_name ( ) ?. syntax ( ) . descendants ( ) . contains ( name_ref. syntax ( ) ) {
299
+ Some ( ( record_field, initializer) )
300
+ } else {
301
+ cov_mark:: hit!( dont_overwrite_wrong_record_field) ;
302
+ None
303
+ }
289
304
}
290
305
291
306
/// Adds the definition of the new enum before the target node.
@@ -561,6 +576,37 @@ fn main() {
561
576
)
562
577
}
563
578
579
+ #[ test]
580
+ fn local_variable_nested_in_negation ( ) {
581
+ cov_mark:: check!( dont_overwrite_expression_inside_negation) ;
582
+ check_assist (
583
+ bool_to_enum,
584
+ r#"
585
+ fn main() {
586
+ if !"foo".chars().any(|c| {
587
+ let $0foo = true;
588
+ foo
589
+ }) {
590
+ println!("foo");
591
+ }
592
+ }
593
+ "# ,
594
+ r#"
595
+ fn main() {
596
+ if !"foo".chars().any(|c| {
597
+ #[derive(PartialEq, Eq)]
598
+ enum Bool { True, False }
599
+
600
+ let foo = Bool::True;
601
+ foo == Bool::True
602
+ }) {
603
+ println!("foo");
604
+ }
605
+ }
606
+ "# ,
607
+ )
608
+ }
609
+
564
610
#[ test]
565
611
fn local_variable_non_bool ( ) {
566
612
cov_mark:: check!( not_applicable_non_bool_local) ;
@@ -638,6 +684,42 @@ fn main() {
638
684
)
639
685
}
640
686
687
+ #[ test]
688
+ fn field_negated ( ) {
689
+ check_assist (
690
+ bool_to_enum,
691
+ r#"
692
+ struct Foo {
693
+ $0bar: bool,
694
+ }
695
+
696
+ fn main() {
697
+ let foo = Foo { bar: false };
698
+
699
+ if !foo.bar {
700
+ println!("foo");
701
+ }
702
+ }
703
+ "# ,
704
+ r#"
705
+ #[derive(PartialEq, Eq)]
706
+ enum Bool { True, False }
707
+
708
+ struct Foo {
709
+ bar: Bool,
710
+ }
711
+
712
+ fn main() {
713
+ let foo = Foo { bar: Bool::False };
714
+
715
+ if foo.bar == Bool::False {
716
+ println!("foo");
717
+ }
718
+ }
719
+ "# ,
720
+ )
721
+ }
722
+
641
723
#[ test]
642
724
fn field_in_mod_properly_indented ( ) {
643
725
check_assist (
@@ -714,6 +796,88 @@ fn main() {
714
796
)
715
797
}
716
798
799
+ #[ test]
800
+ fn field_assigned_to_another ( ) {
801
+ cov_mark:: check!( dont_assign_incorrect_ref) ;
802
+ check_assist (
803
+ bool_to_enum,
804
+ r#"
805
+ struct Foo {
806
+ $0foo: bool,
807
+ }
808
+
809
+ struct Bar {
810
+ bar: bool,
811
+ }
812
+
813
+ fn main() {
814
+ let foo = Foo { foo: true };
815
+ let mut bar = Bar { bar: true };
816
+
817
+ bar.bar = foo.foo;
818
+ }
819
+ "# ,
820
+ r#"
821
+ #[derive(PartialEq, Eq)]
822
+ enum Bool { True, False }
823
+
824
+ struct Foo {
825
+ foo: Bool,
826
+ }
827
+
828
+ struct Bar {
829
+ bar: bool,
830
+ }
831
+
832
+ fn main() {
833
+ let foo = Foo { foo: Bool::True };
834
+ let mut bar = Bar { bar: true };
835
+
836
+ bar.bar = foo.foo == Bool::True;
837
+ }
838
+ "# ,
839
+ )
840
+ }
841
+
842
+ #[ test]
843
+ fn field_initialized_with_other ( ) {
844
+ cov_mark:: check!( dont_overwrite_wrong_record_field) ;
845
+ check_assist (
846
+ bool_to_enum,
847
+ r#"
848
+ struct Foo {
849
+ $0foo: bool,
850
+ }
851
+
852
+ struct Bar {
853
+ bar: bool,
854
+ }
855
+
856
+ fn main() {
857
+ let foo = Foo { foo: true };
858
+ let bar = Bar { bar: foo.foo };
859
+ }
860
+ "# ,
861
+ r#"
862
+ #[derive(PartialEq, Eq)]
863
+ enum Bool { True, False }
864
+
865
+ struct Foo {
866
+ foo: Bool,
867
+ }
868
+
869
+ struct Bar {
870
+ bar: bool,
871
+ }
872
+
873
+ fn main() {
874
+ let foo = Foo { foo: Bool::True };
875
+ let bar = Bar { bar: foo.foo == Bool::True };
876
+ }
877
+ "# ,
878
+ )
879
+ }
880
+
717
881
#[ test]
718
882
fn field_non_bool ( ) {
719
883
cov_mark:: check!( not_applicable_non_bool_field) ;
0 commit comments