From ca6db2d008cf3e0e3700e84400bd3d6e259e3c0f Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Tue, 28 Apr 2020 11:16:11 -0600 Subject: Implement @Type() for EnumLiteral and FnFrame --- lib/std/builtin.zig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/std') diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index af8033ae91..9d419f9af2 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -157,7 +157,7 @@ pub const TypeInfo = union(enum) { Fn: Fn, BoundFn: Fn, Opaque: void, - Frame: void, + Frame: Frame, AnyFrame: AnyFrame, Vector: Vector, EnumLiteral: void, @@ -315,6 +315,12 @@ pub const TypeInfo = union(enum) { args: []FnArg, }; + /// This data structure is used by the Zig language code generation and + /// therefore must be kept in sync with the compiler implementation. + pub const Frame = struct { + function: var, + }; + /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const AnyFrame = struct { -- cgit v1.2.3 From 647901b4a82dbb89656c620d4d4a89869fdf1fa0 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Thu, 30 Apr 2020 04:30:01 -0600 Subject: Constify TypeInfo --- lib/std/builtin.zig | 18 +++++++++--------- lib/std/meta.zig | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'lib/std') diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 9d419f9af2..9b0293228b 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -235,8 +235,8 @@ pub const TypeInfo = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const Struct = struct { layout: ContainerLayout, - fields: []StructField, - decls: []Declaration, + fields: []const StructField, + decls: []const Declaration, }; /// This data structure is used by the Zig language code generation and @@ -261,7 +261,7 @@ pub const TypeInfo = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const ErrorSet = ?[]Error; + pub const ErrorSet = ?[]const Error; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. @@ -275,8 +275,8 @@ pub const TypeInfo = union(enum) { pub const Enum = struct { layout: ContainerLayout, tag_type: type, - fields: []EnumField, - decls: []Declaration, + fields: []const EnumField, + decls: []const Declaration, is_exhaustive: bool, }; @@ -293,8 +293,8 @@ pub const TypeInfo = union(enum) { pub const Union = struct { layout: ContainerLayout, tag_type: ?type, - fields: []UnionField, - decls: []Declaration, + fields: []const UnionField, + decls: []const Declaration, }; /// This data structure is used by the Zig language code generation and @@ -312,7 +312,7 @@ pub const TypeInfo = union(enum) { is_generic: bool, is_var_args: bool, return_type: ?type, - args: []FnArg, + args: []const FnArg, }; /// This data structure is used by the Zig language code generation and @@ -358,7 +358,7 @@ pub const TypeInfo = union(enum) { is_export: bool, lib_name: ?[]const u8, return_type: type, - arg_names: [][]const u8, + arg_names: []const []const u8, /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. diff --git a/lib/std/meta.zig b/lib/std/meta.zig index e38712af2b..4fc74282a5 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -219,7 +219,7 @@ test "std.meta.containerLayout" { testing.expect(containerLayout(U3) == .Extern); } -pub fn declarations(comptime T: type) []TypeInfo.Declaration { +pub fn declarations(comptime T: type) []const TypeInfo.Declaration { return switch (@typeInfo(T)) { .Struct => |info| info.decls, .Enum => |info| info.decls, @@ -243,7 +243,7 @@ test "std.meta.declarations" { fn a() void {} }; - const decls = comptime [_][]TypeInfo.Declaration{ + const decls = comptime [_][]const TypeInfo.Declaration{ declarations(E1), declarations(S1), declarations(U1), @@ -292,10 +292,10 @@ test "std.meta.declarationInfo" { } pub fn fields(comptime T: type) switch (@typeInfo(T)) { - .Struct => []TypeInfo.StructField, - .Union => []TypeInfo.UnionField, - .ErrorSet => []TypeInfo.Error, - .Enum => []TypeInfo.EnumField, + .Struct => []const TypeInfo.StructField, + .Union => []const TypeInfo.UnionField, + .ErrorSet => []const TypeInfo.Error, + .Enum => []const TypeInfo.EnumField, else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), } { return switch (@typeInfo(T)) { -- cgit v1.2.3 From a62e9bc8e50296e2d5b201614a78b0e658887aa9 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Thu, 30 Apr 2020 05:50:17 -0600 Subject: Implement @Type for ErrorSet --- lib/std/builtin.zig | 1 + src/ir.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++- test/stage1/behavior/type.zig | 7 ++++ 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'lib/std') diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 9b0293228b..47fba9d095 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -256,6 +256,7 @@ pub const TypeInfo = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const Error = struct { name: []const u8, + /// This field is ignored when using @Type(). value: comptime_int, }; diff --git a/src/ir.cpp b/src/ir.cpp index 1a7c0c3527..5ba92be3c0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25456,7 +25456,79 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI ZigFn *fn = function->data.x_ptr.data.fn.fn_entry; return get_fn_frame_type(ira->codegen, fn); } - case ZigTypeIdErrorSet: + case ZigTypeIdErrorSet: { + assert(payload->special == ConstValSpecialStatic); + assert(payload->type->id == ZigTypeIdOptional); + ZigValue *slice = payload->data.x_optional; + if (slice == nullptr) + return ira->codegen->builtin_types.entry_global_error_set; + assert(slice->special == ConstValSpecialStatic); + assert(is_slice(slice->type)); + ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); + Buf bare_name = BUF_INIT; + buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->old_irb.exec, "error", source_instr->scope, source_instr->source_node, &bare_name)); + err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; + err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; + err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; + ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; + assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);; + assert(ptr->data.x_ptr.data.base_array.elem_index == 0); + ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; + assert(arr->special == ConstValSpecialStatic); + assert(arr->data.x_array.special == ConstArraySpecialNone); + ZigValue *len = slice->data.x_struct.fields[slice_len_index]; + size_t count = bigint_as_usize(&len->data.x_bigint); + err_set_type->data.error_set.err_count = count; + err_set_type->data.error_set.errors = heap::c_allocator.allocate(count); + bool *already_set = heap::c_allocator.allocate(ira->codegen->errors_by_index.length + count); + for (size_t i = 0; i < count; i++) { + ZigValue *error = &arr->data.x_array.data.s_none.elements[i]; + assert(error->type == ir_type_info_get_type(ira, "Error", nullptr)); + ErrorTableEntry *err_entry = heap::c_allocator.create(); + err_entry->decl_node = source_instr->source_node; + ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0); + ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index]; + ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index]; + assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); + assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0); + ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val; + assert(name_arr->special == ConstValSpecialStatic); + switch (name_arr->data.x_array.special) { + case ConstArraySpecialUndef: + return ira->codegen->invalid_inst_gen->value->type; + case ConstArraySpecialNone: { + buf_resize(&err_entry->name, 0); + size_t name_count = bigint_as_usize(&name_len->data.x_bigint); + for (size_t j = 0; j < name_count; j++) { + ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j]; + unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); + buf_append_char(&err_entry->name, ch); + } + break; + } + case ConstArraySpecialBuf: + buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf); + break; + } + auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry); + if (existing_entry) { + err_entry->value = existing_entry->value->value; + } else { + size_t error_value_count = ira->codegen->errors_by_index.length; + assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); + err_entry->value = error_value_count; + ira->codegen->errors_by_index.append(err_entry); + } + if (already_set[err_entry->value]) { + ir_add_error(ira, source_instr, buf_sprintf("duplicate error: %s", buf_ptr(&err_entry->name))); + return ira->codegen->invalid_inst_gen->value->type; + } else { + already_set[err_entry->value] = true; + } + err_set_type->data.error_set.errors[i] = err_entry; + } + return err_set_type; + } case ZigTypeIdEnum: ir_add_error(ira, source_instr, buf_sprintf( "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); diff --git a/test/stage1/behavior/type.zig b/test/stage1/behavior/type.zig index d8ed633887..f21e9f1ce9 100644 --- a/test/stage1/behavior/type.zig +++ b/test/stage1/behavior/type.zig @@ -229,3 +229,10 @@ test "Type.Frame" { @Frame(add), }); } + +test "Type.ErrorSet" { + // error sets don't compare equal so just check if they compile + _ = @Type(@typeInfo(error{})); + _ = @Type(@typeInfo(error{A})); + _ = @Type(@typeInfo(error{ A, B, C })); +} -- cgit v1.2.3