| ... | ... | @@ -9903,63 +9903,63 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9903 | 9903 | type_info_ty, |
| 9904 | 9904 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9905 | 9905 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Type)), |
| 9906 | | .val = Value.initTag(.unreachable_value), |
| 9906 | .val = Value.@"void", |
| 9907 | 9907 | }), |
| 9908 | 9908 | ), |
| 9909 | 9909 | .Void => return sema.addConstant( |
| 9910 | 9910 | type_info_ty, |
| 9911 | 9911 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9912 | 9912 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Void)), |
| 9913 | | .val = Value.initTag(.unreachable_value), |
| 9913 | .val = Value.@"void", |
| 9914 | 9914 | }), |
| 9915 | 9915 | ), |
| 9916 | 9916 | .Bool => return sema.addConstant( |
| 9917 | 9917 | type_info_ty, |
| 9918 | 9918 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9919 | 9919 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Bool)), |
| 9920 | | .val = Value.initTag(.unreachable_value), |
| 9920 | .val = Value.@"void", |
| 9921 | 9921 | }), |
| 9922 | 9922 | ), |
| 9923 | 9923 | .NoReturn => return sema.addConstant( |
| 9924 | 9924 | type_info_ty, |
| 9925 | 9925 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9926 | 9926 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.NoReturn)), |
| 9927 | | .val = Value.initTag(.unreachable_value), |
| 9927 | .val = Value.@"void", |
| 9928 | 9928 | }), |
| 9929 | 9929 | ), |
| 9930 | 9930 | .ComptimeFloat => return sema.addConstant( |
| 9931 | 9931 | type_info_ty, |
| 9932 | 9932 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9933 | 9933 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeFloat)), |
| 9934 | | .val = Value.initTag(.unreachable_value), |
| 9934 | .val = Value.@"void", |
| 9935 | 9935 | }), |
| 9936 | 9936 | ), |
| 9937 | 9937 | .ComptimeInt => return sema.addConstant( |
| 9938 | 9938 | type_info_ty, |
| 9939 | 9939 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9940 | 9940 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeInt)), |
| 9941 | | .val = Value.initTag(.unreachable_value), |
| 9941 | .val = Value.@"void", |
| 9942 | 9942 | }), |
| 9943 | 9943 | ), |
| 9944 | 9944 | .Undefined => return sema.addConstant( |
| 9945 | 9945 | type_info_ty, |
| 9946 | 9946 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9947 | 9947 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Undefined)), |
| 9948 | | .val = Value.initTag(.unreachable_value), |
| 9948 | .val = Value.@"void", |
| 9949 | 9949 | }), |
| 9950 | 9950 | ), |
| 9951 | 9951 | .Null => return sema.addConstant( |
| 9952 | 9952 | type_info_ty, |
| 9953 | 9953 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9954 | 9954 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Null)), |
| 9955 | | .val = Value.initTag(.unreachable_value), |
| 9955 | .val = Value.@"void", |
| 9956 | 9956 | }), |
| 9957 | 9957 | ), |
| 9958 | 9958 | .EnumLiteral => return sema.addConstant( |
| 9959 | 9959 | type_info_ty, |
| 9960 | 9960 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9961 | 9961 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.EnumLiteral)), |
| 9962 | | .val = Value.initTag(.unreachable_value), |
| 9962 | .val = Value.@"void", |
| 9963 | 9963 | }), |
| 9964 | 9964 | ), |
| 9965 | 9965 | .Fn => { |
| ... | ... | @@ -10380,6 +10380,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10380 | 10380 | }; |
| 10381 | 10381 | |
| 10382 | 10382 | const union_ty = try sema.resolveTypeFields(block, src, ty); |
| 10383 | try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout |
| 10384 | const layout = union_ty.containerLayout(); |
| 10385 | |
| 10383 | 10386 | const union_fields = union_ty.unionFields(); |
| 10384 | 10387 | const union_field_vals = try fields_anon_decl.arena().alloc(Value, union_fields.count()); |
| 10385 | 10388 | |
| ... | ... | @@ -10398,13 +10401,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10398 | 10401 | }; |
| 10399 | 10402 | |
| 10400 | 10403 | const union_field_fields = try fields_anon_decl.arena().create([3]Value); |
| 10404 | const alignment = switch (layout) { |
| 10405 | .Auto, .Extern => try sema.unionFieldAlignment(block, src, field), |
| 10406 | .Packed => 0, |
| 10407 | }; |
| 10408 | |
| 10401 | 10409 | union_field_fields.* = .{ |
| 10402 | 10410 | // name: []const u8, |
| 10403 | 10411 | name_val, |
| 10404 | 10412 | // field_type: type, |
| 10405 | 10413 | try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty), |
| 10406 | 10414 | // alignment: comptime_int, |
| 10407 | | try field.abi_align.copy(fields_anon_decl.arena()), |
| 10415 | try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), |
| 10408 | 10416 | }; |
| 10409 | 10417 | field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), union_field_fields); |
| 10410 | 10418 | } |
| ... | ... | @@ -10435,7 +10443,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10435 | 10443 | // layout: ContainerLayout, |
| 10436 | 10444 | try Value.Tag.enum_field_index.create( |
| 10437 | 10445 | sema.arena, |
| 10438 | | @enumToInt(union_ty.containerLayout()), |
| 10446 | @enumToInt(layout), |
| 10439 | 10447 | ), |
| 10440 | 10448 | |
| 10441 | 10449 | // tag_type: ?type, |
| ... | ... | @@ -10473,6 +10481,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10473 | 10481 | break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena()); |
| 10474 | 10482 | }; |
| 10475 | 10483 | const struct_ty = try sema.resolveTypeFields(block, src, ty); |
| 10484 | try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout |
| 10476 | 10485 | const layout = struct_ty.containerLayout(); |
| 10477 | 10486 | |
| 10478 | 10487 | const struct_field_vals = fv: { |
| ... | ... | @@ -17704,6 +17713,10 @@ fn resolveTypeLayout( |
| 17704 | 17713 | .Optional => { |
| 17705 | 17714 | var buf: Type.Payload.ElemType = undefined; |
| 17706 | 17715 | const payload_ty = ty.optionalChild(&buf); |
| 17716 | // In case of querying the ABI alignment of this optional, we will ask |
| 17717 | // for hasRuntimeBits() of the payload type, so we need "requires comptime" |
| 17718 | // to be known already before this function returns. |
| 17719 | _ = try sema.typeRequiresComptime(block, src, payload_ty); |
| 17707 | 17720 | return sema.resolveTypeLayout(block, src, payload_ty); |
| 17708 | 17721 | }, |
| 17709 | 17722 | .ErrorUnion => { |
| ... | ... | @@ -17735,6 +17748,13 @@ fn resolveStructLayout( |
| 17735 | 17748 | try sema.resolveTypeLayout(block, src, field.ty); |
| 17736 | 17749 | } |
| 17737 | 17750 | struct_obj.status = .have_layout; |
| 17751 | |
| 17752 | // In case of querying the ABI alignment of this struct, we will ask |
| 17753 | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| 17754 | // to be known already before this function returns. |
| 17755 | for (struct_obj.fields.values()) |field| { |
| 17756 | _ = try sema.typeRequiresComptime(block, src, field.ty); |
| 17757 | } |
| 17738 | 17758 | } |
| 17739 | 17759 | // otherwise it's a tuple; no need to resolve anything |
| 17740 | 17760 | } |
| ... | ... | @@ -19288,6 +19308,21 @@ fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 |
| 19288 | 19308 | return ty.abiAlignment(target); |
| 19289 | 19309 | } |
| 19290 | 19310 | |
| 19311 | /// Not valid to call for packed unions. |
| 19312 | /// Keep implementation in sync with `Module.Union.Field.normalAlignment`. |
| 19313 | fn unionFieldAlignment( |
| 19314 | sema: *Sema, |
| 19315 | block: *Block, |
| 19316 | src: LazySrcLoc, |
| 19317 | field: Module.Union.Field, |
| 19318 | ) !u32 { |
| 19319 | if (field.abi_align.tag() == .abi_align_default) { |
| 19320 | return sema.typeAbiAlignment(block, src, field.ty); |
| 19321 | } else { |
| 19322 | return @intCast(u32, field.abi_align.toUnsignedInt()); |
| 19323 | } |
| 19324 | } |
| 19325 | |
| 19291 | 19326 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. |
| 19292 | 19327 | pub fn fnHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 19293 | 19328 | const fn_info = ty.fnInfo(); |