| ... | @@ -3772,6 +3772,7 @@ fn validateStructInit( | ... | @@ -3772,6 +3772,7 @@ fn validateStructInit( |
| 3772 | } | 3772 | } |
| 3773 | | 3773 | |
| 3774 | var root_msg: ?*Module.ErrorMsg = null; | 3774 | var root_msg: ?*Module.ErrorMsg = null; |
| | 3775 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 3775 | | 3776 | |
| 3776 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); | 3777 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); |
| 3777 | if ((is_comptime or block.is_comptime) and | 3778 | if ((is_comptime or block.is_comptime) and |
| ... | @@ -3947,6 +3948,7 @@ fn validateStructInit( | ... | @@ -3947,6 +3948,7 @@ fn validateStructInit( |
| 3947 | } | 3948 | } |
| 3948 | | 3949 | |
| 3949 | if (root_msg) |msg| { | 3950 | if (root_msg) |msg| { |
| | 3951 | root_msg = null; |
| 3950 | if (struct_ty.castTag(.@"struct")) |struct_obj| { | 3952 | if (struct_ty.castTag(.@"struct")) |struct_obj| { |
| 3951 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); | 3953 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); |
| 3952 | defer gpa.free(fqn); | 3954 | defer gpa.free(fqn); |
| ... | @@ -4005,6 +4007,8 @@ fn zirValidateArrayInit( | ... | @@ -4005,6 +4007,8 @@ fn zirValidateArrayInit( |
| 4005 | if (instrs.len != array_len and array_ty.isTuple()) { | 4007 | if (instrs.len != array_len and array_ty.isTuple()) { |
| 4006 | const struct_obj = array_ty.castTag(.tuple).?.data; | 4008 | const struct_obj = array_ty.castTag(.tuple).?.data; |
| 4007 | var root_msg: ?*Module.ErrorMsg = null; | 4009 | var root_msg: ?*Module.ErrorMsg = null; |
| | 4010 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| | 4011 | |
| 4008 | for (struct_obj.values) |default_val, i| { | 4012 | for (struct_obj.values) |default_val, i| { |
| 4009 | if (i < instrs.len) continue; | 4013 | if (i < instrs.len) continue; |
| 4010 | | 4014 | |
| ... | @@ -4019,6 +4023,7 @@ fn zirValidateArrayInit( | ... | @@ -4019,6 +4023,7 @@ fn zirValidateArrayInit( |
| 4019 | } | 4023 | } |
| 4020 | | 4024 | |
| 4021 | if (root_msg) |msg| { | 4025 | if (root_msg) |msg| { |
| | 4026 | root_msg = null; |
| 4022 | return sema.failWithOwnedErrorMsg(msg); | 4027 | return sema.failWithOwnedErrorMsg(msg); |
| 4023 | } | 4028 | } |
| 4024 | } | 4029 | } |
| ... | @@ -8964,12 +8969,15 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8964,12 +8969,15 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8964 | }, | 8969 | }, |
| 8965 | }; | 8970 | }; |
| 8966 | | 8971 | |
| 8967 | const union_originally = blk: { | 8972 | const maybe_union_ty = blk: { |
| 8968 | const zir_data = sema.code.instructions.items(.data); | 8973 | const zir_data = sema.code.instructions.items(.data); |
| 8969 | const cond_index = Zir.refToIndex(extra.data.operand).?; | 8974 | const cond_index = Zir.refToIndex(extra.data.operand).?; |
| 8970 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; | 8975 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; |
| 8971 | break :blk sema.typeOf(raw_operand).zigTypeTag() == .Union; | 8976 | break :blk sema.typeOf(raw_operand); |
| 8972 | }; | 8977 | }; |
| | 8978 | const union_originally = maybe_union_ty.zigTypeTag() == .Union; |
| | 8979 | var seen_union_fields: []?Module.SwitchProngSrc = &.{}; |
| | 8980 | defer gpa.free(seen_union_fields); |
| 8973 | | 8981 | |
| 8974 | const operand_ty = sema.typeOf(operand); | 8982 | const operand_ty = sema.typeOf(operand); |
| 8975 | | 8983 | |
| ... | @@ -9004,7 +9012,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9004,7 +9012,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9004 | .Union => unreachable, // handled in zirSwitchCond | 9012 | .Union => unreachable, // handled in zirSwitchCond |
| 9005 | .Enum => { | 9013 | .Enum => { |
| 9006 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); | 9014 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); |
| 9007 | defer gpa.free(seen_fields); | 9015 | defer if (!union_originally) gpa.free(seen_fields); |
| | 9016 | if (union_originally) seen_union_fields = seen_fields; |
| 9008 | mem.set(?Module.SwitchProngSrc, seen_fields, null); | 9017 | mem.set(?Module.SwitchProngSrc, seen_fields, null); |
| 9009 | | 9018 | |
| 9010 | // This is used for non-exhaustive enum values that do not correspond to any tags. | 9019 | // This is used for non-exhaustive enum values that do not correspond to any tags. |
| ... | @@ -9637,18 +9646,28 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9637,18 +9646,28 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9637 | const item = try sema.resolveInst(item_ref); | 9646 | const item = try sema.resolveInst(item_ref); |
| 9638 | // `item` is already guaranteed to be constant known. | 9647 | // `item` is already guaranteed to be constant known. |
| 9639 | | 9648 | |
| 9640 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { | 9649 | const analyze_body = if (union_originally) blk: { |
| 9641 | error.ComptimeBreak => { | 9650 | const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; |
| 9642 | const zir_datas = sema.code.instructions.items(.data); | 9651 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| 9643 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; | 9652 | break :blk field_ty.zigTypeTag() != .NoReturn; |
| 9644 | try sema.addRuntimeBreak(&case_block, .{ | 9653 | } else true; |
| 9645 | .block_inst = break_data.block_inst, | 9654 | |
| 9646 | .operand = break_data.operand, | 9655 | if (analyze_body) { |
| 9647 | .inst = sema.comptime_break_inst, | 9656 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { |
| 9648 | }); | 9657 | error.ComptimeBreak => { |
| 9649 | }, | 9658 | const zir_datas = sema.code.instructions.items(.data); |
| 9650 | else => |e| return e, | 9659 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; |
| 9651 | }; | 9660 | try sema.addRuntimeBreak(&case_block, .{ |
| | 9661 | .block_inst = break_data.block_inst, |
| | 9662 | .operand = break_data.operand, |
| | 9663 | .inst = sema.comptime_break_inst, |
| | 9664 | }); |
| | 9665 | }, |
| | 9666 | else => |e| return e, |
| | 9667 | }; |
| | 9668 | } else { |
| | 9669 | _ = try case_block.addNoOp(.unreach); |
| | 9670 | } |
| 9652 | | 9671 | |
| 9653 | try wip_captures.finalize(); | 9672 | try wip_captures.finalize(); |
| 9654 | | 9673 | |
| ... | @@ -9689,20 +9708,34 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9689,20 +9708,34 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9689 | if (ranges_len == 0) { | 9708 | if (ranges_len == 0) { |
| 9690 | cases_len += 1; | 9709 | cases_len += 1; |
| 9691 | | 9710 | |
| | 9711 | const analyze_body = if (union_originally) |
| | 9712 | for (items) |item_ref| { |
| | 9713 | const item = try sema.resolveInst(item_ref); |
| | 9714 | const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; |
| | 9715 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| | 9716 | if (field_ty.zigTypeTag() != .NoReturn) break true; |
| | 9717 | } else false |
| | 9718 | else |
| | 9719 | true; |
| | 9720 | |
| 9692 | const body = sema.code.extra[extra_index..][0..body_len]; | 9721 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9693 | extra_index += body_len; | 9722 | extra_index += body_len; |
| 9694 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { | 9723 | if (analyze_body) { |
| 9695 | error.ComptimeBreak => { | 9724 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { |
| 9696 | const zir_datas = sema.code.instructions.items(.data); | 9725 | error.ComptimeBreak => { |
| 9697 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; | 9726 | const zir_datas = sema.code.instructions.items(.data); |
| 9698 | try sema.addRuntimeBreak(&case_block, .{ | 9727 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; |
| 9699 | .block_inst = break_data.block_inst, | 9728 | try sema.addRuntimeBreak(&case_block, .{ |
| 9700 | .operand = break_data.operand, | 9729 | .block_inst = break_data.block_inst, |
| 9701 | .inst = sema.comptime_break_inst, | 9730 | .operand = break_data.operand, |
| 9702 | }); | 9731 | .inst = sema.comptime_break_inst, |
| 9703 | }, | 9732 | }); |
| 9704 | else => |e| return e, | 9733 | }, |
| 9705 | }; | 9734 | else => |e| return e, |
| | 9735 | }; |
| | 9736 | } else { |
| | 9737 | _ = try case_block.addNoOp(.unreach); |
| | 9738 | } |
| 9706 | | 9739 | |
| 9707 | try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len + | 9740 | try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len + |
| 9708 | case_block.instructions.items.len); | 9741 | case_block.instructions.items.len); |
| ... | @@ -9824,7 +9857,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9824,7 +9857,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9824 | case_block.instructions.shrinkRetainingCapacity(0); | 9857 | case_block.instructions.shrinkRetainingCapacity(0); |
| 9825 | case_block.wip_capture_scope = wip_captures.scope; | 9858 | case_block.wip_capture_scope = wip_captures.scope; |
| 9826 | | 9859 | |
| 9827 | if (special.body.len != 0) { | 9860 | const analyze_body = if (union_originally) |
| | 9861 | for (seen_union_fields) |seen_field, index| { |
| | 9862 | if (seen_field != null) continue; |
| | 9863 | const union_obj = maybe_union_ty.cast(Type.Payload.Union).?.data; |
| | 9864 | const field_ty = union_obj.fields.values()[index].ty; |
| | 9865 | if (field_ty.zigTypeTag() != .NoReturn) break true; |
| | 9866 | } else false |
| | 9867 | else |
| | 9868 | true; |
| | 9869 | |
| | 9870 | if (special.body.len != 0 and analyze_body) { |
| 9828 | _ = sema.analyzeBodyInner(&case_block, special.body) catch |err| switch (err) { | 9871 | _ = sema.analyzeBodyInner(&case_block, special.body) catch |err| switch (err) { |
| 9829 | error.ComptimeBreak => { | 9872 | error.ComptimeBreak => { |
| 9830 | const zir_datas = sema.code.instructions.items(.data); | 9873 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -13225,6 +13268,14 @@ fn analyzeCmpUnionTag( | ... | @@ -13225,6 +13268,14 @@ fn analyzeCmpUnionTag( |
| 13225 | const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src); | 13268 | const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src); |
| 13226 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); | 13269 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); |
| 13227 | | 13270 | |
| | 13271 | if (try sema.resolveMaybeUndefVal(block, tag_src, coerced_tag)) |enum_val| { |
| | 13272 | if (enum_val.isUndef()) return sema.addConstUndef(Type.bool); |
| | 13273 | const field_ty = union_ty.unionFieldType(enum_val, sema.mod); |
| | 13274 | if (field_ty.zigTypeTag() == .NoReturn) { |
| | 13275 | return Air.Inst.Ref.bool_false; |
| | 13276 | } |
| | 13277 | } |
| | 13278 | |
| 13228 | return sema.cmpSelf(block, src, coerced_union, coerced_tag, op, un_src, tag_src); | 13279 | return sema.cmpSelf(block, src, coerced_union, coerced_tag, op, un_src, tag_src); |
| 13229 | } | 13280 | } |
| 13230 | | 13281 | |
| ... | @@ -15579,6 +15630,8 @@ fn finishStructInit( | ... | @@ -15579,6 +15630,8 @@ fn finishStructInit( |
| 15579 | const gpa = sema.gpa; | 15630 | const gpa = sema.gpa; |
| 15580 | | 15631 | |
| 15581 | var root_msg: ?*Module.ErrorMsg = null; | 15632 | var root_msg: ?*Module.ErrorMsg = null; |
| | 15633 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| | 15634 | |
| 15582 | if (struct_ty.isAnonStruct()) { | 15635 | if (struct_ty.isAnonStruct()) { |
| 15583 | const struct_obj = struct_ty.castTag(.anon_struct).?.data; | 15636 | const struct_obj = struct_ty.castTag(.anon_struct).?.data; |
| 15584 | for (struct_obj.values) |default_val, i| { | 15637 | for (struct_obj.values) |default_val, i| { |
| ... | @@ -15634,6 +15687,7 @@ fn finishStructInit( | ... | @@ -15634,6 +15687,7 @@ fn finishStructInit( |
| 15634 | } | 15687 | } |
| 15635 | | 15688 | |
| 15636 | if (root_msg) |msg| { | 15689 | if (root_msg) |msg| { |
| | 15690 | root_msg = null; |
| 15637 | if (struct_ty.castTag(.@"struct")) |struct_obj| { | 15691 | if (struct_ty.castTag(.@"struct")) |struct_obj| { |
| 15638 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); | 15692 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); |
| 15639 | defer gpa.free(fqn); | 15693 | defer gpa.free(fqn); |
| ... | @@ -21682,6 +21736,18 @@ fn unionFieldPtr( | ... | @@ -21682,6 +21736,18 @@ fn unionFieldPtr( |
| 21682 | .@"addrspace" = union_ptr_ty.ptrAddressSpace(), | 21736 | .@"addrspace" = union_ptr_ty.ptrAddressSpace(), |
| 21683 | }); | 21737 | }); |
| 21684 | | 21738 | |
| | 21739 | if (initializing and field.ty.zigTypeTag() == .NoReturn) { |
| | 21740 | const msg = msg: { |
| | 21741 | const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{}); |
| | 21742 | errdefer msg.destroy(sema.gpa); |
| | 21743 | |
| | 21744 | try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); |
| | 21745 | try sema.addDeclaredHereNote(msg, union_ty); |
| | 21746 | break :msg msg; |
| | 21747 | }; |
| | 21748 | return sema.failWithOwnedErrorMsg(msg); |
| | 21749 | } |
| | 21750 | |
| 21685 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: { | 21751 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: { |
| 21686 | switch (union_obj.layout) { | 21752 | switch (union_obj.layout) { |
| 21687 | .Auto => if (!initializing) { | 21753 | .Auto => if (!initializing) { |
| ... | @@ -21734,6 +21800,10 @@ fn unionFieldPtr( | ... | @@ -21734,6 +21800,10 @@ fn unionFieldPtr( |
| 21734 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 21800 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 21735 | try sema.addSafetyCheck(block, ok, .inactive_union_field); | 21801 | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 21736 | } | 21802 | } |
| | 21803 | if (field.ty.zigTypeTag() == .NoReturn) { |
| | 21804 | _ = try block.addNoOp(.unreach); |
| | 21805 | return Air.Inst.Ref.unreachable_value; |
| | 21806 | } |
| 21737 | return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty); | 21807 | return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty); |
| 21738 | } | 21808 | } |
| 21739 | | 21809 | |
| ... | @@ -21802,6 +21872,10 @@ fn unionFieldVal( | ... | @@ -21802,6 +21872,10 @@ fn unionFieldVal( |
| 21802 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 21872 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 21803 | try sema.addSafetyCheck(block, ok, .inactive_union_field); | 21873 | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 21804 | } | 21874 | } |
| | 21875 | if (field.ty.zigTypeTag() == .NoReturn) { |
| | 21876 | _ = try block.addNoOp(.unreach); |
| | 21877 | return Air.Inst.Ref.unreachable_value; |
| | 21878 | } |
| 21805 | return block.addStructFieldVal(union_byval, field_index, field.ty); | 21879 | return block.addStructFieldVal(union_byval, field_index, field.ty); |
| 21806 | } | 21880 | } |
| 21807 | | 21881 | |
| ... | @@ -25002,6 +25076,18 @@ fn coerceEnumToUnion( | ... | @@ -25002,6 +25076,18 @@ fn coerceEnumToUnion( |
| 25002 | }; | 25076 | }; |
| 25003 | const field = union_obj.fields.values()[field_index]; | 25077 | const field = union_obj.fields.values()[field_index]; |
| 25004 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); | 25078 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); |
| | 25079 | if (field_ty.zigTypeTag() == .NoReturn) { |
| | 25080 | const msg = msg: { |
| | 25081 | const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{}); |
| | 25082 | errdefer msg.destroy(sema.gpa); |
| | 25083 | |
| | 25084 | const field_name = union_obj.fields.keys()[field_index]; |
| | 25085 | try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); |
| | 25086 | try sema.addDeclaredHereNote(msg, union_ty); |
| | 25087 | break :msg msg; |
| | 25088 | }; |
| | 25089 | return sema.failWithOwnedErrorMsg(msg); |
| | 25090 | } |
| 25005 | const opv = (try sema.typeHasOnePossibleValue(block, inst_src, field_ty)) orelse { | 25091 | const opv = (try sema.typeHasOnePossibleValue(block, inst_src, field_ty)) orelse { |
| 25006 | const msg = msg: { | 25092 | const msg = msg: { |
| 25007 | const field_name = union_obj.fields.keys()[field_index]; | 25093 | const field_name = union_obj.fields.keys()[field_index]; |
| ... | @@ -25037,13 +25123,37 @@ fn coerceEnumToUnion( | ... | @@ -25037,13 +25123,37 @@ fn coerceEnumToUnion( |
| 25037 | return sema.failWithOwnedErrorMsg(msg); | 25123 | return sema.failWithOwnedErrorMsg(msg); |
| 25038 | } | 25124 | } |
| 25039 | | 25125 | |
| | 25126 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| | 25127 | { |
| | 25128 | var msg: ?*Module.ErrorMsg = null; |
| | 25129 | errdefer if (msg) |some| some.destroy(sema.gpa); |
| | 25130 | |
| | 25131 | for (union_obj.fields.values()) |field, i| { |
| | 25132 | if (field.ty.zigTypeTag() == .NoReturn) { |
| | 25133 | const err_msg = msg orelse try sema.errMsg( |
| | 25134 | block, |
| | 25135 | inst_src, |
| | 25136 | "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field", |
| | 25137 | .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) }, |
| | 25138 | ); |
| | 25139 | msg = err_msg; |
| | 25140 | |
| | 25141 | try sema.addFieldErrNote(block, union_ty, i, err_msg, "'noreturn' field here", .{}); |
| | 25142 | } |
| | 25143 | } |
| | 25144 | if (msg) |some| { |
| | 25145 | msg = null; |
| | 25146 | try sema.addDeclaredHereNote(some, union_ty); |
| | 25147 | return sema.failWithOwnedErrorMsg(some); |
| | 25148 | } |
| | 25149 | } |
| | 25150 | |
| 25040 | // If the union has all fields 0 bits, the union value is just the enum value. | 25151 | // If the union has all fields 0 bits, the union value is just the enum value. |
| 25041 | if (union_ty.unionHasAllZeroBitFieldTypes()) { | 25152 | if (union_ty.unionHasAllZeroBitFieldTypes()) { |
| 25042 | return block.addBitCast(union_ty, enum_tag); | 25153 | return block.addBitCast(union_ty, enum_tag); |
| 25043 | } | 25154 | } |
| 25044 | | 25155 | |
| 25045 | const msg = msg: { | 25156 | const msg = msg: { |
| 25046 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | | |
| 25047 | const msg = try sema.errMsg( | 25157 | const msg = try sema.errMsg( |
| 25048 | block, | 25158 | block, |
| 25049 | inst_src, | 25159 | inst_src, |
| ... | @@ -25054,11 +25164,11 @@ fn coerceEnumToUnion( | ... | @@ -25054,11 +25164,11 @@ fn coerceEnumToUnion( |
| 25054 | | 25164 | |
| 25055 | var it = union_obj.fields.iterator(); | 25165 | var it = union_obj.fields.iterator(); |
| 25056 | var field_index: usize = 0; | 25166 | var field_index: usize = 0; |
| 25057 | while (it.next()) |field| { | 25167 | while (it.next()) |field| : (field_index += 1) { |
| 25058 | const field_name = field.key_ptr.*; | 25168 | const field_name = field.key_ptr.*; |
| 25059 | const field_ty = field.value_ptr.ty; | 25169 | const field_ty = field.value_ptr.ty; |
| | 25170 | if (!field_ty.hasRuntimeBits()) continue; |
| 25060 | try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) }); | 25171 | try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) }); |
| 25061 | field_index += 1; | | |
| 25062 | } | 25172 | } |
| 25063 | try sema.addDeclaredHereNote(msg, union_ty); | 25173 | try sema.addDeclaredHereNote(msg, union_ty); |
| 25064 | break :msg msg; | 25174 | break :msg msg; |
| ... | @@ -25361,6 +25471,7 @@ fn coerceTupleToStruct( | ... | @@ -25361,6 +25471,7 @@ fn coerceTupleToStruct( |
| 25361 | | 25471 | |
| 25362 | // Populate default field values and report errors for missing fields. | 25472 | // Populate default field values and report errors for missing fields. |
| 25363 | var root_msg: ?*Module.ErrorMsg = null; | 25473 | var root_msg: ?*Module.ErrorMsg = null; |
| | 25474 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 25364 | | 25475 | |
| 25365 | for (field_refs) |*field_ref, i| { | 25476 | for (field_refs) |*field_ref, i| { |
| 25366 | if (field_ref.* != .none) continue; | 25477 | if (field_ref.* != .none) continue; |
| ... | @@ -25386,6 +25497,7 @@ fn coerceTupleToStruct( | ... | @@ -25386,6 +25497,7 @@ fn coerceTupleToStruct( |
| 25386 | } | 25497 | } |
| 25387 | | 25498 | |
| 25388 | if (root_msg) |msg| { | 25499 | if (root_msg) |msg| { |
| | 25500 | root_msg = null; |
| 25389 | try sema.addDeclaredHereNote(msg, struct_ty); | 25501 | try sema.addDeclaredHereNote(msg, struct_ty); |
| 25390 | return sema.failWithOwnedErrorMsg(msg); | 25502 | return sema.failWithOwnedErrorMsg(msg); |
| 25391 | } | 25503 | } |
| ... | @@ -25455,6 +25567,7 @@ fn coerceTupleToTuple( | ... | @@ -25455,6 +25567,7 @@ fn coerceTupleToTuple( |
| 25455 | | 25567 | |
| 25456 | // Populate default field values and report errors for missing fields. | 25568 | // Populate default field values and report errors for missing fields. |
| 25457 | var root_msg: ?*Module.ErrorMsg = null; | 25569 | var root_msg: ?*Module.ErrorMsg = null; |
| | 25570 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 25458 | | 25571 | |
| 25459 | for (field_refs) |*field_ref, i| { | 25572 | for (field_refs) |*field_ref, i| { |
| 25460 | if (field_ref.* != .none) continue; | 25573 | if (field_ref.* != .none) continue; |
| ... | @@ -25490,6 +25603,7 @@ fn coerceTupleToTuple( | ... | @@ -25490,6 +25603,7 @@ fn coerceTupleToTuple( |
| 25490 | } | 25603 | } |
| 25491 | | 25604 | |
| 25492 | if (root_msg) |msg| { | 25605 | if (root_msg) |msg| { |
| | 25606 | root_msg = null; |
| 25493 | try sema.addDeclaredHereNote(msg, tuple_ty); | 25607 | try sema.addDeclaredHereNote(msg, tuple_ty); |
| 25494 | return sema.failWithOwnedErrorMsg(msg); | 25608 | return sema.failWithOwnedErrorMsg(msg); |
| 25495 | } | 25609 | } |
| ... | @@ -27914,6 +28028,18 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -27914,6 +28028,18 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 27914 | }; | 28028 | }; |
| 27915 | return sema.failWithOwnedErrorMsg(msg); | 28029 | return sema.failWithOwnedErrorMsg(msg); |
| 27916 | } | 28030 | } |
| | 28031 | if (field_ty.zigTypeTag() == .NoReturn) { |
| | 28032 | const msg = msg: { |
| | 28033 | const tree = try sema.getAstTree(&block_scope); |
| | 28034 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, i); |
| | 28035 | const msg = try sema.errMsg(&block_scope, field_src, "struct fields cannot be 'noreturn'", .{}); |
| | 28036 | errdefer msg.destroy(sema.gpa); |
| | 28037 | |
| | 28038 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 28039 | break :msg msg; |
| | 28040 | }; |
| | 28041 | return sema.failWithOwnedErrorMsg(msg); |
| | 28042 | } |
| 27917 | if (struct_obj.layout == .Extern and !sema.validateExternType(field.ty, .other)) { | 28043 | if (struct_obj.layout == .Extern and !sema.validateExternType(field.ty, .other)) { |
| 27918 | const msg = msg: { | 28044 | const msg = msg: { |
| 27919 | const tree = try sema.getAstTree(&block_scope); | 28045 | const tree = try sema.getAstTree(&block_scope); |
| ... | @@ -28725,6 +28851,16 @@ fn enumFieldSrcLoc( | ... | @@ -28725,6 +28851,16 @@ fn enumFieldSrcLoc( |
| 28725 | .container_decl_arg_trailing, | 28851 | .container_decl_arg_trailing, |
| 28726 | => tree.containerDeclArg(enum_node), | 28852 | => tree.containerDeclArg(enum_node), |
| 28727 | | 28853 | |
| | 28854 | .tagged_union, |
| | 28855 | .tagged_union_trailing, |
| | 28856 | => tree.taggedUnion(enum_node), |
| | 28857 | .tagged_union_two, |
| | 28858 | .tagged_union_two_trailing, |
| | 28859 | => tree.taggedUnionTwo(&buffer, enum_node), |
| | 28860 | .tagged_union_enum_tag, |
| | 28861 | .tagged_union_enum_tag_trailing, |
| | 28862 | => tree.taggedUnionEnumTag(enum_node), |
| | 28863 | |
| 28728 | // Container was constructed with `@Type`. | 28864 | // Container was constructed with `@Type`. |
| 28729 | else => return LazySrcLoc.nodeOffset(0), | 28865 | else => return LazySrcLoc.nodeOffset(0), |
| 28730 | }; | 28866 | }; |
| ... | @@ -29375,7 +29511,9 @@ fn unionFieldAlignment( | ... | @@ -29375,7 +29511,9 @@ fn unionFieldAlignment( |
| 29375 | src: LazySrcLoc, | 29511 | src: LazySrcLoc, |
| 29376 | field: Module.Union.Field, | 29512 | field: Module.Union.Field, |
| 29377 | ) !u32 { | 29513 | ) !u32 { |
| 29378 | if (field.abi_align == 0) { | 29514 | if (field.ty.zigTypeTag() == .NoReturn) { |
| | 29515 | return @as(u32, 0); |
| | 29516 | } else if (field.abi_align == 0) { |
| 29379 | return sema.typeAbiAlignment(block, src, field.ty); | 29517 | return sema.typeAbiAlignment(block, src, field.ty); |
| 29380 | } else { | 29518 | } else { |
| 29381 | return field.abi_align; | 29519 | return field.abi_align; |