@@ -574,11 +574,24 @@ 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_cmp_call ( mut lhs : Vec < ast:: Expr > , mut rhs : Vec < ast:: Expr > ) -> ast:: Expr {
578
- let ( lhs, rhs) = match ( lhs. len ( ) , rhs. len ( ) ) {
579
- ( 1 , 1 ) => ( lhs. pop ( ) . unwrap ( ) , rhs. pop ( ) . unwrap ( ) ) ,
580
- _ => ( make:: expr_tuple ( lhs. into_iter ( ) ) , make:: expr_tuple ( rhs. into_iter ( ) ) ) ,
581
- } ;
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
+ fn gen_partial_cmp_call ( lhs : ast:: Expr , rhs : ast:: Expr ) -> ast:: Expr {
582
595
let rhs = make:: expr_ref ( rhs, false ) ;
583
596
let method = make:: name_ref ( "partial_cmp" ) ;
584
597
make:: expr_method_call ( lhs, method, make:: arg_list ( Some ( rhs) ) )
@@ -594,35 +607,41 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
594
607
ast:: Adt :: Enum ( _) => return None ,
595
608
ast:: Adt :: Struct ( strukt) => match strukt. field_list ( ) {
596
609
Some ( ast:: FieldList :: RecordFieldList ( field_list) ) => {
597
- let mut l_fields = vec ! [ ] ;
598
- let mut r_fields = vec ! [ ] ;
610
+ let mut exprs = vec ! [ ] ;
599
611
for field in field_list. fields ( ) {
600
612
let lhs = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
601
613
let lhs = make:: expr_field ( lhs, & field. name ( ) ?. to_string ( ) ) ;
602
614
let rhs = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
603
615
let rhs = make:: expr_field ( rhs, & field. name ( ) ?. to_string ( ) ) ;
604
- l_fields . push ( lhs) ;
605
- r_fields . push ( rhs ) ;
616
+ let ord = gen_partial_cmp_call ( lhs, rhs ) ;
617
+ exprs . push ( ord ) ;
606
618
}
607
619
608
- let expr = gen_partial_cmp_call ( l_fields, r_fields) ;
609
- make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
620
+ let tail = exprs. pop ( ) ;
621
+ let stmts = exprs
622
+ . into_iter ( )
623
+ . map ( gen_partial_eq_match)
624
+ . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
625
+ make:: block_expr ( stmts. into_iter ( ) , tail) . indent ( ast:: edit:: IndentLevel ( 1 ) )
610
626
}
611
627
612
628
Some ( ast:: FieldList :: TupleFieldList ( field_list) ) => {
613
- let mut l_fields = vec ! [ ] ;
614
- let mut r_fields = vec ! [ ] ;
629
+ let mut exprs = vec ! [ ] ;
615
630
for ( i, _) in field_list. fields ( ) . enumerate ( ) {
616
631
let idx = format ! ( "{}" , i) ;
617
632
let lhs = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
618
633
let lhs = make:: expr_field ( lhs, & idx) ;
619
634
let rhs = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
620
635
let rhs = make:: expr_field ( rhs, & idx) ;
621
- l_fields . push ( lhs) ;
622
- r_fields . push ( rhs ) ;
636
+ let ord = gen_partial_cmp_call ( lhs, rhs ) ;
637
+ exprs . push ( ord ) ;
623
638
}
624
- let expr = gen_partial_cmp_call ( l_fields, r_fields) ;
625
- make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
639
+ let tail = exprs. pop ( ) ;
640
+ let stmts = exprs
641
+ . into_iter ( )
642
+ . map ( gen_partial_eq_match)
643
+ . collect :: < Option < Vec < ast:: Stmt > > > ( ) ?;
644
+ make:: block_expr ( stmts. into_iter ( ) , tail) . indent ( ast:: edit:: IndentLevel ( 1 ) )
626
645
}
627
646
628
647
// No fields in the body means there's nothing to hash.
0 commit comments