| ... | @@ -9903,63 +9903,63 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -9903,63 +9903,63 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9903 | type_info_ty, | 9903 | type_info_ty, |
| 9904 | try Value.Tag.@"union".create(sema.arena, .{ | 9904 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9905 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Type)), | 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 | .Void => return sema.addConstant( | 9909 | .Void => return sema.addConstant( |
| 9910 | type_info_ty, | 9910 | type_info_ty, |
| 9911 | try Value.Tag.@"union".create(sema.arena, .{ | 9911 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9912 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Void)), | 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 | .Bool => return sema.addConstant( | 9916 | .Bool => return sema.addConstant( |
| 9917 | type_info_ty, | 9917 | type_info_ty, |
| 9918 | try Value.Tag.@"union".create(sema.arena, .{ | 9918 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9919 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Bool)), | 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 | .NoReturn => return sema.addConstant( | 9923 | .NoReturn => return sema.addConstant( |
| 9924 | type_info_ty, | 9924 | type_info_ty, |
| 9925 | try Value.Tag.@"union".create(sema.arena, .{ | 9925 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9926 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.NoReturn)), | 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 | .ComptimeFloat => return sema.addConstant( | 9930 | .ComptimeFloat => return sema.addConstant( |
| 9931 | type_info_ty, | 9931 | type_info_ty, |
| 9932 | try Value.Tag.@"union".create(sema.arena, .{ | 9932 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9933 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeFloat)), | 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 | .ComptimeInt => return sema.addConstant( | 9937 | .ComptimeInt => return sema.addConstant( |
| 9938 | type_info_ty, | 9938 | type_info_ty, |
| 9939 | try Value.Tag.@"union".create(sema.arena, .{ | 9939 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9940 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeInt)), | 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 | .Undefined => return sema.addConstant( | 9944 | .Undefined => return sema.addConstant( |
| 9945 | type_info_ty, | 9945 | type_info_ty, |
| 9946 | try Value.Tag.@"union".create(sema.arena, .{ | 9946 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9947 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Undefined)), | 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 | .Null => return sema.addConstant( | 9951 | .Null => return sema.addConstant( |
| 9952 | type_info_ty, | 9952 | type_info_ty, |
| 9953 | try Value.Tag.@"union".create(sema.arena, .{ | 9953 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9954 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Null)), | 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 | .EnumLiteral => return sema.addConstant( | 9958 | .EnumLiteral => return sema.addConstant( |
| 9959 | type_info_ty, | 9959 | type_info_ty, |
| 9960 | try Value.Tag.@"union".create(sema.arena, .{ | 9960 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9961 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.EnumLiteral)), | 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 | .Fn => { | 9965 | .Fn => { |
| ... | @@ -10380,6 +10380,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -10380,6 +10380,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10380 | }; | 10380 | }; |
| 10381 | | 10381 | |
| 10382 | const union_ty = try sema.resolveTypeFields(block, src, ty); | 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 | const union_fields = union_ty.unionFields(); | 10386 | const union_fields = union_ty.unionFields(); |
| 10384 | const union_field_vals = try fields_anon_decl.arena().alloc(Value, union_fields.count()); | 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,13 +10401,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10398 | }; | 10401 | }; |
| 10399 | | 10402 | |
| 10400 | const union_field_fields = try fields_anon_decl.arena().create([3]Value); | 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 | union_field_fields.* = .{ | 10409 | union_field_fields.* = .{ |
| 10402 | // name: []const u8, | 10410 | // name: []const u8, |
| 10403 | name_val, | 10411 | name_val, |
| 10404 | // field_type: type, | 10412 | // field_type: type, |
| 10405 | try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty), | 10413 | try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty), |
| 10406 | // alignment: comptime_int, | 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 | field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), union_field_fields); | 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,7 +10443,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10435 | // layout: ContainerLayout, | 10443 | // layout: ContainerLayout, |
| 10436 | try Value.Tag.enum_field_index.create( | 10444 | try Value.Tag.enum_field_index.create( |
| 10437 | sema.arena, | 10445 | sema.arena, |
| 10438 | @enumToInt(union_ty.containerLayout()), | 10446 | @enumToInt(layout), |
| 10439 | ), | 10447 | ), |
| 10440 | | 10448 | |
| 10441 | // tag_type: ?type, | 10449 | // tag_type: ?type, |
| ... | @@ -10473,6 +10481,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -10473,6 +10481,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10473 | break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena()); | 10481 | break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena()); |
| 10474 | }; | 10482 | }; |
| 10475 | const struct_ty = try sema.resolveTypeFields(block, src, ty); | 10483 | const struct_ty = try sema.resolveTypeFields(block, src, ty); |
| | 10484 | try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout |
| 10476 | const layout = struct_ty.containerLayout(); | 10485 | const layout = struct_ty.containerLayout(); |
| 10477 | | 10486 | |
| 10478 | const struct_field_vals = fv: { | 10487 | const struct_field_vals = fv: { |
| ... | @@ -17704,6 +17713,10 @@ fn resolveTypeLayout( | ... | @@ -17704,6 +17713,10 @@ fn resolveTypeLayout( |
| 17704 | .Optional => { | 17713 | .Optional => { |
| 17705 | var buf: Type.Payload.ElemType = undefined; | 17714 | var buf: Type.Payload.ElemType = undefined; |
| 17706 | const payload_ty = ty.optionalChild(&buf); | 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 | return sema.resolveTypeLayout(block, src, payload_ty); | 17720 | return sema.resolveTypeLayout(block, src, payload_ty); |
| 17708 | }, | 17721 | }, |
| 17709 | .ErrorUnion => { | 17722 | .ErrorUnion => { |
| ... | @@ -17735,6 +17748,13 @@ fn resolveStructLayout( | ... | @@ -17735,6 +17748,13 @@ fn resolveStructLayout( |
| 17735 | try sema.resolveTypeLayout(block, src, field.ty); | 17748 | try sema.resolveTypeLayout(block, src, field.ty); |
| 17736 | } | 17749 | } |
| 17737 | struct_obj.status = .have_layout; | 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 | // otherwise it's a tuple; no need to resolve anything | 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,6 +19308,21 @@ fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 |
| 19288 | return ty.abiAlignment(target); | 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 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. | 19326 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. |
| 19292 | pub fn fnHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { | 19327 | pub fn fnHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 19293 | const fn_info = ty.fnInfo(); | 19328 | const fn_info = ty.fnInfo(); |