authorgravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-04-30 05:50:17-06:00
committergravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-05-02 14:39:32-06:00
loga62e9bc8e50296e2d5b201614a78b0e658887aa9
tree83ec2f2583af3b60ac155ca1fb36c7aeaf419bfa
parent647901b4a82dbb89656c620d4d4a89869fdf1fa0
signaturelock-open Commit is signed but in an unrecognized format.

Implement @Type for ErrorSet


3 files changed, 81 insertions(+), 1 deletions(-)

lib/std/builtin.zig+1
...@@ -256,6 +256,7 @@ pub const TypeInfo = union(enum) {...@@ -256,6 +256,7 @@ pub const TypeInfo = union(enum) {
256 /// therefore must be kept in sync with the compiler implementation.256 /// therefore must be kept in sync with the compiler implementation.
257 pub const Error = struct {257 pub const Error = struct {
258 name: []const u8,258 name: []const u8,
259 /// This field is ignored when using @Type().
259 value: comptime_int,260 value: comptime_int,
260 };261 };
261262
src/ir.cpp+73-1
...@@ -25456,7 +25456,79 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -25456,7 +25456,79 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
25456 ZigFn *fn = function->data.x_ptr.data.fn.fn_entry;25456 ZigFn *fn = function->data.x_ptr.data.fn.fn_entry;
25457 return get_fn_frame_type(ira->codegen, fn);25457 return get_fn_frame_type(ira->codegen, fn);
25458 }25458 }
25459 case ZigTypeIdErrorSet:25459 case ZigTypeIdErrorSet: {
25460 assert(payload->special == ConstValSpecialStatic);
25461 assert(payload->type->id == ZigTypeIdOptional);
25462 ZigValue *slice = payload->data.x_optional;
25463 if (slice == nullptr)
25464 return ira->codegen->builtin_types.entry_global_error_set;
25465 assert(slice->special == ConstValSpecialStatic);
25466 assert(is_slice(slice->type));
25467 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
25468 Buf bare_name = BUF_INIT;
25469 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));
25470 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
25471 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
25472 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;
25473 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];
25474 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);;
25475 assert(ptr->data.x_ptr.data.base_array.elem_index == 0);
25476 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;
25477 assert(arr->special == ConstValSpecialStatic);
25478 assert(arr->data.x_array.special == ConstArraySpecialNone);
25479 ZigValue *len = slice->data.x_struct.fields[slice_len_index];
25480 size_t count = bigint_as_usize(&len->data.x_bigint);
25481 err_set_type->data.error_set.err_count = count;
25482 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count);
25483 bool *already_set = heap::c_allocator.allocate<bool>(ira->codegen->errors_by_index.length + count);
25484 for (size_t i = 0; i < count; i++) {
25485 ZigValue *error = &arr->data.x_array.data.s_none.elements[i];
25486 assert(error->type == ir_type_info_get_type(ira, "Error", nullptr));
25487 ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>();
25488 err_entry->decl_node = source_instr->source_node;
25489 ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0);
25490 ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index];
25491 ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index];
25492 assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
25493 assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0);
25494 ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val;
25495 assert(name_arr->special == ConstValSpecialStatic);
25496 switch (name_arr->data.x_array.special) {
25497 case ConstArraySpecialUndef:
25498 return ira->codegen->invalid_inst_gen->value->type;
25499 case ConstArraySpecialNone: {
25500 buf_resize(&err_entry->name, 0);
25501 size_t name_count = bigint_as_usize(&name_len->data.x_bigint);
25502 for (size_t j = 0; j < name_count; j++) {
25503 ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j];
25504 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
25505 buf_append_char(&err_entry->name, ch);
25506 }
25507 break;
25508 }
25509 case ConstArraySpecialBuf:
25510 buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf);
25511 break;
25512 }
25513 auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry);
25514 if (existing_entry) {
25515 err_entry->value = existing_entry->value->value;
25516 } else {
25517 size_t error_value_count = ira->codegen->errors_by_index.length;
25518 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count));
25519 err_entry->value = error_value_count;
25520 ira->codegen->errors_by_index.append(err_entry);
25521 }
25522 if (already_set[err_entry->value]) {
25523 ir_add_error(ira, source_instr, buf_sprintf("duplicate error: %s", buf_ptr(&err_entry->name)));
25524 return ira->codegen->invalid_inst_gen->value->type;
25525 } else {
25526 already_set[err_entry->value] = true;
25527 }
25528 err_set_type->data.error_set.errors[i] = err_entry;
25529 }
25530 return err_set_type;
25531 }
25460 case ZigTypeIdEnum:25532 case ZigTypeIdEnum:
25461 ir_add_error(ira, source_instr, buf_sprintf(25533 ir_add_error(ira, source_instr, buf_sprintf(
25462 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));25534 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
test/stage1/behavior/type.zig+7
...@@ -229,3 +229,10 @@ test "Type.Frame" {...@@ -229,3 +229,10 @@ test "Type.Frame" {
229 @Frame(add),229 @Frame(add),
230 });230 });
231}231}
232
233test "Type.ErrorSet" {
234 // error sets don't compare equal so just check if they compile
235 _ = @Type(@typeInfo(error{}));
236 _ = @Type(@typeInfo(error{A}));
237 _ = @Type(@typeInfo(error{ A, B, C }));
238}