@@ -199,8 +199,6 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
199
199
auto self_pattern_str = " __self_" + std::to_string (i);
200
200
auto other_pattern_str = " __other_" + std::to_string (i);
201
201
202
- rust_debug (" ]ARTHUR[ %s" , self_pattern_str.c_str ());
203
-
204
202
self_patterns.emplace_back (
205
203
builder.identifier_pattern (self_pattern_str));
206
204
other_patterns.emplace_back (
@@ -240,15 +238,55 @@ MatchCase
240
238
DerivePartialEq::match_enum_struct (PathInExpression variant_path,
241
239
const EnumItemStruct &variant)
242
240
{
243
- // NOTE: We currently do not support compiling struct patterns where an
244
- // identifier is assigned a new pattern, e.g. Bloop { f0: x }
245
- // This is what we should be using to compile PartialEq for enum struct
246
- // variants, as we need to be comparing the field of each instance meaning we
247
- // need to give two different names to two different instances of the same
248
- // field. We cannot just use the field's name like we do when deriving
249
- // `Clone`.
250
-
251
- rust_unreachable ();
241
+ auto self_fields = std::vector<std::unique_ptr<StructPatternField>> ();
242
+ auto other_fields = std::vector<std::unique_ptr<StructPatternField>> ();
243
+
244
+ auto self_other_exprs = std::vector<SelfOther> ();
245
+
246
+ for (auto &field : variant.get_struct_fields ())
247
+ {
248
+ // The patterns we're creating for each field are `self_<field>` and
249
+ // `other_<field>` where `field` is the name of the field. It doesn't
250
+ // actually matter what we use, as long as it's ordered, unique, and that
251
+ // we can reuse it in the match case's return expression to check that
252
+ // they are equal.
253
+
254
+ auto field_name = field.get_field_name ().as_string ();
255
+
256
+ auto self_pattern_str = " __self_" + field_name;
257
+ auto other_pattern_str = " __other_" + field_name;
258
+
259
+ self_fields.emplace_back (builder.struct_pattern_ident_pattern (
260
+ field_name, builder.identifier_pattern (self_pattern_str)));
261
+ other_fields.emplace_back (builder.struct_pattern_ident_pattern (
262
+ field_name, builder.identifier_pattern (other_pattern_str)));
263
+
264
+ self_other_exprs.emplace_back (SelfOther{
265
+ builder.identifier (self_pattern_str),
266
+ builder.identifier (other_pattern_str),
267
+ });
268
+ }
269
+
270
+ auto self_elts = StructPatternElements (std::move (self_fields));
271
+ auto other_elts = StructPatternElements (std::move (other_fields));
272
+
273
+ auto self_pattern = std::unique_ptr<Pattern> (
274
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
275
+ variant_path, loc, std::move (self_elts))),
276
+ false , false , loc));
277
+ auto other_pattern = std::unique_ptr<Pattern> (
278
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
279
+ variant_path, loc, std::move (other_elts))),
280
+ false , false , loc));
281
+
282
+ auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
283
+ vec (std::move (self_pattern), std::move (other_pattern)));
284
+
285
+ auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
286
+
287
+ auto expr = build_eq_expression (std::move (self_other_exprs));
288
+
289
+ return builder.match_case (std::move (pattern), std::move (expr));
252
290
}
253
291
254
292
void
@@ -275,9 +313,9 @@ DerivePartialEq::visit_enum (Enum &item)
275
313
static_cast <EnumItemTuple &> (*variant)));
276
314
break ;
277
315
case EnumItem::Kind::Struct:
278
- rust_sorry_at (
279
- item. get_locus () ,
280
- " cannot derive(PartialEq) for enum struct variants yet " );
316
+ cases. emplace_back (
317
+ match_enum_struct (variant_path ,
318
+ static_cast <EnumItemStruct &> (*variant)) );
281
319
break ;
282
320
}
283
321
}
0 commit comments