mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
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
This commit is contained in:
parent
139b731d82
commit
71aa5084ed
31
src/Sema.zig
31
src/Sema.zig
@ -9903,63 +9903,63 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Type)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.Void => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Void)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.Bool => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Bool)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.NoReturn => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.NoReturn)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.ComptimeFloat => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeFloat)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.ComptimeInt => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeInt)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.Undefined => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Undefined)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.Null => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Null)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.EnumLiteral => return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.EnumLiteral)),
|
||||
.val = Value.initTag(.unreachable_value),
|
||||
.val = Value.@"void",
|
||||
}),
|
||||
),
|
||||
.Fn => {
|
||||
@ -10380,6 +10380,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
};
|
||||
|
||||
const union_ty = try sema.resolveTypeFields(block, src, ty);
|
||||
try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout
|
||||
const layout = union_ty.containerLayout();
|
||||
|
||||
const union_fields = union_ty.unionFields();
|
||||
const union_field_vals = try fields_anon_decl.arena().alloc(Value, union_fields.count());
|
||||
|
||||
@ -10398,13 +10401,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
};
|
||||
|
||||
const union_field_fields = try fields_anon_decl.arena().create([3]Value);
|
||||
const alignment = switch (layout) {
|
||||
.Auto, .Extern => field.normalAlignment(target),
|
||||
.Packed => 0,
|
||||
};
|
||||
|
||||
union_field_fields.* = .{
|
||||
// name: []const u8,
|
||||
name_val,
|
||||
// field_type: type,
|
||||
try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty),
|
||||
// alignment: comptime_int,
|
||||
try field.abi_align.copy(fields_anon_decl.arena()),
|
||||
try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),
|
||||
};
|
||||
field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), union_field_fields);
|
||||
}
|
||||
@ -10435,7 +10443,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// layout: ContainerLayout,
|
||||
try Value.Tag.enum_field_index.create(
|
||||
sema.arena,
|
||||
@enumToInt(union_ty.containerLayout()),
|
||||
@enumToInt(layout),
|
||||
),
|
||||
|
||||
// tag_type: ?type,
|
||||
@ -10473,6 +10481,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
|
||||
};
|
||||
const struct_ty = try sema.resolveTypeFields(block, src, ty);
|
||||
try sema.resolveTypeLayout(block, src, ty); // Getting alignment requires type layout
|
||||
const layout = struct_ty.containerLayout();
|
||||
|
||||
const struct_field_vals = fv: {
|
||||
|
||||
18
src/type.zig
18
src/type.zig
@ -1619,6 +1619,10 @@ pub const Type = extern union {
|
||||
|
||||
// These types have more than one possible value, so the result is the same as
|
||||
// asking whether they are comptime-only types.
|
||||
//
|
||||
// If we get an error that the comptimeOnly status hasn't been
|
||||
// resolved yet, then we assume that there are runtime bits,
|
||||
// just like we do for structs below
|
||||
.anyframe_T,
|
||||
.optional,
|
||||
.optional_single_mut_pointer,
|
||||
@ -1632,7 +1636,7 @@ pub const Type = extern union {
|
||||
.const_slice,
|
||||
.mut_slice,
|
||||
.pointer,
|
||||
=> !ty.comptimeOnly(),
|
||||
=> !(ty.comptimeOnly() catch return true),
|
||||
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
@ -1728,7 +1732,7 @@ pub const Type = extern union {
|
||||
.Inline => return false,
|
||||
else => {},
|
||||
}
|
||||
if (fn_info.return_type.comptimeOnly()) return false;
|
||||
if (fn_info.return_type.comptimeOnly() catch unreachable) return false;
|
||||
return true;
|
||||
},
|
||||
else => return ty.hasRuntimeBits(),
|
||||
@ -3610,7 +3614,7 @@ pub const Type = extern union {
|
||||
|
||||
/// During semantic analysis, instead call `Sema.typeRequiresComptime` which
|
||||
/// resolves field types rather than asserting they are already resolved.
|
||||
pub fn comptimeOnly(ty: Type) bool {
|
||||
pub fn comptimeOnly(ty: Type) error{StatusNotResolved}!bool {
|
||||
return switch (ty.tag()) {
|
||||
.u1,
|
||||
.u8,
|
||||
@ -3731,7 +3735,7 @@ pub const Type = extern union {
|
||||
.tuple => {
|
||||
const tuple = ty.castTag(.tuple).?.data;
|
||||
for (tuple.types) |field_ty| {
|
||||
if (field_ty.comptimeOnly()) return true;
|
||||
if (try field_ty.comptimeOnly()) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -3739,18 +3743,20 @@ pub const Type = extern union {
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
switch (struct_obj.requires_comptime) {
|
||||
.wip, .unknown => unreachable, // This function asserts types already resolved.
|
||||
.wip => unreachable,
|
||||
.no => return false,
|
||||
.yes => return true,
|
||||
.unknown => return error.StatusNotResolved,
|
||||
}
|
||||
},
|
||||
|
||||
.@"union", .union_tagged => {
|
||||
const union_obj = ty.cast(Type.Payload.Union).?.data;
|
||||
switch (union_obj.requires_comptime) {
|
||||
.wip, .unknown => unreachable, // This function asserts types already resolved.
|
||||
.wip => unreachable,
|
||||
.no => return false,
|
||||
.yes => return true,
|
||||
.unknown => return error.StatusNotResolved,
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -249,8 +249,6 @@ fn testEnum() !void {
|
||||
}
|
||||
|
||||
test "type info: union info" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
try testUnion();
|
||||
comptime try testUnion();
|
||||
}
|
||||
@ -436,8 +434,6 @@ fn testAnyFrame() !void {
|
||||
}
|
||||
|
||||
test "type info: pass to function" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
_ = passTypeInfo(@typeInfo(void));
|
||||
_ = comptime passTypeInfo(@typeInfo(void));
|
||||
}
|
||||
@ -448,8 +444,6 @@ fn passTypeInfo(comptime info: TypeInfo) type {
|
||||
}
|
||||
|
||||
test "type info: TypeId -> TypeInfo impl cast" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
_ = passTypeInfo(TypeId.Void);
|
||||
_ = comptime passTypeInfo(TypeId.Void);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user