@@ -574,27 +574,18 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
574
574
}
575
575
576
576
fn gen_partial_ord ( adt : & ast:: Adt , func : & ast:: Fn ) -> Option < ( ) > {
577
- fn gen_partial_eq_match ( match_target : ast:: Expr ) -> Option < ast:: Stmt > {
578
- let mut arms = vec ! [ ] ;
579
-
580
- let variant_name =
581
- make:: path_pat ( make:: ext:: path_from_idents ( [ "core" , "cmp" , "Ordering" , "Eq" ] ) ?) ;
582
- let lhs = make:: tuple_struct_pat ( make:: ext:: path_from_idents ( [ "Some" ] ) ?, [ variant_name] ) ;
583
- arms. push ( make:: match_arm ( Some ( lhs. into ( ) ) , None , make:: expr_empty_block ( ) ) ) ;
584
-
585
- arms. push ( make:: match_arm (
586
- [ make:: ident_pat ( false , false , make:: name ( "ord" ) ) . into ( ) ] ,
587
- None ,
588
- make:: expr_return ( Some ( make:: expr_path ( make:: ext:: ident_path ( "ord" ) ) ) ) ,
589
- ) ) ;
590
- let list = make:: match_arm_list ( arms) . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
591
- Some ( make:: expr_stmt ( make:: expr_match ( match_target, list) ) . into ( ) )
592
- }
593
-
594
577
fn gen_partial_cmp_call ( lhs : ast:: Expr , rhs : ast:: Expr ) -> ast:: Expr {
595
578
let method = make:: name_ref ( "partial_cmp" ) ;
596
579
make:: expr_method_call ( lhs, method, make:: arg_list ( Some ( rhs) ) )
597
580
}
581
+ fn gen_partial_cmp_call2 ( mut lhs : Vec < ast:: Expr > , mut rhs : Vec < ast:: Expr > ) -> ast:: Expr {
582
+ let ( lhs, rhs) = match ( lhs. len ( ) , rhs. len ( ) ) {
583
+ ( 1 , 1 ) => ( lhs. pop ( ) . unwrap ( ) , rhs. pop ( ) . unwrap ( ) ) ,
584
+ _ => ( make:: expr_tuple ( lhs. into_iter ( ) ) , make:: expr_tuple ( rhs. into_iter ( ) ) ) ,
585
+ } ;
586
+ let method = make:: name_ref ( "partial_cmp" ) ;
587
+ make:: expr_method_call ( lhs, method, make:: arg_list ( Some ( rhs) ) )
588
+ }
598
589
599
590
fn gen_record_pat_field ( field_name : & str , pat_name : & str ) -> ast:: RecordPatField {
600
591
let pat = make:: ext:: simple_ident_pat ( make:: name ( & pat_name) ) ;
@@ -637,80 +628,78 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
637
628
match variant. field_list ( ) {
638
629
// => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
639
630
Some ( ast:: FieldList :: RecordFieldList ( list) ) => {
640
- let mut exprs = vec ! [ ] ;
631
+ let mut l_pat_fields = vec ! [ ] ;
632
+ let mut r_pat_fields = vec ! [ ] ;
641
633
let mut l_fields = vec ! [ ] ;
642
634
let mut r_fields = vec ! [ ] ;
643
635
644
636
for field in list. fields ( ) {
645
637
let field_name = field. name ( ) ?. to_string ( ) ;
646
638
647
639
let l_name = & format ! ( "l_{}" , field_name) ;
648
- l_fields . push ( gen_record_pat_field ( & field_name, & l_name) ) ;
640
+ l_pat_fields . push ( gen_record_pat_field ( & field_name, & l_name) ) ;
649
641
650
642
let r_name = & format ! ( "r_{}" , field_name) ;
651
- r_fields . push ( gen_record_pat_field ( & field_name, & r_name) ) ;
643
+ r_pat_fields . push ( gen_record_pat_field ( & field_name, & r_name) ) ;
652
644
653
645
let lhs = make:: expr_path ( make:: ext:: ident_path ( l_name) ) ;
654
646
let rhs = make:: expr_path ( make:: ext:: ident_path ( r_name) ) ;
655
- let ord = gen_partial_cmp_call ( lhs, rhs ) ;
656
- exprs . push ( ord ) ;
647
+ l_fields . push ( lhs) ;
648
+ r_fields . push ( rhs ) ;
657
649
}
658
650
659
- let left = gen_record_pat ( gen_variant_path ( & variant) ?, l_fields ) ;
660
- let right = gen_record_pat ( gen_variant_path ( & variant) ?, r_fields ) ;
661
- let tuple = make:: tuple_pat ( vec ! [ left . into( ) , right . into( ) ] ) ;
651
+ let left_pat = gen_record_pat ( gen_variant_path ( & variant) ?, l_pat_fields ) ;
652
+ let right_pat = gen_record_pat ( gen_variant_path ( & variant) ?, r_pat_fields ) ;
653
+ let tuple_pat = make:: tuple_pat ( vec ! [ left_pat . into( ) , right_pat . into( ) ] ) ;
662
654
663
- if let Some ( tail) = exprs. pop ( ) {
664
- let stmts = exprs
665
- . into_iter ( )
666
- . map ( gen_partial_eq_match)
667
- . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
668
- let expr = match stmts. len ( ) {
669
- 0 => tail,
670
- _ => make:: block_expr ( stmts. into_iter ( ) , Some ( tail) )
655
+ let len = l_fields. len ( ) ;
656
+ if len != 0 {
657
+ let mut expr = gen_partial_cmp_call2 ( l_fields, r_fields) ;
658
+ if len >= 2 {
659
+ expr = make:: block_expr ( None , Some ( expr) )
671
660
. indent ( ast:: edit:: IndentLevel ( 1 ) )
672
- . into ( ) ,
673
- } ;
674
- arms. push ( make:: match_arm ( Some ( tuple . into ( ) ) , None , expr. into ( ) ) ) ;
661
+ . into ( ) ;
662
+ }
663
+ arms. push ( make:: match_arm ( Some ( tuple_pat . into ( ) ) , None , expr) ) ;
675
664
}
676
665
}
677
666
678
667
Some ( ast:: FieldList :: TupleFieldList ( list) ) => {
679
- let mut exprs = vec ! [ ] ;
668
+ let mut l_pat_fields = vec ! [ ] ;
669
+ let mut r_pat_fields = vec ! [ ] ;
680
670
let mut l_fields = vec ! [ ] ;
681
671
let mut r_fields = vec ! [ ] ;
682
672
683
673
for ( i, _) in list. fields ( ) . enumerate ( ) {
684
674
let field_name = format ! ( "{}" , i) ;
685
675
686
676
let l_name = format ! ( "l{}" , field_name) ;
687
- l_fields . push ( gen_tuple_field ( & l_name) ) ;
677
+ l_pat_fields . push ( gen_tuple_field ( & l_name) ) ;
688
678
689
679
let r_name = format ! ( "r{}" , field_name) ;
690
- r_fields . push ( gen_tuple_field ( & r_name) ) ;
680
+ r_pat_fields . push ( gen_tuple_field ( & r_name) ) ;
691
681
692
682
let lhs = make:: expr_path ( make:: ext:: ident_path ( & l_name) ) ;
693
683
let rhs = make:: expr_path ( make:: ext:: ident_path ( & r_name) ) ;
694
- let ord = gen_partial_cmp_call ( lhs, rhs ) ;
695
- exprs . push ( ord ) ;
684
+ l_fields . push ( lhs) ;
685
+ r_fields . push ( rhs ) ;
696
686
}
697
687
698
- let left = make:: tuple_struct_pat ( gen_variant_path ( & variant) ?, l_fields) ;
699
- let right = make:: tuple_struct_pat ( gen_variant_path ( & variant) ?, r_fields) ;
700
- let tuple = make:: tuple_pat ( vec ! [ left. into( ) , right. into( ) ] ) ;
701
-
702
- if let Some ( tail) = exprs. pop ( ) {
703
- let stmts = exprs
704
- . into_iter ( )
705
- . map ( gen_partial_eq_match)
706
- . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
707
- let expr = match stmts. len ( ) {
708
- 0 => tail,
709
- _ => make:: block_expr ( stmts. into_iter ( ) , Some ( tail) )
688
+ let left_pat =
689
+ make:: tuple_struct_pat ( gen_variant_path ( & variant) ?, l_pat_fields) ;
690
+ let right_pat =
691
+ make:: tuple_struct_pat ( gen_variant_path ( & variant) ?, r_pat_fields) ;
692
+ let tuple_pat = make:: tuple_pat ( vec ! [ left_pat. into( ) , right_pat. into( ) ] ) ;
693
+
694
+ let len = l_fields. len ( ) ;
695
+ if len != 0 {
696
+ let mut expr = gen_partial_cmp_call2 ( l_fields, r_fields) ;
697
+ if len >= 2 {
698
+ expr = make:: block_expr ( None , Some ( expr) )
710
699
. indent ( ast:: edit:: IndentLevel ( 1 ) )
711
- . into ( ) ,
712
- } ;
713
- arms. push ( make:: match_arm ( Some ( tuple . into ( ) ) , None , expr. into ( ) ) ) ;
700
+ . into ( ) ;
701
+ }
702
+ arms. push ( make:: match_arm ( Some ( tuple_pat . into ( ) ) , None , expr) ) ;
714
703
}
715
704
}
716
705
None => continue ,
@@ -735,41 +724,35 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
735
724
}
736
725
ast:: Adt :: Struct ( strukt) => match strukt. field_list ( ) {
737
726
Some ( ast:: FieldList :: RecordFieldList ( field_list) ) => {
738
- let mut exprs = vec ! [ ] ;
727
+ let mut l_fields = vec ! [ ] ;
728
+ let mut r_fields = vec ! [ ] ;
739
729
for field in field_list. fields ( ) {
740
730
let lhs = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
741
731
let lhs = make:: expr_field ( lhs, & field. name ( ) ?. to_string ( ) ) ;
742
732
let rhs = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
743
733
let rhs = make:: expr_field ( rhs, & field. name ( ) ?. to_string ( ) ) ;
744
- let ord = gen_partial_cmp_call ( lhs, rhs ) ;
745
- exprs . push ( ord ) ;
734
+ l_fields . push ( lhs) ;
735
+ r_fields . push ( rhs ) ;
746
736
}
747
737
748
- let tail = exprs. pop ( ) ;
749
- let stmts = exprs
750
- . into_iter ( )
751
- . map ( gen_partial_eq_match)
752
- . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
753
- make:: block_expr ( stmts. into_iter ( ) , tail) . indent ( ast:: edit:: IndentLevel ( 1 ) )
738
+ let expr = gen_partial_cmp_call2 ( l_fields, r_fields) ;
739
+ make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
754
740
}
755
741
756
742
Some ( ast:: FieldList :: TupleFieldList ( field_list) ) => {
757
- let mut exprs = vec ! [ ] ;
743
+ let mut l_fields = vec ! [ ] ;
744
+ let mut r_fields = vec ! [ ] ;
758
745
for ( i, _) in field_list. fields ( ) . enumerate ( ) {
759
746
let idx = format ! ( "{}" , i) ;
760
747
let lhs = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
761
748
let lhs = make:: expr_field ( lhs, & idx) ;
762
749
let rhs = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
763
750
let rhs = make:: expr_field ( rhs, & idx) ;
764
- let ord = gen_partial_cmp_call ( lhs, rhs ) ;
765
- exprs . push ( ord ) ;
751
+ l_fields . push ( lhs) ;
752
+ r_fields . push ( rhs ) ;
766
753
}
767
- let tail = exprs. pop ( ) ;
768
- let stmts = exprs
769
- . into_iter ( )
770
- . map ( gen_partial_eq_match)
771
- . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
772
- make:: block_expr ( stmts. into_iter ( ) , tail) . indent ( ast:: edit:: IndentLevel ( 1 ) )
754
+ let expr = gen_partial_cmp_call2 ( l_fields, r_fields) ;
755
+ make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
773
756
}
774
757
775
758
// No fields in the body means there's nothing to hash.
0 commit comments