| ... | ... | @@ -35614,6 +35614,12 @@ fn unionFields( |
| 35614 | 35614 | if (small.any_aligned_fields) |
| 35615 | 35615 | try field_aligns.ensureTotalCapacityPrecise(sema.arena, fields_len); |
| 35616 | 35616 | |
| 35617 | var max_bits: u64 = 0; |
| 35618 | var min_bits: u64 = std.math.maxInt(u64); |
| 35619 | var max_bits_src: LazySrcLoc = undefined; |
| 35620 | var min_bits_src: LazySrcLoc = undefined; |
| 35621 | var max_bits_ty: Type = undefined; |
| 35622 | var min_bits_ty: Type = undefined; |
| 35617 | 35623 | const bits_per_field = 4; |
| 35618 | 35624 | const fields_per_u32 = 32 / bits_per_field; |
| 35619 | 35625 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; |
| ... | ... | @@ -35622,6 +35628,7 @@ fn unionFields( |
| 35622 | 35628 | var cur_bit_bag: u32 = undefined; |
| 35623 | 35629 | var field_i: u32 = 0; |
| 35624 | 35630 | var last_tag_val: ?Value = null; |
| 35631 | const layout = union_type.flagsUnordered(ip).layout; |
| 35625 | 35632 | while (field_i < fields_len) : (field_i += 1) { |
| 35626 | 35633 | if (field_i % fields_per_u32 == 0) { |
| 35627 | 35634 | cur_bit_bag = zir.extra[bit_bag_index]; |
| ... | ... | @@ -35773,31 +35780,45 @@ fn unionFields( |
| 35773 | 35780 | }; |
| 35774 | 35781 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35775 | 35782 | } |
| 35776 | | const layout = union_type.flagsUnordered(ip).layout; |
| 35777 | | if (layout == .@"extern" and |
| 35778 | | !try sema.validateExternType(field_ty, .union_field)) |
| 35779 | | { |
| 35780 | | const msg = msg: { |
| 35781 | | const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); |
| 35782 | | errdefer msg.destroy(sema.gpa); |
| 35783 | switch (layout) { |
| 35784 | .@"extern" => if (!try sema.validateExternType(field_ty, .union_field)) { |
| 35785 | const msg = msg: { |
| 35786 | const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); |
| 35787 | errdefer msg.destroy(sema.gpa); |
| 35783 | 35788 | |
| 35784 | | try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); |
| 35789 | try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); |
| 35785 | 35790 | |
| 35786 | | try sema.addDeclaredHereNote(msg, field_ty); |
| 35787 | | break :msg msg; |
| 35788 | | }; |
| 35789 | | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35790 | | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 35791 | | const msg = msg: { |
| 35792 | | const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); |
| 35793 | | errdefer msg.destroy(sema.gpa); |
| 35791 | try sema.addDeclaredHereNote(msg, field_ty); |
| 35792 | break :msg msg; |
| 35793 | }; |
| 35794 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35795 | }, |
| 35796 | .@"packed" => { |
| 35797 | if (!try sema.validatePackedType(field_ty)) { |
| 35798 | const msg = msg: { |
| 35799 | const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); |
| 35800 | errdefer msg.destroy(sema.gpa); |
| 35794 | 35801 | |
| 35795 | | try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); |
| 35802 | try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); |
| 35796 | 35803 | |
| 35797 | | try sema.addDeclaredHereNote(msg, field_ty); |
| 35798 | | break :msg msg; |
| 35799 | | }; |
| 35800 | | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35804 | try sema.addDeclaredHereNote(msg, field_ty); |
| 35805 | break :msg msg; |
| 35806 | }; |
| 35807 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35808 | } |
| 35809 | const field_bits = try field_ty.bitSizeSema(pt); |
| 35810 | if (field_bits >= max_bits) { |
| 35811 | max_bits = field_bits; |
| 35812 | max_bits_src = type_src; |
| 35813 | max_bits_ty = field_ty; |
| 35814 | } |
| 35815 | if (field_bits <= min_bits) { |
| 35816 | min_bits = field_bits; |
| 35817 | min_bits_src = type_src; |
| 35818 | min_bits_ty = field_ty; |
| 35819 | } |
| 35820 | }, |
| 35821 | .auto => {}, |
| 35801 | 35822 | } |
| 35802 | 35823 | |
| 35803 | 35824 | field_types.appendAssumeCapacity(field_ty.toIntern()); |
| ... | ... | @@ -35815,6 +35836,19 @@ fn unionFields( |
| 35815 | 35836 | union_type.setFieldTypes(ip, field_types.items); |
| 35816 | 35837 | union_type.setFieldAligns(ip, field_aligns.items); |
| 35817 | 35838 | |
| 35839 | if (layout == .@"packed" and fields_len != 0 and min_bits != max_bits) { |
| 35840 | const msg = msg: { |
| 35841 | const msg = try sema.errMsg(src, "packed union has fields with mismatching bit sizes", .{}); |
| 35842 | errdefer msg.destroy(sema.gpa); |
| 35843 | try sema.errNote(min_bits_src, msg, "{d} bits here", .{min_bits}); |
| 35844 | try sema.addDeclaredHereNote(msg, min_bits_ty); |
| 35845 | try sema.errNote(max_bits_src, msg, "{d} bits here", .{max_bits}); |
| 35846 | try sema.addDeclaredHereNote(msg, max_bits_ty); |
| 35847 | break :msg msg; |
| 35848 | }; |
| 35849 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35850 | } |
| 35851 | |
| 35818 | 35852 | if (explicit_tags_seen.len > 0) { |
| 35819 | 35853 | const tag_ty = union_type.tagTypeUnordered(ip); |
| 35820 | 35854 | const tag_info = ip.loadEnumType(tag_ty); |