@@ -346,15 +346,73 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
346
346
// `Hash` cannot be derived for unions, so no default impl can be provided.
347
347
ast:: Adt :: Union ( _) => return None ,
348
348
349
- // FIXME: generate trait variants
350
349
ast:: Adt :: Enum ( enum_) => {
351
350
// => std::mem::discriminant(self) == std::mem::discriminant(other)
352
- let lhs = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
353
- let lhs = make:: expr_call ( gen_discriminant ( ) , make:: arg_list ( Some ( lhs) ) ) ;
354
- let rhs = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
355
- let rhs = make:: expr_call ( gen_discriminant ( ) , make:: arg_list ( Some ( rhs) ) ) ;
356
- let cmp = make:: expr_op ( ast:: BinOp :: EqualityTest , lhs, rhs) ;
357
- make:: block_expr ( None , Some ( cmp) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
351
+ let self_name = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
352
+ let lhs = make:: expr_call ( gen_discriminant ( ) , make:: arg_list ( Some ( self_name. clone ( ) ) ) ) ;
353
+ let other_name = make:: expr_path ( make:: ext:: ident_path ( "other" ) ) ;
354
+ let rhs = make:: expr_call ( gen_discriminant ( ) , make:: arg_list ( Some ( other_name. clone ( ) ) ) ) ;
355
+ let eq_check = make:: expr_op ( ast:: BinOp :: EqualityTest , lhs, rhs) ;
356
+
357
+ let mut case_count = 0 ;
358
+ let mut arms = vec ! [ ] ;
359
+ for variant in enum_. variant_list ( ) ?. variants ( ) {
360
+ case_count += 1 ;
361
+ match variant. field_list ( ) {
362
+ // => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
363
+ Some ( ast:: FieldList :: RecordFieldList ( list) ) => {
364
+ // let mut pats = vec![];
365
+ // let mut fields = vec![];
366
+ for field in list. fields ( ) {
367
+ // let field_name = field.name()?;
368
+ // let pat = make::record_pat(path, pats);
369
+ // let pat = make::ident_pat(false, false, field_name.clone());
370
+ // pats.push(pat.into());
371
+
372
+ // let path = make::ext::ident_path(&field_name.to_string());
373
+ // let method_call = gen_clone_call(make::expr_path(path));
374
+ // let name_ref = make::name_ref(&field_name.to_string());
375
+ // let field = make::record_expr_field(name_ref, Some(method_call));
376
+ // fields.push(field);
377
+ }
378
+ // let pat = make::record_pat(variant_name.clone(), pats.into_iter());
379
+ // let fields = make::record_expr_field_list(fields);
380
+ // let record_expr = make::record_expr(variant_name, fields).into();
381
+ // arms.push(make::match_arm(Some(pat.into()), None, record_expr));
382
+ todo ! ( "implement tuple record iteration" )
383
+ }
384
+ Some ( ast:: FieldList :: TupleFieldList ( list) ) => {
385
+ todo ! ( "implement tuple enum iteration" )
386
+ }
387
+ None => continue ,
388
+ }
389
+ }
390
+
391
+ if !arms. is_empty ( ) && case_count > arms. len ( ) {
392
+ let lhs = make:: wildcard_pat ( ) . into ( ) ;
393
+ arms. push ( make:: match_arm ( Some ( lhs) , None , make:: expr_literal ( "true" ) . into ( ) ) ) ;
394
+ }
395
+
396
+ let expr = match arms. len ( ) {
397
+ 0 => eq_check,
398
+ _ => {
399
+ let condition = make:: condition ( eq_check, None ) ;
400
+
401
+ let match_target = make:: expr_tuple ( vec ! [ self_name, other_name] ) ;
402
+ let list = make:: match_arm_list ( arms) . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
403
+ let match_expr = Some ( make:: expr_match ( match_target, list) ) ;
404
+ let then_branch = make:: block_expr ( None , match_expr) ;
405
+ let then_branch = then_branch. indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
406
+
407
+ let else_branche = make:: expr_literal ( "false" ) ;
408
+ let else_branche = make:: block_expr ( None , Some ( else_branche. into ( ) ) )
409
+ . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
410
+
411
+ make:: expr_if ( condition, then_branch, Some ( else_branche. into ( ) ) )
412
+ }
413
+ } ;
414
+
415
+ make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) )
358
416
}
359
417
ast:: Adt :: Struct ( strukt) => match strukt. field_list ( ) {
360
418
Some ( ast:: FieldList :: RecordFieldList ( field_list) ) => {
0 commit comments