authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 17:50:41-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 17:50:41-05:00
logca2a788a240bbc3fa8060471bcda845e543dac70
tree2a6d173cf7a90e20ad5bce72ca099307265c1d29
parent1bca8e693d42256d575c76fbab5c68d86c0c4bc3
signaturelock-open Commit is signed but in an unrecognized format.

fully anonymous struct literals


5 files changed, 271 insertions(+), 63 deletions(-)

src/all_types.hpp+13
...@@ -1187,10 +1187,22 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);...@@ -1187,10 +1187,22 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
1187static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;1187static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;
1188static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;1188static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;
11891189
1190struct InferredStructField {
1191 ZigType *inferred_struct_type;
1192 Buf *field_name;
1193};
1194
1190struct ZigTypePointer {1195struct ZigTypePointer {
1191 ZigType *child_type;1196 ZigType *child_type;
1192 ZigType *slice_parent;1197 ZigType *slice_parent;
11931198
1199 // Anonymous struct literal syntax uses this when the result location has
1200 // no type in it. This field is null if this pointer does not refer to
1201 // a field of a currently-being-inferred struct type.
1202 // When this is non-null, the pointer is pointing to the base of the inferred
1203 // struct.
1204 InferredStructField *inferred_struct_field;
1205
1194 PtrLen ptr_len;1206 PtrLen ptr_len;
1195 uint32_t explicit_alignment; // 0 means use ABI alignment1207 uint32_t explicit_alignment; // 0 means use ABI alignment
11961208
...@@ -1743,6 +1755,7 @@ struct TypeId {...@@ -1743,6 +1755,7 @@ struct TypeId {
1743 union {1755 union {
1744 struct {1756 struct {
1745 ZigType *child_type;1757 ZigType *child_type;
1758 InferredStructField *inferred_struct_field;
1746 PtrLen ptr_len;1759 PtrLen ptr_len;
1747 uint32_t alignment;1760 uint32_t alignment;
17481761
src/analyze.cpp+92-41
...@@ -486,7 +486,7 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {...@@ -486,7 +486,7 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {
486ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,486ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,
487 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,487 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
488 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,488 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,
489 uint32_t vector_index)489 uint32_t vector_index, InferredStructField *inferred_struct_field)
490{490{
491 assert(ptr_len != PtrLenC || allow_zero);491 assert(ptr_len != PtrLenC || allow_zero);
492 assert(!type_is_invalid(child_type));492 assert(!type_is_invalid(child_type));
...@@ -509,7 +509,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -509,7 +509,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
509 TypeId type_id = {};509 TypeId type_id = {};
510 ZigType **parent_pointer = nullptr;510 ZigType **parent_pointer = nullptr;
511 if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||511 if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
512 allow_zero || vector_index != VECTOR_INDEX_NONE)512 allow_zero || vector_index != VECTOR_INDEX_NONE || inferred_struct_field != nullptr)
513 {513 {
514 type_id.id = ZigTypeIdPointer;514 type_id.id = ZigTypeIdPointer;
515 type_id.data.pointer.child_type = child_type;515 type_id.data.pointer.child_type = child_type;
...@@ -521,6 +521,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -521,6 +521,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
521 type_id.data.pointer.ptr_len = ptr_len;521 type_id.data.pointer.ptr_len = ptr_len;
522 type_id.data.pointer.allow_zero = allow_zero;522 type_id.data.pointer.allow_zero = allow_zero;
523 type_id.data.pointer.vector_index = vector_index;523 type_id.data.pointer.vector_index = vector_index;
524 type_id.data.pointer.inferred_struct_field = inferred_struct_field;
524525
525 auto existing_entry = g->type_table.maybe_get(type_id);526 auto existing_entry = g->type_table.maybe_get(type_id);
526 if (existing_entry)527 if (existing_entry)
...@@ -548,8 +549,15 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -548,8 +549,15 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
548 }549 }
549 buf_resize(&entry->name, 0);550 buf_resize(&entry->name, 0);
550 if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {551 if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {
551 buf_appendf(&entry->name, "%s%s%s%s%s",552 if (inferred_struct_field == nullptr) {
552 star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));553 buf_appendf(&entry->name, "%s%s%s%s%s",
554 star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
555 } else {
556 buf_appendf(&entry->name, "(%s%s%s%s field '%s' of %s)",
557 star_str, const_str, volatile_str, allow_zero_str,
558 buf_ptr(inferred_struct_field->field_name),
559 buf_ptr(&inferred_struct_field->inferred_struct_type->name));
560 }
553 } else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {561 } else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {
554 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,562 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
555 const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));563 const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
...@@ -606,6 +614,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -606,6 +614,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
606 entry->data.pointer.host_int_bytes = host_int_bytes;614 entry->data.pointer.host_int_bytes = host_int_bytes;
607 entry->data.pointer.allow_zero = allow_zero;615 entry->data.pointer.allow_zero = allow_zero;
608 entry->data.pointer.vector_index = vector_index;616 entry->data.pointer.vector_index = vector_index;
617 entry->data.pointer.inferred_struct_field = inferred_struct_field;
609618
610 if (parent_pointer) {619 if (parent_pointer) {
611 *parent_pointer = entry;620 *parent_pointer = entry;
...@@ -620,12 +629,12 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -620,12 +629,12 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
620 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)629 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
621{630{
622 return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,631 return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,
623 byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE);632 byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE, nullptr);
624}633}
625634
626ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {635ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
627 return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,636 return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,
628 VECTOR_INDEX_NONE);637 VECTOR_INDEX_NONE, nullptr);
629}638}
630639
631ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {640ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
...@@ -2082,7 +2091,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2082,7 +2091,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2082 }2091 }
20832092
2084 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);2093 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
2085 assert(decl_node->type == NodeTypeContainerDecl);2094 assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
20862095
2087 size_t field_count = struct_type->data.structure.src_field_count;2096 size_t field_count = struct_type->data.structure.src_field_count;
20882097
...@@ -2670,7 +2679,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2670,7 +2679,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2670 return ErrorNone;2679 return ErrorNone;
26712680
2672 AstNode *decl_node = struct_type->data.structure.decl_node;2681 AstNode *decl_node = struct_type->data.structure.decl_node;
2673 assert(decl_node->type == NodeTypeContainerDecl);
26742682
2675 if (struct_type->data.structure.resolve_loop_flag_zero_bits) {2683 if (struct_type->data.structure.resolve_loop_flag_zero_bits) {
2676 if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {2684 if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
...@@ -2681,29 +2689,46 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2681,29 +2689,46 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2681 }2689 }
2682 return ErrorSemanticAnalyzeFail;2690 return ErrorSemanticAnalyzeFail;
2683 }2691 }
2684
2685 struct_type->data.structure.resolve_loop_flag_zero_bits = true;2692 struct_type->data.structure.resolve_loop_flag_zero_bits = true;
26862693
2687 assert(!struct_type->data.structure.fields);2694 size_t field_count;
2688 size_t field_count = decl_node->data.container_decl.fields.length;2695 if (decl_node->type == NodeTypeContainerDecl) {
2689 struct_type->data.structure.src_field_count = (uint32_t)field_count;2696 field_count = decl_node->data.container_decl.fields.length;
2690 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);2697 struct_type->data.structure.src_field_count = (uint32_t)field_count;
2698
2699 src_assert(struct_type->data.structure.fields == nullptr, decl_node);
2700 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
2701 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2702 src_assert(struct_type->data.structure.is_inferred, decl_node);
2703 src_assert(struct_type->data.structure.fields != nullptr, decl_node);
2704
2705 field_count = struct_type->data.structure.src_field_count;
2706 } else zig_unreachable();
2707
2691 struct_type->data.structure.fields_by_name.init(field_count);2708 struct_type->data.structure.fields_by_name.init(field_count);
26922709
2693 Scope *scope = &struct_type->data.structure.decls_scope->base;2710 Scope *scope = &struct_type->data.structure.decls_scope->base;
26942711
2695 size_t gen_field_index = 0;2712 size_t gen_field_index = 0;
2696 for (size_t i = 0; i < field_count; i += 1) {2713 for (size_t i = 0; i < field_count; i += 1) {
2697 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
2698 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];2714 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
2699 type_struct_field->name = field_node->data.struct_field.name;
2700 type_struct_field->decl_node = field_node;
27012715
2702 if (field_node->data.struct_field.type == nullptr) {2716 AstNode *field_node;
2703 add_node_error(g, field_node, buf_sprintf("struct field missing type"));2717 if (decl_node->type == NodeTypeContainerDecl) {
2704 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2718 field_node = decl_node->data.container_decl.fields.at(i);
2705 return ErrorSemanticAnalyzeFail;2719 type_struct_field->name = field_node->data.struct_field.name;
2706 }2720 type_struct_field->decl_node = field_node;
2721
2722 if (field_node->data.struct_field.type == nullptr) {
2723 add_node_error(g, field_node, buf_sprintf("struct field missing type"));
2724 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2725 return ErrorSemanticAnalyzeFail;
2726 }
2727 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2728 field_node = type_struct_field->decl_node;
2729
2730 src_assert(type_struct_field->type_entry != nullptr, field_node);
2731 } else zig_unreachable();
27072732
2708 auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);2733 auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);
2709 if (field_entry != nullptr) {2734 if (field_entry != nullptr) {
...@@ -2714,16 +2739,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2714,16 +2739,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2714 return ErrorSemanticAnalyzeFail;2739 return ErrorSemanticAnalyzeFail;
2715 }2740 }
27162741
2717 ConstExprValue *field_type_val = analyze_const_value(g, scope,2742 ConstExprValue *field_type_val;
2718 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);2743 if (decl_node->type == NodeTypeContainerDecl) {
2719 if (type_is_invalid(field_type_val->type)) {2744 field_type_val = analyze_const_value(g, scope,
2720 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2745 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
2721 return ErrorSemanticAnalyzeFail;2746 if (type_is_invalid(field_type_val->type)) {
2722 }2747 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2723 assert(field_type_val->special != ConstValSpecialRuntime);2748 return ErrorSemanticAnalyzeFail;
2724 type_struct_field->type_val = field_type_val;2749 }
2725 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)2750 assert(field_type_val->special != ConstValSpecialRuntime);
2726 return ErrorSemanticAnalyzeFail;2751 type_struct_field->type_val = field_type_val;
2752 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2753 return ErrorSemanticAnalyzeFail;
2754 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2755 field_type_val = type_struct_field->type_val;
2756 } else zig_unreachable();
27272757
2728 bool field_is_opaque_type;2758 bool field_is_opaque_type;
2729 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {2759 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
...@@ -2807,7 +2837,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2807,7 +2837,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2807 }2837 }
28082838
2809 struct_type->data.structure.resolve_loop_flag_other = true;2839 struct_type->data.structure.resolve_loop_flag_other = true;
2810 assert(decl_node->type == NodeTypeContainerDecl);2840 assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
28112841
2812 size_t field_count = struct_type->data.structure.src_field_count;2842 size_t field_count = struct_type->data.structure.src_field_count;
2813 bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;2843 bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;
...@@ -2817,7 +2847,8 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2817,7 +2847,8 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2817 if (field->gen_index == SIZE_MAX)2847 if (field->gen_index == SIZE_MAX)
2818 continue;2848 continue;
28192849
2820 AstNode *align_expr = field->decl_node->data.struct_field.align_expr;2850 AstNode *align_expr = (field->decl_node->type == NodeTypeStructField) ?
2851 field->decl_node->data.struct_field.align_expr : nullptr;
2821 if (align_expr != nullptr) {2852 if (align_expr != nullptr) {
2822 if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,2853 if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,
2823 &field->align))2854 &field->align))
...@@ -5416,6 +5447,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -5416,6 +5447,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5416 if (type_entry->one_possible_value != OnePossibleValueInvalid)5447 if (type_entry->one_possible_value != OnePossibleValueInvalid)
5417 return type_entry->one_possible_value;5448 return type_entry->one_possible_value;
54185449
5450 if (type_entry->id == ZigTypeIdStruct &&
5451 type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
5452 {
5453 return OnePossibleValueNo;
5454 }
5455
5419 Error err;5456 Error err;
5420 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))5457 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5421 return OnePossibleValueInvalid;5458 return OnePossibleValueInvalid;
...@@ -5820,9 +5857,15 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -5820,9 +5857,15 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
58205857
58215858
5822ConstExprValue *create_const_vals(size_t count) {5859ConstExprValue *create_const_vals(size_t count) {
5823 ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count, "ConstGlobalRefs");5860 return realloc_const_vals(nullptr, 0, count);
5824 ConstExprValue *vals = allocate<ConstExprValue>(count, "ConstExprValue");5861}
5825 for (size_t i = 0; i < count; i += 1) {5862
5863ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count) {
5864 ConstGlobalRefs *old_global_refs = (base == nullptr) ? nullptr : base->global_refs;
5865 ConstGlobalRefs *global_refs = reallocate<ConstGlobalRefs>(old_global_refs, old_count,
5866 new_count, "ConstGlobalRefs");
5867 ConstExprValue *vals = reallocate<ConstExprValue>(base, old_count, new_count, "ConstExprValue");
5868 for (size_t i = old_count; i < new_count; i += 1) {
5826 vals[i].global_refs = &global_refs[i];5869 vals[i].global_refs = &global_refs[i];
5827 }5870 }
5828 return vals;5871 return vals;
...@@ -7002,7 +7045,16 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -7002,7 +7045,16 @@ bool type_id_eql(TypeId a, TypeId b) {
7002 a.data.pointer.alignment == b.data.pointer.alignment &&7045 a.data.pointer.alignment == b.data.pointer.alignment &&
7003 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&7046 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
7004 a.data.pointer.vector_index == b.data.pointer.vector_index &&7047 a.data.pointer.vector_index == b.data.pointer.vector_index &&
7005 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;7048 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes &&
7049 (
7050 a.data.pointer.inferred_struct_field == b.data.pointer.inferred_struct_field ||
7051 (a.data.pointer.inferred_struct_field != nullptr &&
7052 b.data.pointer.inferred_struct_field != nullptr &&
7053 a.data.pointer.inferred_struct_field->inferred_struct_type ==
7054 b.data.pointer.inferred_struct_field->inferred_struct_type &&
7055 buf_eql_buf(a.data.pointer.inferred_struct_field->field_name,
7056 b.data.pointer.inferred_struct_field->field_name))
7057 );
7006 case ZigTypeIdArray:7058 case ZigTypeIdArray:
7007 return a.data.array.child_type == b.data.array.child_type &&7059 return a.data.array.child_type == b.data.array.child_type &&
7008 a.data.array.size == b.data.array.size;7060 a.data.array.size == b.data.array.size;
...@@ -7815,7 +7867,6 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7815,7 +7867,6 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7815 ZigLLVMDIScope *di_scope;7867 ZigLLVMDIScope *di_scope;
7816 unsigned line;7868 unsigned line;
7817 if (decl_node != nullptr) {7869 if (decl_node != nullptr) {
7818 assert(decl_node->type == NodeTypeContainerDecl);
7819 Scope *scope = &struct_type->data.structure.decls_scope->base;7870 Scope *scope = &struct_type->data.structure.decls_scope->base;
7820 ZigType *import = get_scope_import(scope);7871 ZigType *import = get_scope_import(scope);
7821 di_file = import->data.structure.root_struct->di_file;7872 di_file = import->data.structure.root_struct->di_file;
...@@ -8018,7 +8069,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8018,7 +8069,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8018 }8069 }
8019 unsigned line;8070 unsigned line;
8020 if (decl_node != nullptr) {8071 if (decl_node != nullptr) {
8021 AstNode *field_node = decl_node->data.container_decl.fields.at(i);8072 AstNode *field_node = field->decl_node;
8022 line = field_node->line + 1;8073 line = field_node->line + 1;
8023 } else {8074 } else {
8024 line = 0;8075 line = 0;
...@@ -8314,12 +8365,12 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus...@@ -8314,12 +8365,12 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus
8314 if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {8365 if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {
8315 peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,8366 peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,
8316 PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,8367 PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,
8317 VECTOR_INDEX_NONE);8368 VECTOR_INDEX_NONE, nullptr);
8318 } else {8369 } else {
8319 uint32_t host_vec_len = type->data.pointer.host_int_bytes;8370 uint32_t host_vec_len = type->data.pointer.host_int_bytes;
8320 ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);8371 ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);
8321 peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,8372 peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,
8322 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE);8373 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr);
8323 }8374 }
8324 type->llvm_type = get_llvm_type(g, peer_type);8375 type->llvm_type = get_llvm_type(g, peer_type);
8325 type->llvm_di_type = get_llvm_di_type(g, peer_type);8376 type->llvm_di_type = get_llvm_di_type(g, peer_type);
src/analyze.hpp+2-1
...@@ -24,7 +24,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,...@@ -24,7 +24,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,
24ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,24ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,
25 bool is_const, bool is_volatile, PtrLen ptr_len,25 bool is_const, bool is_volatile, PtrLen ptr_len,
26 uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,26 uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,
27 bool allow_zero, uint32_t vector_index);27 bool allow_zero, uint32_t vector_index, InferredStructField *inferred_struct_field);
28uint64_t type_size(CodeGen *g, ZigType *type_entry);28uint64_t type_size(CodeGen *g, ZigType *type_entry);
29uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);29uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
30ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);30ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
...@@ -175,6 +175,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde...@@ -175,6 +175,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
175ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);175ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
176176
177ConstExprValue *create_const_vals(size_t count);177ConstExprValue *create_const_vals(size_t count);
178ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count);
178179
179ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);180ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
180void expand_undef_array(CodeGen *g, ConstExprValue *const_val);181void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
src/ir.cpp+142-21
...@@ -202,6 +202,8 @@ static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char...@@ -202,6 +202,8 @@ static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char
202 Scope *scope, AstNode *source_node, Buf *out_bare_name);202 Scope *scope, AstNode *source_node, Buf *out_bare_name);
203static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,203static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
204 ResultLoc *parent_result_loc);204 ResultLoc *parent_result_loc);
205static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
206 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
205207
206static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {208static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
207 assert(get_src_ptr_type(const_val->type) != nullptr);209 assert(get_src_ptr_type(const_val->type) != nullptr);
...@@ -16321,13 +16323,81 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -16321,13 +16323,81 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
16321 return ir_const_void(ira, source_instr);16323 return ir_const_void(ira, source_instr);
16322 }16324 }
1632316325
16324 ZigType *child_type = ptr->value.type->data.pointer.child_type;16326 InferredStructField *isf = ptr->value.type->data.pointer.inferred_struct_field;
16327 if (allow_write_through_const && isf != nullptr) {
16328 // Now it's time to add the field to the struct type.
16329 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
16330 uint32_t new_field_count = old_field_count + 1;
16331 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
16332 // This thing with max(x, 16) is a hack to allow this functionality to work without
16333 // modifying the ConstExprValue layout of structs. That reworking needs to be
16334 // done, but this hack lets us do it separately, in the future.
16335 TypeStructField *prev_ptr = isf->inferred_struct_type->data.structure.fields;
16336 isf->inferred_struct_type->data.structure.fields = reallocate(
16337 isf->inferred_struct_type->data.structure.fields,
16338 (old_field_count == 0) ? 0 : max(old_field_count, 16u),
16339 max(new_field_count, 16u));
16340 if (prev_ptr != nullptr && prev_ptr != isf->inferred_struct_type->data.structure.fields) {
16341 zig_panic("TODO need to rework the layout of ZigTypeStruct. this realloc would have caused invalid pointer references");
16342 }
16343
16344 // This reference can't live long, don't keep it around outside this block.
16345 TypeStructField *field = &isf->inferred_struct_type->data.structure.fields[old_field_count];
16346 field->name = isf->field_name;
16347 field->type_entry = uncasted_value->value.type;
16348 field->type_val = create_const_type(ira->codegen, field->type_entry);
16349 field->src_index = old_field_count;
16350 field->decl_node = uncasted_value->source_node;
16351
16352 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
16353 IrInstruction *casted_ptr;
16354 if (instr_is_comptime(ptr)) {
16355 casted_ptr = ir_const(ira, source_instr, struct_ptr_type);
16356 copy_const_val(&casted_ptr->value, &ptr->value, false);
16357 casted_ptr->value.type = struct_ptr_type;
16358 } else {
16359 casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope,
16360 source_instr->source_node, struct_ptr_type, ptr, CastOpNoop);
16361 casted_ptr->value.type = struct_ptr_type;
16362 }
16363 if (instr_is_comptime(casted_ptr)) {
16364 ConstExprValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
16365 if (!ptr_val)
16366 return ira->codegen->invalid_instruction;
16367 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
16368 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
16369 source_instr->source_node);
16370 struct_val->special = ConstValSpecialStatic;
16371 ConstExprValue *prev_ptr = struct_val->data.x_struct.fields;
16372 // This thing with max(x, 16) is a hack to allow this functionality to work without
16373 // modifying the ConstExprValue layout of structs. That reworking needs to be
16374 // done, but this hack lets us do it separately, in the future.
16375 struct_val->data.x_struct.fields = realloc_const_vals(struct_val->data.x_struct.fields,
16376 (old_field_count == 0) ? 0 : max(old_field_count, 16u),
16377 max(new_field_count, 16u));
16378 if (prev_ptr != nullptr && prev_ptr != struct_val->data.x_struct.fields) {
16379 zig_panic("TODO need to rework the layout of ConstExprValue for structs. this realloc would have caused invalid pointer references");
16380 }
16381
16382 ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];
16383 field_val->special = ConstValSpecialUndef;
16384 field_val->type = field->type_entry;
16385 field_val->parent.id = ConstParentIdStruct;
16386 field_val->parent.data.p_struct.struct_val = struct_val;
16387 field_val->parent.data.p_struct.field_index = old_field_count;
16388 }
16389 }
16390
16391 ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, casted_ptr,
16392 isf->inferred_struct_type, true);
16393 }
1632516394
16326 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {16395 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {
16327 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));16396 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
16328 return ira->codegen->invalid_instruction;16397 return ira->codegen->invalid_instruction;
16329 }16398 }
1633016399
16400 ZigType *child_type = ptr->value.type->data.pointer.child_type;
16331 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);16401 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);
16332 if (value == ira->codegen->invalid_instruction)16402 if (value == ira->codegen->invalid_instruction)
16333 return ira->codegen->invalid_instruction;16403 return ira->codegen->invalid_instruction;
...@@ -17853,7 +17923,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17853,7 +17923,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17853 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,17923 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
17854 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,17924 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
17855 elem_ptr_instruction->ptr_len,17925 elem_ptr_instruction->ptr_len,
17856 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index);17926 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index,
17927 nullptr);
17857 } else if (return_type->data.pointer.explicit_alignment != 0) {17928 } else if (return_type->data.pointer.explicit_alignment != 0) {
17858 // figure out the largest alignment possible17929 // figure out the largest alignment possible
1785917930
...@@ -18094,7 +18165,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -18094,7 +18165,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
18094 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,18165 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
18095 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,18166 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
18096 elem_ptr_instruction->ptr_len,18167 elem_ptr_instruction->ptr_len,
18097 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME);18168 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME,
18169 nullptr);
18098 } else {18170 } else {
18099 // runtime known element index18171 // runtime known element index
18100 switch (type_requires_comptime(ira->codegen, return_type)) {18172 switch (type_requires_comptime(ira->codegen, return_type)) {
...@@ -18210,31 +18282,34 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -18210,31 +18282,34 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
18210 case OnePossibleValueNo:18282 case OnePossibleValueNo:
18211 break;18283 break;
18212 }18284 }
18213 ResolveStatus needed_resolve_status =
18214 (struct_type->data.structure.layout == ContainerLayoutAuto) ?
18215 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
18216 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
18217 return ira->codegen->invalid_instruction;
18218 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
18219 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
18220 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
18221 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
18222 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
18223 bool is_const = struct_ptr->value.type->data.pointer.is_const;18285 bool is_const = struct_ptr->value.type->data.pointer.is_const;
18224 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;18286 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
18225 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,18287 ZigType *ptr_type;
18226 is_const, is_volatile, PtrLenSingle, field->align,18288 if (struct_type->data.structure.is_inferred) {
18227 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),18289 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
18228 (uint32_t)host_int_bytes_for_result_type, false);18290 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
18291 } else {
18292 ResolveStatus needed_resolve_status =
18293 (struct_type->data.structure.layout == ContainerLayoutAuto) ?
18294 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
18295 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
18296 return ira->codegen->invalid_instruction;
18297 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
18298 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
18299 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
18300 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
18301 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
18302 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
18303 is_const, is_volatile, PtrLenSingle, field->align,
18304 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
18305 (uint32_t)host_int_bytes_for_result_type, false);
18306 }
18229 if (instr_is_comptime(struct_ptr)) {18307 if (instr_is_comptime(struct_ptr)) {
18230 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);18308 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
18231 if (!ptr_val)18309 if (!ptr_val)
18232 return ira->codegen->invalid_instruction;18310 return ira->codegen->invalid_instruction;
1823318311
18234 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {18312 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
18235 if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusSizeKnown)))
18236 return ira->codegen->invalid_instruction;
18237
18238 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);18313 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
18239 if (struct_val == nullptr)18314 if (struct_val == nullptr)
18240 return ira->codegen->invalid_instruction;18315 return ira->codegen->invalid_instruction;
...@@ -18246,7 +18321,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -18246,7 +18321,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
18246 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {18321 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
18247 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];18322 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
18248 field_val->special = ConstValSpecialUndef;18323 field_val->special = ConstValSpecialUndef;
18249 field_val->type = struct_type->data.structure.fields[i].type_entry;18324 field_val->type = resolve_struct_field_type(ira->codegen,
18325 &struct_type->data.structure.fields[i]);
18250 field_val->parent.id = ConstParentIdStruct;18326 field_val->parent.id = ConstParentIdStruct;
18251 field_val->parent.data.p_struct.struct_val = struct_val;18327 field_val->parent.data.p_struct.struct_val = struct_val;
18252 field_val->parent.data.p_struct.field_index = i;18328 field_val->parent.data.p_struct.field_index = i;
...@@ -18275,6 +18351,40 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -18275,6 +18351,40 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
18275 return result;18351 return result;
18276}18352}
1827718353
18354static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
18355 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type)
18356{
18357 // The type of the field is not available until a store using this pointer happens.
18358 // So, here we create a special pointer type which has the inferred struct type and
18359 // field name encoded in the type. Later, when there is a store via this pointer,
18360 // the field type will then be available, and the field will be added to the inferred
18361 // struct.
18362
18363 ZigType *container_ptr_type = container_ptr->value.type;
18364 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr);
18365
18366 InferredStructField *inferred_struct_field = allocate<InferredStructField>(1, "InferredStructField");
18367 inferred_struct_field->inferred_struct_type = container_type;
18368 inferred_struct_field->field_name = field_name;
18369
18370 ZigType *elem_type = ira->codegen->builtin_types.entry_c_void;
18371 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
18372 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile,
18373 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field);
18374
18375 if (instr_is_comptime(container_ptr)) {
18376 IrInstruction *result = ir_const(ira, source_instr, field_ptr_type);
18377 copy_const_val(&result->value, &container_ptr->value, false);
18378 result->value.type = field_ptr_type;
18379 return result;
18380 }
18381
18382 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope,
18383 source_instr->source_node, field_ptr_type, container_ptr, CastOpNoop);
18384 result->value.type = field_ptr_type;
18385 return result;
18386}
18387
18278static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,18388static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
18279 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)18389 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)
18280{18390{
...@@ -18282,6 +18392,12 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -18282,6 +18392,12 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1828218392
18283 ZigType *bare_type = container_ref_type(container_type);18393 ZigType *bare_type = container_ref_type(container_type);
1828418394
18395 if (initializing && bare_type->id == ZigTypeIdStruct &&
18396 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred)
18397 {
18398 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type);
18399 }
18400
18285 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))18401 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))
18286 return ira->codegen->invalid_instruction;18402 return ira->codegen->invalid_instruction;
1828718403
...@@ -20056,6 +20172,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -20056,6 +20172,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
20056 return ira->codegen->invalid_instruction;20172 return ira->codegen->invalid_instruction;
20057 }20173 }
2005820174
20175 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) {
20176 // We're now done inferring the type.
20177 container_type->data.structure.resolve_status = ResolveStatusUnstarted;
20178 }
20179
20059 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))20180 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
20060 return ira->codegen->invalid_instruction;20181 return ira->codegen->invalid_instruction;
2006120182
test/stage1/behavior/struct.zig+22
...@@ -729,3 +729,25 @@ test "anonymous struct literal syntax" {...@@ -729,3 +729,25 @@ test "anonymous struct literal syntax" {
729 S.doTheTest();729 S.doTheTest();
730 comptime S.doTheTest();730 comptime S.doTheTest();
731}731}
732
733test "fully anonymous struct" {
734 const S = struct {
735 fn doTheTest() void {
736 dump(.{
737 .int = @as(u32, 1234),
738 .float = @as(f64, 12.34),
739 .b = true,
740 .s = "hi",
741 });
742 }
743 fn dump(args: var) void {
744 expect(args.int == 1234);
745 expect(args.float == 12.34);
746 expect(args.b);
747 expect(args.s[0] == 'h');
748 expect(args.s[1] == 'i');
749 }
750 };
751 S.doTheTest();
752 comptime S.doTheTest();
753}