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...@@ -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 };
1038110381
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());
1038510388
...@@ -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 };
1039910402
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 => field.normalAlignment(target),
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 ),
1044010448
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();
1047710486
10478 const struct_field_vals = fv: {10487 const struct_field_vals = fv: {
src/type.zig+12-6
...@@ -1619,6 +1619,10 @@ pub const Type = extern union {...@@ -1619,6 +1619,10 @@ pub const Type = extern union {
16191619
1620 // These types have more than one possible value, so the result is the same as1620 // These types have more than one possible value, so the result is the same as
1621 // asking whether they are comptime-only types.1621 // 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
1622 .anyframe_T,1626 .anyframe_T,
1623 .optional,1627 .optional,
1624 .optional_single_mut_pointer,1628 .optional_single_mut_pointer,
...@@ -1632,7 +1636,7 @@ pub const Type = extern union {...@@ -1632,7 +1636,7 @@ pub const Type = extern union {
1632 .const_slice,1636 .const_slice,
1633 .mut_slice,1637 .mut_slice,
1634 .pointer,1638 .pointer,
1635 => !ty.comptimeOnly(),1639 => !(ty.comptimeOnly() catch return true),
16361640
1637 .@"struct" => {1641 .@"struct" => {
1638 const struct_obj = ty.castTag(.@"struct").?.data;1642 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -1728,7 +1732,7 @@ pub const Type = extern union {...@@ -1728,7 +1732,7 @@ pub const Type = extern union {
1728 .Inline => return false,1732 .Inline => return false,
1729 else => {},1733 else => {},
1730 }1734 }
1731 if (fn_info.return_type.comptimeOnly()) return false;1735 if (fn_info.return_type.comptimeOnly() catch unreachable) return false;
1732 return true;1736 return true;
1733 },1737 },
1734 else => return ty.hasRuntimeBits(),1738 else => return ty.hasRuntimeBits(),
...@@ -3610,7 +3614,7 @@ pub const Type = extern union {...@@ -3610,7 +3614,7 @@ pub const Type = extern union {
36103614
3611 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which3615 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which
3612 /// resolves field types rather than asserting they are already resolved.3616 /// 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 {
3614 return switch (ty.tag()) {3618 return switch (ty.tag()) {
3615 .u1,3619 .u1,
3616 .u8,3620 .u8,
...@@ -3731,7 +3735,7 @@ pub const Type = extern union {...@@ -3731,7 +3735,7 @@ pub const Type = extern union {
3731 .tuple => {3735 .tuple => {
3732 const tuple = ty.castTag(.tuple).?.data;3736 const tuple = ty.castTag(.tuple).?.data;
3733 for (tuple.types) |field_ty| {3737 for (tuple.types) |field_ty| {
3734 if (field_ty.comptimeOnly()) return true;3738 if (try field_ty.comptimeOnly()) return true;
3735 }3739 }
3736 return false;3740 return false;
3737 },3741 },
...@@ -3739,18 +3743,20 @@ pub const Type = extern union {...@@ -3739,18 +3743,20 @@ pub const Type = extern union {
3739 .@"struct" => {3743 .@"struct" => {
3740 const struct_obj = ty.castTag(.@"struct").?.data;3744 const struct_obj = ty.castTag(.@"struct").?.data;
3741 switch (struct_obj.requires_comptime) {3745 switch (struct_obj.requires_comptime) {
3742 .wip, .unknown => unreachable, // This function asserts types already resolved.3746 .wip => unreachable,
3743 .no => return false,3747 .no => return false,
3744 .yes => return true,3748 .yes => return true,
3749 .unknown => return error.StatusNotResolved,
3745 }3750 }
3746 },3751 },
37473752
3748 .@"union", .union_tagged => {3753 .@"union", .union_tagged => {
3749 const union_obj = ty.cast(Type.Payload.Union).?.data;3754 const union_obj = ty.cast(Type.Payload.Union).?.data;
3750 switch (union_obj.requires_comptime) {3755 switch (union_obj.requires_comptime) {
3751 .wip, .unknown => unreachable, // This function asserts types already resolved.3756 .wip => unreachable,
3752 .no => return false,3757 .no => return false,
3753 .yes => return true,3758 .yes => return true,
3759 .unknown => return error.StatusNotResolved,
3754 }3760 }
3755 },3761 },
37563762
test/behavior/type_info.zig-6
...@@ -249,8 +249,6 @@ fn testEnum() !void {...@@ -249,8 +249,6 @@ fn testEnum() !void {
249}249}
250250
251test "type info: union info" {251test "type info: union info" {
252 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
253
254 try testUnion();252 try testUnion();
255 comptime try testUnion();253 comptime try testUnion();
256}254}
...@@ -436,8 +434,6 @@ fn testAnyFrame() !void {...@@ -436,8 +434,6 @@ fn testAnyFrame() !void {
436}434}
437435
438test "type info: pass to function" {436test "type info: pass to function" {
439 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
440
441 _ = passTypeInfo(@typeInfo(void));437 _ = passTypeInfo(@typeInfo(void));
442 _ = comptime passTypeInfo(@typeInfo(void));438 _ = comptime passTypeInfo(@typeInfo(void));
443}439}
...@@ -448,8 +444,6 @@ fn passTypeInfo(comptime info: TypeInfo) type {...@@ -448,8 +444,6 @@ fn passTypeInfo(comptime info: TypeInfo) type {
448}444}
449445
450test "type info: TypeId -> TypeInfo impl cast" {446test "type info: TypeId -> TypeInfo impl cast" {
451 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
452
453 _ = passTypeInfo(TypeId.Void);447 _ = passTypeInfo(TypeId.Void);
454 _ = comptime passTypeInfo(TypeId.Void);448 _ = comptime passTypeInfo(TypeId.Void);
455}449}