authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-20 16:57:10-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-08-20 16:57:10-04:00
log776bfb0ee6ccd3c8f4b15834c3c40e5f5d731f79
tree8621a07362fc0efda75f1b33cb073157654407f3
parent1a4059ed88740c0289b7fea5735115fa9481a8e5
parent8126421d07da21f0d404ec481edfda85da0709fc
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6099 from tadeokondrak/@Type(.Struct)

Implement @Type for structs

8 files changed, 174 insertions(+), 70 deletions(-)

lib/std/builtin.zig-1
...@@ -259,7 +259,6 @@ pub const TypeInfo = union(enum) {...@@ -259,7 +259,6 @@ pub const TypeInfo = union(enum) {
259 /// therefore must be kept in sync with the compiler implementation.259 /// therefore must be kept in sync with the compiler implementation.
260 pub const StructField = struct {260 pub const StructField = struct {
261 name: []const u8,261 name: []const u8,
262 offset: ?comptime_int,
263 field_type: type,262 field_type: type,
264 default_value: anytype,263 default_value: anytype,
265 };264 };
src/all_types.hpp+1
...@@ -1420,6 +1420,7 @@ struct ZigTypeStruct {...@@ -1420,6 +1420,7 @@ struct ZigTypeStruct {
1420 bool requires_comptime;1420 bool requires_comptime;
1421 bool resolve_loop_flag_zero_bits;1421 bool resolve_loop_flag_zero_bits;
1422 bool resolve_loop_flag_other;1422 bool resolve_loop_flag_other;
1423 bool created_by_at_type;
1423};1424};
14241425
1425struct ZigTypeOptional {1426struct ZigTypeOptional {
src/analyze.cpp+5-5
...@@ -138,7 +138,7 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope...@@ -138,7 +138,7 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope
138 dest->parent = parent;138 dest->parent = parent;
139}139}
140140
141static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,141ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
142 ZigType *import, Buf *bare_name)142 ZigType *import, Buf *bare_name)
143{143{
144 ScopeDecls *scope = heap::c_allocator.create<ScopeDecls>();144 ScopeDecls *scope = heap::c_allocator.create<ScopeDecls>();
...@@ -2821,7 +2821,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2821,7 +2821,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
28212821
2822 src_assert(struct_type->data.structure.fields == nullptr, decl_node);2822 src_assert(struct_type->data.structure.fields == nullptr, decl_node);
2823 struct_type->data.structure.fields = alloc_type_struct_fields(field_count);2823 struct_type->data.structure.fields = alloc_type_struct_fields(field_count);
2824 } else if (is_anon_container(struct_type)) {2824 } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) {
2825 field_count = struct_type->data.structure.src_field_count;2825 field_count = struct_type->data.structure.src_field_count;
28262826
2827 src_assert(field_count == 0 || struct_type->data.structure.fields != nullptr, decl_node);2827 src_assert(field_count == 0 || struct_type->data.structure.fields != nullptr, decl_node);
...@@ -2856,7 +2856,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2856,7 +2856,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2856 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2856 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2857 return ErrorSemanticAnalyzeFail;2857 return ErrorSemanticAnalyzeFail;
2858 }2858 }
2859 } else if (is_anon_container(struct_type)) {2859 } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) {
2860 field_node = type_struct_field->decl_node;2860 field_node = type_struct_field->decl_node;
28612861
2862 src_assert(type_struct_field->type_entry != nullptr, field_node);2862 src_assert(type_struct_field->type_entry != nullptr, field_node);
...@@ -2883,7 +2883,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2883,7 +2883,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2883 type_struct_field->type_val = field_type_val;2883 type_struct_field->type_val = field_type_val;
2884 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)2884 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2885 return ErrorSemanticAnalyzeFail;2885 return ErrorSemanticAnalyzeFail;
2886 } else if (is_anon_container(struct_type)) {2886 } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) {
2887 field_type_val = type_struct_field->type_val;2887 field_type_val = type_struct_field->type_val;
2888 } else zig_unreachable();2888 } else zig_unreachable();
28892889
...@@ -8331,7 +8331,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8331,7 +8331,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8331 ZigLLVMDIFile *di_file;8331 ZigLLVMDIFile *di_file;
8332 ZigLLVMDIScope *di_scope;8332 ZigLLVMDIScope *di_scope;
8333 unsigned line;8333 unsigned line;
8334 if (decl_node != nullptr) {8334 if (decl_node != nullptr && !struct_type->data.structure.created_by_at_type) {
8335 Scope *scope = &struct_type->data.structure.decls_scope->base;8335 Scope *scope = &struct_type->data.structure.decls_scope->base;
8336 ZigType *import = get_scope_import(scope);8336 ZigType *import = get_scope_import(scope);
8337 di_file = import->data.structure.root_struct->di_file;8337 di_file = import->data.structure.root_struct->di_file;
src/analyze.hpp+1
...@@ -116,6 +116,7 @@ void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool...@@ -116,6 +116,7 @@ void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool
116116
117void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val);117void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val);
118118
119ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ZigType *import, Buf *bare_name);
119ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent);120ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent);
120ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent);121ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent);
121ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent);122ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
src/ir.cpp+120-50
...@@ -25678,37 +25678,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25678,37 +25678,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25678 struct_field_val->type = type_info_struct_field_type;25678 struct_field_val->type = type_info_struct_field_type;
2567925679
25680 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4);25680 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4);
25681 inner_fields[1]->special = ConstValSpecialStatic;
25682 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
25683
25684 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field);
25685 if (field_type == nullptr)
25686 return ErrorSemanticAnalyzeFail;
25687 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
25688 return err;
25689 if (!type_has_bits(ira->codegen, struct_field->type_entry)) {
25690 inner_fields[1]->data.x_optional = nullptr;
25691 } else {
25692 size_t byte_offset = struct_field->offset;
25693 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
25694 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic;
25695 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
25696 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset);
25697 }
2569825681
25699 inner_fields[2]->special = ConstValSpecialStatic;25682 inner_fields[1]->special = ConstValSpecialStatic;
25700 inner_fields[2]->type = ira->codegen->builtin_types.entry_type;25683 inner_fields[1]->type = ira->codegen->builtin_types.entry_type;
25701 inner_fields[2]->data.x_type = struct_field->type_entry;25684 inner_fields[1]->data.x_type = struct_field->type_entry;
2570225685
25703 // default_value: anytype25686 // default_value: anytype
25704 inner_fields[3]->special = ConstValSpecialStatic;25687 inner_fields[2]->special = ConstValSpecialStatic;
25705 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);25688 inner_fields[2]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
25706 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;25689 if (inner_fields[2]->type == nullptr) return ErrorSemanticAnalyzeFail;
25707 memoize_field_init_val(ira->codegen, type_entry, struct_field);25690 memoize_field_init_val(ira->codegen, type_entry, struct_field);
25708 if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){25691 if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){
25709 return ErrorSemanticAnalyzeFail;25692 return ErrorSemanticAnalyzeFail;
25710 }25693 }
25711 set_optional_payload(inner_fields[3], struct_field->init_val);25694 set_optional_payload(inner_fields[2], struct_field->init_val);
2571225695
25713 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;25696 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;
25714 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);25697 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);
...@@ -25959,6 +25942,36 @@ static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *sour...@@ -25959,6 +25942,36 @@ static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *sour
25959 return value->data.x_optional->data.x_type;25942 return value->data.x_optional->data.x_type;
25960}25943}
2596125944
25945static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value,
25946 const char *name, size_t field_index, Buf *out)
25947{
25948 ZigValue *slice = get_const_field(ira, source_node, struct_value, name, field_index);
25949 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];
25950 ZigValue *len = slice->data.x_struct.fields[slice_len_index];
25951 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
25952 assert(ptr->data.x_ptr.data.base_array.elem_index == 0);
25953 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;
25954 assert(arr->special == ConstValSpecialStatic);
25955 switch (arr->data.x_array.special) {
25956 case ConstArraySpecialUndef:
25957 return ErrorSemanticAnalyzeFail;
25958 case ConstArraySpecialNone: {
25959 buf_resize(out, 0);
25960 size_t count = bigint_as_usize(&len->data.x_bigint);
25961 for (size_t j = 0; j < count; j++) {
25962 ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j];
25963 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
25964 buf_append_char(out, ch);
25965 }
25966 break;
25967 }
25968 case ConstArraySpecialBuf:
25969 buf_init_from_buf(out, arr->data.x_array.data.s_buf);
25970 break;
25971 }
25972 return ErrorNone;
25973}
25974
25962static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) {25975static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) {
25963 Error err;25976 Error err;
25964 switch (tagTypeId) {25977 switch (tagTypeId) {
...@@ -26162,30 +26175,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26162,30 +26175,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26162 assert(error->type == ir_type_info_get_type(ira, "Error", nullptr));26175 assert(error->type == ir_type_info_get_type(ira, "Error", nullptr));
26163 ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>();26176 ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>();
26164 err_entry->decl_node = source_instr->source_node;26177 err_entry->decl_node = source_instr->source_node;
26165 ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0);26178 Error err;
26166 ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index];26179 if ((err = get_const_field_buf(ira, source_instr->source_node, error, "name", 0, &err_entry->name)))
26167 ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index];26180 return ira->codegen->invalid_inst_gen->value->type;
26168 assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
26169 assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0);
26170 ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val;
26171 assert(name_arr->special == ConstValSpecialStatic);
26172 switch (name_arr->data.x_array.special) {
26173 case ConstArraySpecialUndef:
26174 return ira->codegen->invalid_inst_gen->value->type;
26175 case ConstArraySpecialNone: {
26176 buf_resize(&err_entry->name, 0);
26177 size_t name_count = bigint_as_usize(&name_len->data.x_bigint);
26178 for (size_t j = 0; j < name_count; j++) {
26179 ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j];
26180 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
26181 buf_append_char(&err_entry->name, ch);
26182 }
26183 break;
26184 }
26185 case ConstArraySpecialBuf:
26186 buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf);
26187 break;
26188 }
26189 auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry);26181 auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry);
26190 if (existing_entry) {26182 if (existing_entry) {
26191 err_entry->value = existing_entry->value->value;26183 err_entry->value = existing_entry->value->value;
...@@ -26205,14 +26197,92 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26205,14 +26197,92 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26205 }26197 }
26206 return err_set_type;26198 return err_set_type;
26207 }26199 }
26200 case ZigTypeIdStruct: {
26201 assert(payload->special == ConstValSpecialStatic);
26202 assert(payload->type == ir_type_info_get_type(ira, "Struct", nullptr));
26203
26204 ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0);
26205 assert(layout_value->special == ConstValSpecialStatic);
26206 assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr));
26207 ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
26208
26209 ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 1);
26210 assert(fields_value->special == ConstValSpecialStatic);
26211 assert(is_slice(fields_value->type));
26212 ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index];
26213 ZigValue *fields_len_value = fields_value->data.x_struct.fields[slice_len_index];
26214 size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint);
26215
26216 ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 2);
26217 assert(decls_value->special == ConstValSpecialStatic);
26218 assert(is_slice(decls_value->type));
26219 ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
26220 size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
26221 if (decls_len != 0) {
26222 ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type"));
26223 return ira->codegen->invalid_inst_gen->value->type;
26224 }
26225
26226 bool is_tuple;
26227 get_const_field_bool(ira, source_instr->source_node, payload, "is_tuple", 3, &is_tuple);
26228
26229 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
26230 buf_init_from_buf(&entry->name,
26231 get_anon_type_name(ira->codegen, ira->old_irb.exec, "struct", source_instr->scope, source_instr->source_node, &entry->name));
26232 entry->data.structure.decl_node = source_instr->source_node;
26233 entry->data.structure.fields = alloc_type_struct_fields(fields_len);
26234 entry->data.structure.fields_by_name.init(fields_len);
26235 entry->data.structure.src_field_count = fields_len;
26236 entry->data.structure.layout = layout;
26237 entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone;
26238 entry->data.structure.created_by_at_type = true;
26239 entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, &entry->name);
26240
26241 assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
26242 assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);
26243 ZigValue *fields_arr = fields_ptr->data.x_ptr.data.base_array.array_val;
26244 assert(fields_arr->special == ConstValSpecialStatic);
26245 assert(fields_arr->data.x_array.special == ConstArraySpecialNone);
26246 for (size_t i = 0; i < fields_len; i++) {
26247 ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i];
26248 assert(field_value->type == ir_type_info_get_type(ira, "StructField", nullptr));
26249 TypeStructField *field = entry->data.structure.fields[i];
26250 field->name = buf_alloc();
26251 if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name)))
26252 return ira->codegen->invalid_inst_gen->value->type;
26253 field->decl_node = source_instr->source_node;
26254 ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1);
26255 field->type_val = type_value;
26256 field->type_entry = type_value->data.x_type;
26257 if (entry->data.structure.fields_by_name.put_unique(field->name, field) != nullptr) {
26258 ir_add_error(ira, source_instr, buf_sprintf("duplicate struct field '%s'", buf_ptr(field->name)));
26259 return ira->codegen->invalid_inst_gen->value->type;
26260 }
26261 ZigValue *default_value = get_const_field(ira, source_instr->source_node, field_value, "default_value", 2);
26262 if (default_value->type->id == ZigTypeIdNull) {
26263 field->init_val = nullptr;
26264 } else if (default_value->type->id == ZigTypeIdOptional && default_value->type->data.maybe.child_type == field->type_entry) {
26265 field->init_val = default_value->data.x_optional;
26266 } else if (default_value->type == field->type_entry) {
26267 field->init_val = default_value;
26268 } else {
26269 ir_add_error(ira, source_instr,
26270 buf_sprintf("default_value of field '%s' is of type '%s', expected '%s' or '?%s'",
26271 buf_ptr(field->name), buf_ptr(&default_value->type->name),
26272 buf_ptr(&field->type_entry->name), buf_ptr(&field->type_entry->name)));
26273 return ira->codegen->invalid_inst_gen->value->type;
26274 }
26275 }
26276
26277 return entry;
26278 }
26208 case ZigTypeIdEnum:26279 case ZigTypeIdEnum:
26280 case ZigTypeIdUnion:
26209 ir_add_error(ira, source_instr, buf_sprintf(26281 ir_add_error(ira, source_instr, buf_sprintf(
26210 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));26282 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
26211 return ira->codegen->invalid_inst_gen->value->type;26283 return ira->codegen->invalid_inst_gen->value->type;
26212 case ZigTypeIdUnion:
26213 case ZigTypeIdFn:26284 case ZigTypeIdFn:
26214 case ZigTypeIdBoundFn:26285 case ZigTypeIdBoundFn:
26215 case ZigTypeIdStruct:
26216 ir_add_error(ira, source_instr, buf_sprintf(26286 ir_add_error(ira, source_instr, buf_sprintf(
26217 "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId)));26287 "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId)));
26218 return ira->codegen->invalid_inst_gen->value->type;26288 return ira->codegen->invalid_inst_gen->value->type;
test/compile_errors.zig+3-3
...@@ -1395,12 +1395,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1395,12 +1395,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1395 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",1395 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",
1396 });1396 });
13971397
1398 cases.add("Struct unavailable for @Type",1398 cases.add("struct with declarations unavailable for @Type",
1399 \\export fn entry() void {1399 \\export fn entry() void {
1400 \\ _ = @Type(@typeInfo(struct { }));1400 \\ _ = @Type(@typeInfo(struct { const foo = 1; }));
1401 \\}1401 \\}
1402 , &[_][]const u8{1402 , &[_][]const u8{
1403 "tmp.zig:2:15: error: @Type not available for 'TypeInfo.Struct'",1403 "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type",
1404 });1404 });
14051405
1406 cases.add("wrong type for argument tuple to @asyncCall",1406 cases.add("wrong type for argument tuple to @asyncCall",
test/stage1/behavior/type.zig+44
...@@ -236,3 +236,47 @@ test "Type.ErrorSet" {...@@ -236,3 +236,47 @@ test "Type.ErrorSet" {
236 _ = @Type(@typeInfo(error{A}));236 _ = @Type(@typeInfo(error{A}));
237 _ = @Type(@typeInfo(error{ A, B, C }));237 _ = @Type(@typeInfo(error{ A, B, C }));
238}238}
239
240test "Type.Struct" {
241 const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
242 const infoA = @typeInfo(A).Struct;
243 testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout);
244 testing.expectEqualSlices(u8, "x", infoA.fields[0].name);
245 testing.expectEqual(u8, infoA.fields[0].field_type);
246 testing.expectEqual(@as(?u8, null), infoA.fields[0].default_value);
247 testing.expectEqualSlices(u8, "y", infoA.fields[1].name);
248 testing.expectEqual(u32, infoA.fields[1].field_type);
249 testing.expectEqual(@as(?u32, null), infoA.fields[1].default_value);
250 testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls);
251 testing.expectEqual(@as(bool, false), infoA.is_tuple);
252
253 var a = A{ .x = 0, .y = 1 };
254 testing.expectEqual(@as(u8, 0), a.x);
255 testing.expectEqual(@as(u32, 1), a.y);
256 a.y += 1;
257 testing.expectEqual(@as(u32, 2), a.y);
258
259 const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 }));
260 const infoB = @typeInfo(B).Struct;
261 testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout);
262 testing.expectEqualSlices(u8, "x", infoB.fields[0].name);
263 testing.expectEqual(u8, infoB.fields[0].field_type);
264 testing.expectEqual(@as(?u8, null), infoB.fields[0].default_value);
265 testing.expectEqualSlices(u8, "y", infoB.fields[1].name);
266 testing.expectEqual(u32, infoB.fields[1].field_type);
267 testing.expectEqual(@as(?u32, 5), infoB.fields[1].default_value);
268 testing.expectEqual(@as(usize, 0), infoB.decls.len);
269 testing.expectEqual(@as(bool, false), infoB.is_tuple);
270
271 const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 }));
272 const infoC = @typeInfo(C).Struct;
273 testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout);
274 testing.expectEqualSlices(u8, "x", infoC.fields[0].name);
275 testing.expectEqual(u8, infoC.fields[0].field_type);
276 testing.expectEqual(@as(?u8, 3), infoC.fields[0].default_value);
277 testing.expectEqualSlices(u8, "y", infoC.fields[1].name);
278 testing.expectEqual(u32, infoC.fields[1].field_type);
279 testing.expectEqual(@as(?u32, 5), infoC.fields[1].default_value);
280 testing.expectEqual(@as(usize, 0), infoC.decls.len);
281 testing.expectEqual(@as(bool, false), infoC.is_tuple);
282}
test/stage1/behavior/type_info.zig-11
...@@ -238,7 +238,6 @@ fn testStruct() void {...@@ -238,7 +238,6 @@ fn testStruct() void {
238 expect(struct_info == .Struct);238 expect(struct_info == .Struct);
239 expect(struct_info.Struct.layout == .Packed);239 expect(struct_info.Struct.layout == .Packed);
240 expect(struct_info.Struct.fields.len == 4);240 expect(struct_info.Struct.fields.len == 4);
241 expect(struct_info.Struct.fields[1].offset == null);
242 expect(struct_info.Struct.fields[2].field_type == *TestStruct);241 expect(struct_info.Struct.fields[2].field_type == *TestStruct);
243 expect(struct_info.Struct.fields[2].default_value == null);242 expect(struct_info.Struct.fields[2].default_value == null);
244 expect(struct_info.Struct.fields[3].default_value.? == 4);243 expect(struct_info.Struct.fields[3].default_value.? == 4);
...@@ -320,16 +319,6 @@ fn testAnyFrame() void {...@@ -320,16 +319,6 @@ fn testAnyFrame() void {
320 }319 }
321}320}
322321
323test "type info: optional field unwrapping" {
324 const Struct = struct {
325 cdOffset: u32,
326 };
327
328 const field = @typeInfo(Struct).Struct.fields[0];
329
330 _ = field.offset orelse 0;
331}
332
333test "type info: pass to function" {322test "type info: pass to function" {
334 _ = passTypeInfo(@typeInfo(void));323 _ = passTypeInfo(@typeInfo(void));
335 _ = comptime passTypeInfo(@typeInfo(void));324 _ = comptime passTypeInfo(@typeInfo(void));