@@ -489,20 +489,36 @@ fn expand_deriving_eq_struct_def(cx: ext_ctxt,
489
489
// Create the methods.
490
490
let eq_ident = cx. ident_of ( ~"eq") ;
491
491
let ne_ident = cx. ident_of ( ~"ne") ;
492
- let eq_method = expand_deriving_eq_struct_method ( cx,
493
- span,
494
- struct_def,
495
- eq_ident,
496
- type_ident,
497
- ty_params,
498
- Conjunction ) ;
499
- let ne_method = expand_deriving_eq_struct_method ( cx,
500
- span,
501
- struct_def,
502
- ne_ident,
503
- type_ident,
504
- ty_params,
505
- Disjunction ) ;
492
+
493
+ let is_struct_tuple =
494
+ struct_def. fields . len ( ) > 0 && struct_def. fields . all ( |f| {
495
+ match f. node . kind {
496
+ named_field( * ) => false ,
497
+ unnamed_field => true
498
+ }
499
+ } ) ;
500
+
501
+ let derive_struct_fn = if is_struct_tuple {
502
+ expand_deriving_eq_struct_tuple_method
503
+ } else {
504
+ expand_deriving_eq_struct_method
505
+ } ;
506
+
507
+
508
+ let eq_method = derive_struct_fn ( cx,
509
+ span,
510
+ struct_def,
511
+ eq_ident,
512
+ type_ident,
513
+ ty_params,
514
+ Conjunction ) ;
515
+ let ne_method = derive_struct_fn ( cx,
516
+ span,
517
+ struct_def,
518
+ ne_ident,
519
+ type_ident,
520
+ ty_params,
521
+ Disjunction ) ;
506
522
507
523
// Create the implementation.
508
524
return create_derived_eq_impl ( cx,
@@ -811,6 +827,65 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt,
811
827
self_match_expr) ;
812
828
}
813
829
830
+ fn expand_deriving_eq_struct_tuple_method ( cx : ext_ctxt ,
831
+ span : span ,
832
+ struct_def : & struct_def ,
833
+ method_ident : ident ,
834
+ type_ident : ident ,
835
+ ty_params : & [ ty_param ] ,
836
+ junction : Junction )
837
+ -> @method {
838
+ let self_str = ~"self ";
839
+ let other_str = ~"__other";
840
+ let type_path = build:: mk_raw_path ( span, ~[ type_ident] ) ;
841
+ let fields = struct_def. fields ;
842
+
843
+ // Create comparison expression, comparing each of the fields
844
+ let mut match_body = None ;
845
+ for fields. eachi |i, _| {
846
+ let other_field_ident = cx. ident_of ( other_str + i. to_str ( ) ) ;
847
+ let other_field = build:: mk_path ( cx, span, ~[ other_field_ident ] ) ;
848
+
849
+ let self_field_ident = cx. ident_of ( self_str + i. to_str ( ) ) ;
850
+ let self_field = build:: mk_path ( cx, span, ~[ self_field_ident ] ) ;
851
+
852
+ call_substructure_eq_method ( cx, span, self_field, other_field,
853
+ method_ident, junction, & mut match_body) ;
854
+ }
855
+ let match_body = finish_eq_chain_expr ( cx, span, match_body, junction) ;
856
+
857
+ // Create arm for the '__other' match, containing the comparison expr
858
+ let other_subpats = create_subpatterns ( cx, span, other_str, fields. len ( ) ) ;
859
+ let other_arm = ast:: arm {
860
+ pats : ~[ build:: mk_pat_enum ( cx, span, type_path, other_subpats) ] ,
861
+ guard : None ,
862
+ body : build:: mk_simple_block ( cx, span, match_body) ,
863
+ } ;
864
+
865
+ // Create the match on '__other'
866
+ let other_expr = build:: mk_path ( cx, span, ~[ cx. ident_of ( other_str) ] ) ;
867
+ let other_expr = build:: mk_unary ( cx, span, deref, other_expr) ;
868
+ let other_match_expr = expr_match ( other_expr, ~[ other_arm] ) ;
869
+ let other_match_expr = build:: mk_expr ( cx, span, other_match_expr) ;
870
+
871
+ // Create arm for the 'self' match, which contains the '__other' match
872
+ let self_subpats = create_subpatterns ( cx, span, self_str, fields. len ( ) ) ;
873
+ let self_arm = ast:: arm {
874
+ pats : ~[ build:: mk_pat_enum ( cx, span, type_path, self_subpats) ] ,
875
+ guard : None ,
876
+ body : build:: mk_simple_block ( cx, span, other_match_expr) ,
877
+ } ;
878
+
879
+ // Create the match on 'self'
880
+ let self_expr = build:: mk_path ( cx, span, ~[ cx. ident_of ( self_str) ] ) ;
881
+ let self_expr = build:: mk_unary ( cx, span, deref, self_expr) ;
882
+ let self_match_expr = expr_match ( self_expr, ~[ self_arm] ) ;
883
+ let self_match_expr = build:: mk_expr ( cx, span, self_match_expr) ;
884
+
885
+ create_eq_method ( cx, span, method_ident,
886
+ type_ident, ty_params, self_match_expr)
887
+ }
888
+
814
889
fn expand_deriving_iter_bytes_enum_method ( cx : ext_ctxt ,
815
890
span : span ,
816
891
enum_definition : & enum_def )
0 commit comments