| ... | ... | @@ -14883,7 +14883,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 14883 | 14883 | union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: { |
| 14884 | 14884 | var buffer: Value.ToTypeBuffer = undefined; |
| 14885 | 14885 | break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator); |
| 14886 | | } else try sema.generateUnionTagTypeSimple(block, fields_len); |
| 14886 | } else try sema.generateUnionTagTypeSimple(block, fields_len, null); |
| 14887 | 14887 | |
| 14888 | 14888 | // Fields |
| 14889 | 14889 | if (fields_len > 0) { |
| ... | ... | @@ -24237,7 +24237,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 24237 | 24237 | if (small.auto_enum_tag) { |
| 24238 | 24238 | // The provided type is an integer type and we must construct the enum tag type here. |
| 24239 | 24239 | int_tag_ty = provided_ty; |
| 24240 | | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty); |
| 24240 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj); |
| 24241 | 24241 | const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data; |
| 24242 | 24242 | enum_field_names = &enum_obj.fields; |
| 24243 | 24243 | enum_value_map = &enum_obj.values; |
| ... | ... | @@ -24253,7 +24253,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 24253 | 24253 | // If auto_enum_tag is false, this is an untagged union. However, for semantic analysis |
| 24254 | 24254 | // purposes, we still auto-generate an enum tag type the same way. That the union is |
| 24255 | 24255 | // untagged is represented by the Type tag (union vs union_tagged). |
| 24256 | | union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, fields_len); |
| 24256 | union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, fields_len, union_obj); |
| 24257 | 24257 | enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields; |
| 24258 | 24258 | } |
| 24259 | 24259 | |
| ... | ... | @@ -24422,6 +24422,7 @@ fn generateUnionTagTypeNumbered( |
| 24422 | 24422 | block: *Block, |
| 24423 | 24423 | fields_len: u32, |
| 24424 | 24424 | int_ty: Type, |
| 24425 | union_obj: *Module.Union, |
| 24425 | 24426 | ) !Type { |
| 24426 | 24427 | const mod = sema.mod; |
| 24427 | 24428 | |
| ... | ... | @@ -24437,13 +24438,24 @@ fn generateUnionTagTypeNumbered( |
| 24437 | 24438 | }; |
| 24438 | 24439 | const enum_ty = Type.initPayload(&enum_ty_payload.base); |
| 24439 | 24440 | const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty); |
| 24440 | | // TODO better type name |
| 24441 | | const new_decl_index = try mod.createAnonymousDecl(block, .{ |
| 24441 | |
| 24442 | const src_decl = mod.declPtr(block.src_decl); |
| 24443 | const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope); |
| 24444 | errdefer mod.destroyDecl(new_decl_index); |
| 24445 | const name = name: { |
| 24446 | const fqn = try union_obj.getFullyQualifiedName(mod); |
| 24447 | defer sema.gpa.free(fqn); |
| 24448 | break :name try std.fmt.allocPrintZ(mod.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn}); |
| 24449 | }; |
| 24450 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{ |
| 24442 | 24451 | .ty = Type.type, |
| 24443 | 24452 | .val = enum_val, |
| 24444 | | }); |
| 24453 | }, name); |
| 24454 | sema.mod.declPtr(new_decl_index).name_fully_qualified = true; |
| 24455 | |
| 24445 | 24456 | const new_decl = mod.declPtr(new_decl_index); |
| 24446 | 24457 | new_decl.owns_tv = true; |
| 24458 | new_decl.name_fully_qualified = true; |
| 24447 | 24459 | errdefer mod.abortAnonDecl(new_decl_index); |
| 24448 | 24460 | |
| 24449 | 24461 | enum_obj.* = .{ |
| ... | ... | @@ -24463,7 +24475,7 @@ fn generateUnionTagTypeNumbered( |
| 24463 | 24475 | return enum_ty; |
| 24464 | 24476 | } |
| 24465 | 24477 | |
| 24466 | | fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Type { |
| 24478 | fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize, maybe_union_obj: ?*Module.Union) !Type { |
| 24467 | 24479 | const mod = sema.mod; |
| 24468 | 24480 | |
| 24469 | 24481 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| ... | ... | @@ -24478,11 +24490,30 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Ty |
| 24478 | 24490 | }; |
| 24479 | 24491 | const enum_ty = Type.initPayload(&enum_ty_payload.base); |
| 24480 | 24492 | const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty); |
| 24481 | | // TODO better type name |
| 24482 | | const new_decl_index = try mod.createAnonymousDecl(block, .{ |
| 24483 | | .ty = Type.type, |
| 24484 | | .val = enum_val, |
| 24485 | | }); |
| 24493 | |
| 24494 | const new_decl_index = new_decl_index: { |
| 24495 | const union_obj = maybe_union_obj orelse { |
| 24496 | break :new_decl_index try mod.createAnonymousDecl(block, .{ |
| 24497 | .ty = Type.type, |
| 24498 | .val = enum_val, |
| 24499 | }); |
| 24500 | }; |
| 24501 | const src_decl = mod.declPtr(block.src_decl); |
| 24502 | const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope); |
| 24503 | errdefer mod.destroyDecl(new_decl_index); |
| 24504 | const name = name: { |
| 24505 | const fqn = try union_obj.getFullyQualifiedName(mod); |
| 24506 | defer sema.gpa.free(fqn); |
| 24507 | break :name try std.fmt.allocPrintZ(mod.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn}); |
| 24508 | }; |
| 24509 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{ |
| 24510 | .ty = Type.type, |
| 24511 | .val = enum_val, |
| 24512 | }, name); |
| 24513 | sema.mod.declPtr(new_decl_index).name_fully_qualified = true; |
| 24514 | break :new_decl_index new_decl_index; |
| 24515 | }; |
| 24516 | |
| 24486 | 24517 | const new_decl = mod.declPtr(new_decl_index); |
| 24487 | 24518 | new_decl.owns_tv = true; |
| 24488 | 24519 | errdefer mod.abortAnonDecl(new_decl_index); |