| ... | @@ -35614,6 +35614,12 @@ fn unionFields( | ... | @@ -35614,6 +35614,12 @@ fn unionFields( |
| 35614 | if (small.any_aligned_fields) | 35614 | if (small.any_aligned_fields) |
| 35615 | try field_aligns.ensureTotalCapacityPrecise(sema.arena, fields_len); | 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 | const bits_per_field = 4; | 35623 | const bits_per_field = 4; |
| 35618 | const fields_per_u32 = 32 / bits_per_field; | 35624 | const fields_per_u32 = 32 / bits_per_field; |
| 35619 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; | 35625 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; |
| ... | @@ -35622,6 +35628,7 @@ fn unionFields( | ... | @@ -35622,6 +35628,7 @@ fn unionFields( |
| 35622 | var cur_bit_bag: u32 = undefined; | 35628 | var cur_bit_bag: u32 = undefined; |
| 35623 | var field_i: u32 = 0; | 35629 | var field_i: u32 = 0; |
| 35624 | var last_tag_val: ?Value = null; | 35630 | var last_tag_val: ?Value = null; |
| | 35631 | const layout = union_type.flagsUnordered(ip).layout; |
| 35625 | while (field_i < fields_len) : (field_i += 1) { | 35632 | while (field_i < fields_len) : (field_i += 1) { |
| 35626 | if (field_i % fields_per_u32 == 0) { | 35633 | if (field_i % fields_per_u32 == 0) { |
| 35627 | cur_bit_bag = zir.extra[bit_bag_index]; | 35634 | cur_bit_bag = zir.extra[bit_bag_index]; |
| ... | @@ -35773,31 +35780,45 @@ fn unionFields( | ... | @@ -35773,31 +35780,45 @@ fn unionFields( |
| 35773 | }; | 35780 | }; |
| 35774 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 35781 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35775 | } | 35782 | } |
| 35776 | const layout = union_type.flagsUnordered(ip).layout; | 35783 | switch (layout) { |
| 35777 | if (layout == .@"extern" and | 35784 | .@"extern" => if (!try sema.validateExternType(field_ty, .union_field)) { |
| 35778 | !try sema.validateExternType(field_ty, .union_field)) | 35785 | const msg = msg: { |
| 35779 | { | 35786 | const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); |
| 35780 | const msg = msg: { | 35787 | errdefer msg.destroy(sema.gpa); |
| 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 | | 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); | 35791 | try sema.addDeclaredHereNote(msg, field_ty); |
| 35787 | break :msg msg; | 35792 | break :msg msg; |
| 35788 | }; | 35793 | }; |
| 35789 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 35794 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 35790 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { | 35795 | }, |
| 35791 | const msg = msg: { | 35796 | .@"packed" => { |
| 35792 | const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)}); | 35797 | if (!try sema.validatePackedType(field_ty)) { |
| 35793 | errdefer msg.destroy(sema.gpa); | 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); | 35804 | try sema.addDeclaredHereNote(msg, field_ty); |
| 35798 | break :msg msg; | 35805 | break :msg msg; |
| 35799 | }; | 35806 | }; |
| 35800 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 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 | field_types.appendAssumeCapacity(field_ty.toIntern()); | 35824 | field_types.appendAssumeCapacity(field_ty.toIntern()); |
| ... | @@ -35815,6 +35836,19 @@ fn unionFields( | ... | @@ -35815,6 +35836,19 @@ fn unionFields( |
| 35815 | union_type.setFieldTypes(ip, field_types.items); | 35836 | union_type.setFieldTypes(ip, field_types.items); |
| 35816 | union_type.setFieldAligns(ip, field_aligns.items); | 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 | if (explicit_tags_seen.len > 0) { | 35852 | if (explicit_tags_seen.len > 0) { |
| 35819 | const tag_ty = union_type.tagTypeUnordered(ip); | 35853 | const tag_ty = union_type.tagTypeUnordered(ip); |
| 35820 | const tag_info = ip.loadEnumType(tag_ty); | 35854 | const tag_info = ip.loadEnumType(tag_ty); |