| ... | ... | @@ -347,6 +347,12 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { |
| 347 | 347 | } |
| 348 | 348 | }; |
| 349 | 349 | |
| 350 | switch (struct_obj.layout) { |
| 351 | .auto => {}, |
| 352 | .@"extern" => assert(class != .no_possible_value), // field types are all extern, so are not NPV |
| 353 | .@"packed" => unreachable, |
| 354 | } |
| 355 | |
| 350 | 356 | if (struct_obj.layout == .auto) { |
| 351 | 357 | const runtime_order = struct_obj.field_runtime_order.get(ip); |
| 352 | 358 | // This logic does not reorder fields; it only moves the omitted ones to the end so that logic |
| ... | ... | @@ -451,7 +457,12 @@ fn resolvePackedStructLayout( |
| 451 | 457 | try sema.addDeclaredHereNote(msg, field_ty); |
| 452 | 458 | break :msg msg; |
| 453 | 459 | }); |
| 454 | | assert(!field_ty.comptimeOnly(zcu)); // packable types are not comptime-only |
| 460 | switch (field_ty.classify(zcu)) { |
| 461 | .one_possible_value, .runtime => {}, |
| 462 | .no_possible_value => unreachable, // packable types are not NPV |
| 463 | .partially_comptime => unreachable, // packable types are not comptime-only |
| 464 | .fully_comptime => unreachable, // packable types are not comptime-only |
| 465 | } |
| 455 | 466 | field_bits += field_ty.bitSize(zcu); |
| 456 | 467 | } |
| 457 | 468 | |
| ... | ... | @@ -749,6 +760,13 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void { |
| 749 | 760 | } |
| 750 | 761 | } |
| 751 | 762 | |
| 763 | // Uninstantiable `extern union`s don't make sense; disallow them. |
| 764 | if (possible_tags == 0 and union_obj.layout != .auto) { |
| 765 | // Field types are all extern, so not NPV; thus zero possible tags means no tags at all. |
| 766 | assert(union_obj.field_types.len == 0); |
| 767 | return sema.fail(&block, union_ty.srcLoc(zcu), "extern union has no fields", .{}); |
| 768 | } |
| 769 | |
| 752 | 770 | // We only need a runtime tag if there are multiple possible active fields *and* the union is |
| 753 | 771 | // not going to be comptime-only. Even if there are still runtime bits in the payload, the tag |
| 754 | 772 | // does not require runtime bits in a comptime-only union, because it is impossible to get a |
| ... | ... | @@ -874,6 +892,11 @@ fn resolvePackedUnionLayout( |
| 874 | 892 | const gpa = comp.gpa; |
| 875 | 893 | const ip = &zcu.intern_pool; |
| 876 | 894 | |
| 895 | // Uninstantiable `packed union`s don't make sense; disallow them. |
| 896 | if (union_obj.field_types.len == 0) { |
| 897 | return sema.fail(block, union_ty.srcLoc(zcu), "packed union has no fields", .{}); |
| 898 | } |
| 899 | |
| 877 | 900 | // Resolve the layout of all fields, and check their types are allowed. |
| 878 | 901 | for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| { |
| 879 | 902 | const field_ty: Type = .fromInterned(field_ty_ip); |
| ... | ... | @@ -937,9 +960,6 @@ fn resolvePackedUnionLayout( |
| 937 | 960 | }); |
| 938 | 961 | } |
| 939 | 962 | break :ty backing_ty; |
| 940 | | } else if (union_obj.field_types.len == 0) ty: { |
| 941 | | // Special case: there is no first field to infer the type from. Treat the union as empty (zero-bit). |
| 942 | | break :ty .u0; |
| 943 | 963 | } else ty: { |
| 944 | 964 | const field_types = union_obj.field_types.get(ip); |
| 945 | 965 | const first_field_type: Type = .fromInterned(field_types[0]); |