| ... | @@ -3615,8 +3615,6 @@ fn validateUnionInit( | ... | @@ -3615,8 +3615,6 @@ fn validateUnionInit( |
| 3615 | union_ptr: Air.Inst.Ref, | 3615 | union_ptr: Air.Inst.Ref, |
| 3616 | is_comptime: bool, | 3616 | is_comptime: bool, |
| 3617 | ) CompileError!void { | 3617 | ) CompileError!void { |
| 3618 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | | |
| 3619 | | | |
| 3620 | if (instrs.len != 1) { | 3618 | if (instrs.len != 1) { |
| 3621 | const msg = msg: { | 3619 | const msg = msg: { |
| 3622 | const msg = try sema.errMsg( | 3620 | const msg = try sema.errMsg( |
| ... | @@ -3650,7 +3648,8 @@ fn validateUnionInit( | ... | @@ -3650,7 +3648,8 @@ fn validateUnionInit( |
| 3650 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; | 3648 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; |
| 3651 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 3649 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3652 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); | 3650 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 3653 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); | 3651 | // Validate the field access but ignore the index since we want the tag enum field index. |
| | 3652 | _ = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| 3654 | const air_tags = sema.air_instructions.items(.tag); | 3653 | const air_tags = sema.air_instructions.items(.tag); |
| 3655 | const air_datas = sema.air_instructions.items(.data); | 3654 | const air_datas = sema.air_instructions.items(.data); |
| 3656 | const field_ptr_air_ref = sema.inst_map.get(field_ptr).?; | 3655 | const field_ptr_air_ref = sema.inst_map.get(field_ptr).?; |
| ... | @@ -3709,7 +3708,9 @@ fn validateUnionInit( | ... | @@ -3709,7 +3708,9 @@ fn validateUnionInit( |
| 3709 | break; | 3708 | break; |
| 3710 | } | 3709 | } |
| 3711 | | 3710 | |
| 3712 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 3711 | const tag_ty = union_ty.unionTagTypeHypothetical(); |
| | 3712 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 3713 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 3713 | | 3714 | |
| 3714 | if (init_val) |val| { | 3715 | if (init_val) |val| { |
| 3715 | // Our task is to delete all the `field_ptr` and `store` instructions, and insert | 3716 | // Our task is to delete all the `field_ptr` and `store` instructions, and insert |
| ... | @@ -3726,7 +3727,7 @@ fn validateUnionInit( | ... | @@ -3726,7 +3727,7 @@ fn validateUnionInit( |
| 3726 | } | 3727 | } |
| 3727 | | 3728 | |
| 3728 | try sema.requireFunctionBlock(block, init_src); | 3729 | try sema.requireFunctionBlock(block, init_src); |
| 3729 | const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val); | 3730 | const new_tag = try sema.addConstant(tag_ty, tag_val); |
| 3730 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); | 3731 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); |
| 3731 | } | 3732 | } |
| 3732 | | 3733 | |
| ... | @@ -8838,13 +8839,11 @@ fn zirSwitchCapture( | ... | @@ -8838,13 +8839,11 @@ fn zirSwitchCapture( |
| 8838 | switch (operand_ty.zigTypeTag()) { | 8839 | switch (operand_ty.zigTypeTag()) { |
| 8839 | .Union => { | 8840 | .Union => { |
| 8840 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; | 8841 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; |
| 8841 | const enum_ty = union_obj.tag_ty; | | |
| 8842 | | | |
| 8843 | const first_item = try sema.resolveInst(items[0]); | 8842 | const first_item = try sema.resolveInst(items[0]); |
| 8844 | // Previous switch validation ensured this will succeed | 8843 | // Previous switch validation ensured this will succeed |
| 8845 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; | 8844 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; |
| 8846 | | 8845 | |
| 8847 | const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?); | 8846 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); |
| 8848 | const first_field = union_obj.fields.values()[first_field_index]; | 8847 | const first_field = union_obj.fields.values()[first_field_index]; |
| 8849 | | 8848 | |
| 8850 | for (items[1..]) |item, i| { | 8849 | for (items[1..]) |item, i| { |
| ... | @@ -8852,7 +8851,7 @@ fn zirSwitchCapture( | ... | @@ -8852,7 +8851,7 @@ fn zirSwitchCapture( |
| 8852 | // Previous switch validation ensured this will succeed | 8851 | // Previous switch validation ensured this will succeed |
| 8853 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; | 8852 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 8854 | | 8853 | |
| 8855 | const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?; | 8854 | const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; |
| 8856 | const field = union_obj.fields.values()[field_index]; | 8855 | const field = union_obj.fields.values()[field_index]; |
| 8857 | if (!field.ty.eql(first_field.ty, sema.mod)) { | 8856 | if (!field.ty.eql(first_field.ty, sema.mod)) { |
| 8858 | const msg = msg: { | 8857 | const msg = msg: { |
| ... | @@ -15585,7 +15584,9 @@ fn unionInit( | ... | @@ -15585,7 +15584,9 @@ fn unionInit( |
| 15585 | const init = try sema.coerce(block, field.ty, uncasted_init, init_src); | 15584 | const init = try sema.coerce(block, field.ty, uncasted_init, init_src); |
| 15586 | | 15585 | |
| 15587 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { | 15586 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { |
| 15588 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 15587 | const tag_ty = union_ty.unionTagTypeHypothetical(); |
| | 15588 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 15589 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 15589 | return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{ | 15590 | return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{ |
| 15590 | .tag = tag_val, | 15591 | .tag = tag_val, |
| 15591 | .val = init_val, | 15592 | .val = init_val, |
| ... | @@ -15683,7 +15684,9 @@ fn zirStructInit( | ... | @@ -15683,7 +15684,9 @@ fn zirStructInit( |
| 15683 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; | 15684 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 15684 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); | 15685 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 15685 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); | 15686 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 15686 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 15687 | const tag_ty = resolved_ty.unionTagTypeHypothetical(); |
| | 15688 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 15689 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 15687 | | 15690 | |
| 15688 | const init_inst = try sema.resolveInst(item.data.init); | 15691 | const init_inst = try sema.resolveInst(item.data.init); |
| 15689 | if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| { | 15692 | if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| { |
| ... | @@ -16448,9 +16451,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -16448,9 +16451,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 16448 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); | 16451 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); |
| 16449 | const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); | 16452 | const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); |
| 16450 | const union_val = val.cast(Value.Payload.Union).?.data; | 16453 | const union_val = val.cast(Value.Payload.Union).?.data; |
| 16451 | const tag_ty = type_info_ty.unionTagType().?; | | |
| 16452 | const target = mod.getTarget(); | 16454 | const target = mod.getTarget(); |
| 16453 | const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?; | 16455 | const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?; |
| 16454 | if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src); | 16456 | if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src); |
| 16455 | switch (@intToEnum(std.builtin.TypeId, tag_index)) { | 16457 | switch (@intToEnum(std.builtin.TypeId, tag_index)) { |
| 16456 | .Type => return Air.Inst.Ref.type_type, | 16458 | .Type => return Air.Inst.Ref.type_type, |
| ... | @@ -25155,8 +25157,7 @@ fn coerceEnumToUnion( | ... | @@ -25155,8 +25157,7 @@ fn coerceEnumToUnion( |
| 25155 | | 25157 | |
| 25156 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); | 25158 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); |
| 25157 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { | 25159 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 25158 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | 25160 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { |
| 25159 | const field_index = union_obj.tag_ty.enumTagFieldIndex(val, sema.mod) orelse { | | |
| 25160 | const msg = msg: { | 25161 | const msg = msg: { |
| 25161 | const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{ | 25162 | const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 25162 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), | 25163 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), |
| ... | @@ -25167,6 +25168,8 @@ fn coerceEnumToUnion( | ... | @@ -25167,6 +25168,8 @@ fn coerceEnumToUnion( |
| 25167 | }; | 25168 | }; |
| 25168 | return sema.failWithOwnedErrorMsg(msg); | 25169 | return sema.failWithOwnedErrorMsg(msg); |
| 25169 | }; | 25170 | }; |
| | 25171 | |
| | 25172 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 25170 | const field = union_obj.fields.values()[field_index]; | 25173 | const field = union_obj.fields.values()[field_index]; |
| 25171 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); | 25174 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); |
| 25172 | if (field_ty.zigTypeTag() == .NoReturn) { | 25175 | if (field_ty.zigTypeTag() == .NoReturn) { |