@@ -727,7 +727,7 @@ const Unifier = struct {
727
727
// Unify fields
728
728
switch (fields_ext ) {
729
729
.exactly_the_same = > {
730
- // Unify exts (these will both be the empty record)
730
+ // Unify exts
731
731
try self .unifyGuarded (a_gathered_fields .ext , b_gathered_fields .ext );
732
732
733
733
// Unify shared fields
@@ -913,11 +913,10 @@ const Unifier = struct {
913
913
b_fields_range : RecordFieldSafeList.Range ,
914
914
) PartitionedRecordFields {
915
915
// First sort the fields
916
- const sort_ctx = RecordField.SortCtx { .store = ident_store };
917
916
const a_fields = scratch .gathered_fields .rangeToSlice (a_fields_range );
918
- std .mem .sort (RecordField , a_fields , sort_ctx , comptime RecordField .sortByNameAsc );
917
+ std .mem .sort (RecordField , a_fields , ident_store , comptime RecordField .sortByNameAsc );
919
918
const b_fields = scratch .gathered_fields .rangeToSlice (b_fields_range );
920
- std .mem .sort (RecordField , b_fields , sort_ctx , comptime RecordField .sortByNameAsc );
919
+ std .mem .sort (RecordField , b_fields , ident_store , comptime RecordField .sortByNameAsc );
921
920
922
921
// Get the start of index of the new range
923
922
const a_fields_start : RecordFieldSafeList.Idx = @enumFromInt (scratch .only_in_a_fields .len ());
@@ -1130,7 +1129,7 @@ const Unifier = struct {
1130
1129
// Unify tags
1131
1130
switch (tags_ext ) {
1132
1131
.exactly_the_same = > {
1133
- // Unify exts (these will both be the empty tag_union)
1132
+ // Unify exts
1134
1133
try self .unifyGuarded (a_gathered_tags .ext , b_gathered_tags .ext );
1135
1134
1136
1135
// Unify shared tags
@@ -1316,11 +1315,10 @@ const Unifier = struct {
1316
1315
b_tags_range : TagSafeList.Range ,
1317
1316
) PartitionedTags {
1318
1317
// First sort the tags
1319
- const sort_ctx = Tag.SortCtx { .store = ident_store };
1320
1318
const a_tags = scratch .gathered_tags .rangeToSlice (a_tags_range );
1321
- std .mem .sort (Tag , a_tags , sort_ctx , comptime Tag .sortByNameAsc );
1319
+ std .mem .sort (Tag , a_tags , ident_store , comptime Tag .sortByNameAsc );
1322
1320
const b_tags = scratch .gathered_tags .rangeToSlice (b_tags_range );
1323
- std .mem .sort (Tag , b_tags , sort_ctx , comptime Tag .sortByNameAsc );
1321
+ std .mem .sort (Tag , b_tags , ident_store , comptime Tag .sortByNameAsc );
1324
1322
1325
1323
// Get the start of index of the new range
1326
1324
const a_tags_start : TagSafeList.Idx = @enumFromInt (scratch .only_in_a_tags .len ());
@@ -2849,6 +2847,41 @@ test "unify - closed record mismatch on diff fields (fail)" {
2849
2847
2850
2848
// unification - structure/structure - records open
2851
2849
2850
+ test "unify - identital open records" {
2851
+ const gpa = std .testing .allocator ;
2852
+ var env = TestEnv .init (gpa );
2853
+ defer env .deinit ();
2854
+
2855
+ const str = env .types_store .freshFromContent (Content { .structure = .str });
2856
+
2857
+ const field_shared = env .mkRecordField ("x" , str );
2858
+
2859
+ const a_rec_data = env .mkRecordOpen (&[_ ]RecordField {field_shared });
2860
+ const a = env .types_store .freshFromContent (a_rec_data .content );
2861
+ const b_rec_data = env .mkRecordOpen (&[_ ]RecordField {field_shared });
2862
+ const b = env .types_store .freshFromContent (b_rec_data .content );
2863
+
2864
+ const result = unify (& env .types_store , & env .scratch , a , b );
2865
+
2866
+ try std .testing .expectEqual (.ok , result );
2867
+ try std .testing .expectEqual (Slot { .redirect = b }, env .types_store .getSlot (a ));
2868
+
2869
+ // check that the update var at b is correct
2870
+
2871
+ const b_record = try TestEnv .getRecordOrErr (try env .getDescForRootVar (b ));
2872
+ try std .testing .expectEqual (1 , b_record .fields .len ());
2873
+ const b_record_fields = env .types_store .getRecordFieldsSlice (b_record .fields );
2874
+ try std .testing .expectEqual (field_shared .name , b_record_fields .items (.name )[0 ]);
2875
+ try std .testing .expectEqual (field_shared .var_ , b_record_fields .items (.var_ )[0 ]);
2876
+
2877
+ const b_ext = env .types_store .resolveVar (b_record .ext ).desc .content ;
2878
+ try std .testing .expectEqual (Content { .flex_var = null }, b_ext );
2879
+
2880
+ // check that fresh vars are correct
2881
+
2882
+ try std .testing .expectEqual (0 , env .scratch .fresh_vars .len ());
2883
+ }
2884
+
2852
2885
test "unify - open record a extends b" {
2853
2886
const gpa = std .testing .allocator ;
2854
2887
var env = TestEnv .init (gpa );
@@ -3281,6 +3314,46 @@ test "unify - closed tag_unions with diff args (fail)" {
3281
3314
3282
3315
// unification - structure/structure - tag unions open
3283
3316
3317
+ test "unify - identital open tag unions" {
3318
+ const gpa = std .testing .allocator ;
3319
+ var env = TestEnv .init (gpa );
3320
+ defer env .deinit ();
3321
+
3322
+ const str = env .types_store .freshFromContent (Content { .structure = .str });
3323
+
3324
+ const tag_shared = env .mkTag ("Shared" , &[_ ]Var { str , str });
3325
+
3326
+ const tag_union_a = env .mkTagUnionOpen (&[_ ]Tag {tag_shared });
3327
+ const a = env .types_store .freshFromContent (tag_union_a .content );
3328
+
3329
+ const tag_union_b = env .mkTagUnionOpen (&[_ ]Tag {tag_shared });
3330
+ const b = env .types_store .freshFromContent (tag_union_b .content );
3331
+
3332
+ const result = unify (& env .types_store , & env .scratch , a , b );
3333
+
3334
+ try std .testing .expectEqual (.ok , result );
3335
+ try std .testing .expectEqual (Slot { .redirect = b }, env .types_store .getSlot (a ));
3336
+
3337
+ // check that the update var at b is correct
3338
+
3339
+ const b_tag_union = try TestEnv .getTagUnionOrErr (try env .getDescForRootVar (b ));
3340
+ try std .testing .expectEqual (1 , b_tag_union .tags .len ());
3341
+
3342
+ const b_tags = env .types_store .tags .rangeToSlice (b_tag_union .tags );
3343
+ const b_tags_names = b_tags .items (.name );
3344
+ const b_tags_args = b_tags .items (.args );
3345
+ try std .testing .expectEqual (1 , b_tags .len );
3346
+ try std .testing .expectEqual (tag_shared .name , b_tags_names [0 ]);
3347
+ try std .testing .expectEqual (tag_shared .args , b_tags_args [0 ]);
3348
+
3349
+ const b_ext = env .types_store .resolveVar (b_tag_union .ext ).desc .content ;
3350
+ try std .testing .expectEqual (Content { .flex_var = null }, b_ext );
3351
+
3352
+ // check that fresh vars are correct
3353
+
3354
+ try std .testing .expectEqual (0 , env .scratch .fresh_vars .len ());
3355
+ }
3356
+
3284
3357
test "unify - open tag union a extends b" {
3285
3358
const gpa = std .testing .allocator ;
3286
3359
var env = TestEnv .init (gpa );
0 commit comments