authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-02-27 09:50:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-27 14:24:47-07:00
log71aa5084edd1d3fba5bf8db87c4cf0d03667a566
tree6437ecf24efbe2d047568960f0f939d55059d96e
parent139b731d82d0b851c8fb2e6dbb48b735e63eecd1

stage2: Resolve alignment for union field in `@TypeInfo`

This also includes two other small fixes: - Instantiate void TypeInfo fields as void - Return error in `type.comptimeOnly` on unresolved comptime requirements

3 files changed, 32 insertions(+), 23 deletions(-)

src/Sema.zig+20-11
......@@ -9903,63 +9903,63 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
99039903 type_info_ty,
99049904 try Value.Tag.@"union".create(sema.arena, .{
99059905 .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",
99079907 }),
99089908 ),
99099909 .Void => return sema.addConstant(
99109910 type_info_ty,
99119911 try Value.Tag.@"union".create(sema.arena, .{
99129912 .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",
99149914 }),
99159915 ),
99169916 .Bool => return sema.addConstant(
99179917 type_info_ty,
99189918 try Value.Tag.@"union".create(sema.arena, .{
99199919 .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",
99219921 }),
99229922 ),
99239923 .NoReturn => return sema.addConstant(
99249924 type_info_ty,
99259925 try Value.Tag.@"union".create(sema.arena, .{
99269926 .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",
99289928 }),
99299929 ),
99309930 .ComptimeFloat => return sema.addConstant(
99319931 type_info_ty,
99329932 try Value.Tag.@"union".create(sema.arena, .{
99339933 .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",
99359935 }),
99369936 ),
99379937 .ComptimeInt => return sema.addConstant(
99389938 type_info_ty,
99399939 try Value.Tag.@"union".create(sema.arena, .{
99409940 .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",
99429942 }),
99439943 ),
99449944 .Undefined => return sema.addConstant(
99459945 type_info_ty,
99469946 try Value.Tag.@"union".create(sema.arena, .{
99479947 .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",
99499949 }),
99509950 ),
99519951 .Null => return sema.addConstant(
99529952 type_info_ty,
99539953 try Value.Tag.@"union".create(sema.arena, .{
99549954 .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",
99569956 }),
99579957 ),
99589958 .EnumLiteral => return sema.addConstant(
99599959 type_info_ty,
99609960 try Value.Tag.@"union".create(sema.arena, .{
99619961 .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",
99639963 }),
99649964 ),
99659965 .Fn => {
......@@ -10380,6 +10380,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1038010380 };
1038110381
1038210382 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
1038310386 const union_fields = union_ty.unionFields();
1038410387 const union_field_vals = try fields_anon_decl.arena().alloc(Value, union_fields.count());
1038510388
......@@ -10398,13 +10401,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1039810401 };
1039910402
1040010403 const union_field_fields = try fields_anon_decl.arena().create([3]Value);
10404 const alignment = switch (layout) {
10405 .Auto, .Extern => field.normalAlignment(target),
10406 .Packed => 0,
10407 };
10408
1040110409 union_field_fields.* = .{
1040210410 // name: []const u8,
1040310411 name_val,
1040410412 // field_type: type,
1040510413 try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty),
1040610414 // 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),
1040810416 };
1040910417 field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), union_field_fields);
1041010418 }
......@@ -10435,7 +10443,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1043510443 // layout: ContainerLayout,
1043610444 try Value.Tag.enum_field_index.create(
1043710445 sema.arena,
10438 @enumToInt(union_ty.containerLayout()),
10446 @enumToInt(layout),
1043910447 ),
1044010448
1044110449 // tag_type: ?type,
......@@ -10473,6 +10481,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1047310481 break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
1047410482 };
1047510483 const struct_ty = try sema.resolveTypeFields(block, src, ty);
10484 try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout
1047610485 const layout = struct_ty.containerLayout();
1047710486
1047810487 const struct_field_vals = fv: {
src/type.zig+12-6
......@@ -1619,6 +1619,10 @@ pub const Type = extern union {
16191619
16201620 // These types have more than one possible value, so the result is the same as
16211621 // asking whether they are comptime-only types.
1622 //
1623 // If we get an error that the comptimeOnly status hasn't been
1624 // resolved yet, then we assume that there are runtime bits,
1625 // just like we do for structs below
16221626 .anyframe_T,
16231627 .optional,
16241628 .optional_single_mut_pointer,
......@@ -1632,7 +1636,7 @@ pub const Type = extern union {
16321636 .const_slice,
16331637 .mut_slice,
16341638 .pointer,
1635 => !ty.comptimeOnly(),
1639 => !(ty.comptimeOnly() catch return true),
16361640
16371641 .@"struct" => {
16381642 const struct_obj = ty.castTag(.@"struct").?.data;
......@@ -1728,7 +1732,7 @@ pub const Type = extern union {
17281732 .Inline => return false,
17291733 else => {},
17301734 }
1731 if (fn_info.return_type.comptimeOnly()) return false;
1735 if (fn_info.return_type.comptimeOnly() catch unreachable) return false;
17321736 return true;
17331737 },
17341738 else => return ty.hasRuntimeBits(),
......@@ -3610,7 +3614,7 @@ pub const Type = extern union {
36103614
36113615 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which
36123616 /// resolves field types rather than asserting they are already resolved.
3613 pub fn comptimeOnly(ty: Type) bool {
3617 pub fn comptimeOnly(ty: Type) error{StatusNotResolved}!bool {
36143618 return switch (ty.tag()) {
36153619 .u1,
36163620 .u8,
......@@ -3731,7 +3735,7 @@ pub const Type = extern union {
37313735 .tuple => {
37323736 const tuple = ty.castTag(.tuple).?.data;
37333737 for (tuple.types) |field_ty| {
3734 if (field_ty.comptimeOnly()) return true;
3738 if (try field_ty.comptimeOnly()) return true;
37353739 }
37363740 return false;
37373741 },
......@@ -3739,18 +3743,20 @@ pub const Type = extern union {
37393743 .@"struct" => {
37403744 const struct_obj = ty.castTag(.@"struct").?.data;
37413745 switch (struct_obj.requires_comptime) {
3742 .wip, .unknown => unreachable, // This function asserts types already resolved.
3746 .wip => unreachable,
37433747 .no => return false,
37443748 .yes => return true,
3749 .unknown => return error.StatusNotResolved,
37453750 }
37463751 },
37473752
37483753 .@"union", .union_tagged => {
37493754 const union_obj = ty.cast(Type.Payload.Union).?.data;
37503755 switch (union_obj.requires_comptime) {
3751 .wip, .unknown => unreachable, // This function asserts types already resolved.
3756 .wip => unreachable,
37523757 .no => return false,
37533758 .yes => return true,
3759 .unknown => return error.StatusNotResolved,
37543760 }
37553761 },
37563762
test/behavior/type_info.zig-6
......@@ -249,8 +249,6 @@ fn testEnum() !void {
249249}
250250
251251test "type info: union info" {
252 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
253
254252 try testUnion();
255253 comptime try testUnion();
256254}
......@@ -436,8 +434,6 @@ fn testAnyFrame() !void {
436434}
437435
438436test "type info: pass to function" {
439 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
440
441437 _ = passTypeInfo(@typeInfo(void));
442438 _ = comptime passTypeInfo(@typeInfo(void));
443439}
......@@ -448,8 +444,6 @@ fn passTypeInfo(comptime info: TypeInfo) type {
448444}
449445
450446test "type info: TypeId -> TypeInfo impl cast" {
451 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
452
453447 _ = passTypeInfo(TypeId.Void);
454448 _ = comptime passTypeInfo(TypeId.Void);
455449}