@@ -433,6 +433,14 @@ pub const InstGraph = struct {
433433 try self .union_ (left , right );
434434 return ;
435435 }
436+ if (left_named .kind == .alias ) {
437+ try self .unifyThroughBacking (left , left_content , right , pending );
438+ return ;
439+ }
440+ if (right_named .kind == .alias ) {
441+ try self .unifyThroughBacking (right , right_content , left , pending );
442+ return ;
443+ }
436444 try self .unifyThroughBacking (left , left_content , right , pending );
437445 },
438446 else = > try self .unifyThroughBacking (left , left_content , right , pending ),
@@ -1036,3 +1044,53 @@ pub fn assertNoDuplicateTags(name_store: *const names.NameStore, tags: []const T
10361044test "monotype solve declarations are referenced" {
10371045 std .testing .refAllDecls (@This ());
10381046}
1047+
1048+ test "recursive nominal backing can meet an alias to that nominal" {
1049+ const gpa = std .testing .allocator ;
1050+
1051+ var type_store = Type .Store .init (gpa );
1052+ defer type_store .deinit ();
1053+
1054+ var name_store = names .NameStore .init (gpa );
1055+ defer name_store .deinit ();
1056+
1057+ var unsolved_monos = std .AutoHashMap (Type .TypeId , void ).init (gpa );
1058+ defer unsolved_monos .deinit ();
1059+
1060+ const graph = try InstGraph .create (gpa , & type_store , & name_store , & unsolved_monos );
1061+ defer graph .destroy ();
1062+
1063+ const module_name = try name_store .internModuleName ("Main" );
1064+ const nominal_name = try name_store .internTypeName ("Role" );
1065+ const alias_name = try name_store .internTypeName ("Wrapper.Role" );
1066+ const nominal_type : Type.NamedType = .{ .module = .{}, .ty = @enumFromInt (3 ) };
1067+ const alias_type : Type.NamedType = .{ .module = .{}, .ty = @enumFromInt (4 ) };
1068+ const nominal_def : Type.TypeDef = .{ .module_name = module_name , .type_name = nominal_name };
1069+ const alias_def : Type.TypeDef = .{ .module_name = module_name , .type_name = alias_name };
1070+
1071+ const nominal = try graph .newNode (.{ .unresolved = .{} });
1072+ try graph .setContent (nominal , .{ .named = .{
1073+ .named_type = nominal_type ,
1074+ .def = nominal_def ,
1075+ .kind = .nominal ,
1076+ .builtin_owner = null ,
1077+ .args = try graph .arena ().alloc (NodeId , 0 ),
1078+ .backing = .{ .node = nominal , .use = .inspectable },
1079+ } });
1080+
1081+ const alias = try graph .newNode (.{ .named = .{
1082+ .named_type = alias_type ,
1083+ .def = alias_def ,
1084+ .kind = .alias ,
1085+ .builtin_owner = null ,
1086+ .args = try graph .arena ().alloc (NodeId , 0 ),
1087+ .backing = .{ .node = nominal , .use = .inspectable },
1088+ } });
1089+
1090+ const before_nodes = graph .nodes .items .len ;
1091+ try graph .unify (nominal , alias );
1092+
1093+ try std .testing .expectEqual (before_nodes , graph .nodes .items .len );
1094+ try std .testing .expectEqual (nominal , graph .find (nominal ));
1095+ try std .testing .expectEqual (alias , graph .find (alias ));
1096+ }
0 commit comments