authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-27 16:55:58-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-27 16:55:58-04:00
logf4519c520a81439e524428258ad5aa441c9b0687
treeffca3f5d69dbee6e384425c5c7987718d151d850
parentc1fd7ed6e2815b3317b4cb82ce85bf44149d7002
signaturelock-open Commit is signed but in an unrecognized format.

support self-referential struct through a slice of optional

by making optionals even more lazy closes #1805

5 files changed, 210 insertions(+), 98 deletions(-)

src/all_types.hpp+2-1
......@@ -329,7 +329,7 @@ struct LazyValueSliceType {
329329 LazyValue base;
330330
331331 IrAnalyze *ira;
332 ZigType *elem_type;
332 IrInstruction *elem_type;
333333 IrInstruction *align_inst; // can be null
334334
335335 bool is_const;
......@@ -1222,6 +1222,7 @@ struct ZigTypeStruct {
12221222
12231223struct ZigTypeOptional {
12241224 ZigType *child_type;
1225 ResolveStatus resolve_status;
12251226};
12261227
12271228struct ZigTypeErrorUnion {
src/analyze.cpp+134-56
......@@ -566,6 +566,7 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
566566 }
567567
568568 entry->data.maybe.child_type = child_type;
569 entry->data.maybe.resolve_status = ResolveStatusSizeKnown;
569570
570571 child_type->optional_parent = entry;
571572 return entry;
......@@ -1055,9 +1056,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
10551056 zig_unreachable();
10561057 case LazyValueIdSliceType: {
10571058 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
1058 if (type_is_invalid(lazy_slice_type->elem_type))
1059 return ReqCompTimeInvalid;
1060 return type_requires_comptime(g, lazy_slice_type->elem_type);
1059 return type_val_resolve_requires_comptime(g, &lazy_slice_type->elem_type->value);
10611060 }
10621061 case LazyValueIdPtrType: {
10631062 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
......@@ -1099,6 +1098,42 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
10991098 zig_unreachable();
11001099}
11011100
1101static Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
1102 size_t *abi_size, size_t *size_in_bits)
1103{
1104 Error err;
1105 if (type_val->data.x_lazy->id == LazyValueIdOptType) {
1106 if ((err = ir_resolve_lazy(g, source_node, type_val)))
1107 return err;
1108 }
1109 if (type_val->special != ConstValSpecialLazy) {
1110 assert(type_val->special == ConstValSpecialStatic);
1111 ZigType *ty = type_val->data.x_type;
1112 if ((err = type_resolve(g, ty, ResolveStatusSizeKnown)))
1113 return err;
1114 *abi_size = ty->abi_size;
1115 *size_in_bits = ty->size_in_bits;
1116 return ErrorNone;
1117 }
1118 switch (type_val->data.x_lazy->id) {
1119 case LazyValueIdInvalid:
1120 case LazyValueIdAlignOf:
1121 zig_unreachable();
1122 case LazyValueIdSliceType:
1123 *abi_size = g->builtin_types.entry_usize->abi_size * 2;
1124 *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;
1125 return ErrorNone;
1126 case LazyValueIdPtrType:
1127 case LazyValueIdFnType:
1128 *abi_size = g->builtin_types.entry_usize->abi_size;
1129 *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1130 return ErrorNone;
1131 case LazyValueIdOptType:
1132 zig_unreachable();
1133 }
1134 zig_unreachable();
1135}
1136
11021137Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) {
11031138 Error err;
11041139 if (type_val->special != ConstValSpecialLazy) {
......@@ -1767,6 +1802,17 @@ static size_t get_abi_size_bytes(size_t size_in_bits, size_t pointer_size_bytes)
17671802 return align_forward(store_size_bytes, abi_align);
17681803}
17691804
1805ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field) {
1806 Error err;
1807 if (struct_field->type_entry == nullptr) {
1808 if ((err = ir_resolve_lazy(g, struct_field->decl_node, struct_field->type_val))) {
1809 return nullptr;
1810 }
1811 struct_field->type_entry = struct_field->type_val->data.x_type;
1812 }
1813 return struct_field->type_entry;
1814}
1815
17701816static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
17711817 assert(struct_type->id == ZigTypeIdStruct);
17721818
......@@ -1801,40 +1847,6 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
18011847
18021848 uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;
18031849
1804 // Resolve types for fields and then resolve sizes of all the field types.
1805 // This is done before the offset loop because the offset loop has to look ahead.
1806 for (size_t i = 0; i < field_count; i += 1) {
1807 AstNode *field_source_node = decl_node->data.container_decl.fields.at(i);
1808 TypeStructField *field = &struct_type->data.structure.fields[i];
1809
1810 if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) {
1811 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1812 return err;
1813 }
1814 field->type_entry = field->type_val->data.x_type;
1815
1816 if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {
1817 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1818 return err;
1819 }
1820
1821 if (struct_type->data.structure.layout == ContainerLayoutExtern &&
1822 !type_allowed_in_extern(g, field->type_entry))
1823 {
1824 add_node_error(g, field_source_node,
1825 buf_sprintf("extern structs cannot contain fields of type '%s'",
1826 buf_ptr(&field->type_entry->name)));
1827 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1828 return ErrorSemanticAnalyzeFail;
1829 } else if (packed) {
1830 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field_source_node))) {
1831 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1832 return err;
1833 }
1834 }
1835
1836 }
1837
18381850 size_t packed_bits_offset = 0;
18391851 size_t next_offset = 0;
18401852 size_t first_packed_bits_offset_misalign = SIZE_MAX;
......@@ -1847,13 +1859,25 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
18471859 TypeStructField *field = &struct_type->data.structure.fields[i];
18481860 if (field->gen_index == SIZE_MAX)
18491861 continue;
1850 ZigType *field_type = field->type_entry;
1851 assert(field_type != nullptr);
18521862
18531863 field->gen_index = gen_field_index;
18541864 field->offset = next_offset;
18551865
18561866 if (packed) {
1867 ZigType *field_type = resolve_struct_field_type(g, field);
1868 if (field_type == nullptr) {
1869 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1870 return err;
1871 }
1872 if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {
1873 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1874 return err;
1875 }
1876 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field->decl_node))) {
1877 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1878 return err;
1879 }
1880
18571881 size_t field_size_in_bits = type_size_bits(g, field_type);
18581882 size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits;
18591883
......@@ -1889,6 +1913,15 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
18891913 }
18901914 packed_bits_offset = next_packed_bits_offset;
18911915 } else {
1916 size_t field_abi_size;
1917 size_t field_size_in_bits;
1918 if ((err = type_val_resolve_abi_size(g, field->decl_node, field->type_val,
1919 &field_abi_size, &field_size_in_bits)))
1920 {
1921 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1922 return err;
1923 }
1924
18921925 gen_field_index += 1;
18931926 size_t next_src_field_index = i + 1;
18941927 for (; next_src_field_index < field_count; next_src_field_index += 1) {
......@@ -1898,7 +1931,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
18981931 }
18991932 size_t next_align = (next_src_field_index == field_count) ?
19001933 abi_align : struct_type->data.structure.fields[next_src_field_index].align;
1901 next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_align);
1934 next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align);
19021935 size_in_bits = next_offset * 8;
19031936 }
19041937 }
......@@ -1917,6 +1950,36 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
19171950 struct_type->data.structure.resolve_loop_flag_other = false;
19181951 struct_type->data.structure.host_int_bytes = host_int_bytes;
19191952
1953
1954 // Resolve types for fields
1955 if (!packed) {
1956 for (size_t i = 0; i < field_count; i += 1) {
1957 TypeStructField *field = &struct_type->data.structure.fields[i];
1958 ZigType *field_type = resolve_struct_field_type(g, field);
1959 if (field_type == nullptr) {
1960 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1961 return err;
1962 }
1963
1964 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
1965 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1966 return err;
1967 }
1968
1969 if (struct_type->data.structure.layout == ContainerLayoutExtern &&
1970 !type_allowed_in_extern(g, field_type))
1971 {
1972 add_node_error(g, field->decl_node,
1973 buf_sprintf("extern structs cannot contain fields of type '%s'",
1974 buf_ptr(&field_type->name)));
1975 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1976 return ErrorSemanticAnalyzeFail;
1977 }
1978
1979 }
1980 }
1981
1982
19201983 return ErrorNone;
19211984}
19221985
......@@ -7669,8 +7732,11 @@ static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {
76697732 type->llvm_type = LLVMIntType(type->size_in_bits);
76707733}
76717734
7672static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
7673 if (type->llvm_di_type != nullptr) return;
7735static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7736 assert(type->id == ZigTypeIdOptional);
7737 assert(type->data.maybe.resolve_status != ResolveStatusInvalid);
7738 assert(type->data.maybe.resolve_status >= ResolveStatusSizeKnown);
7739 if (type->data.maybe.resolve_status >= wanted_resolve_status) return;
76747740
76757741 LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool);
76767742 ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool);
......@@ -7679,30 +7745,41 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
76797745 if (!type_has_bits(child_type)) {
76807746 type->llvm_type = bool_llvm_type;
76817747 type->llvm_di_type = bool_llvm_di_type;
7748 type->data.maybe.resolve_status = ResolveStatusLLVMFull;
76827749 return;
76837750 }
76847751
7685 LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type);
7686 ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type);
7687
76887752 if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) {
7689 type->llvm_type = child_llvm_type;
7690 type->llvm_di_type = child_llvm_di_type;
7753 type->llvm_type = get_llvm_type(g, child_type);
7754 type->llvm_di_type = get_llvm_di_type(g, child_type);
7755 type->data.maybe.resolve_status = ResolveStatusLLVMFull;
76917756 return;
76927757 }
76937758
7759 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7760 ZigLLVMDIFile *di_file = nullptr;
7761 unsigned line = 0;
7762
7763 if (type->data.maybe.resolve_status < ResolveStatusLLVMFwdDecl) {
7764 type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name));
7765 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
7766 type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7767 dwarf_kind, buf_ptr(&type->name),
7768 compile_unit_scope, di_file, line);
7769
7770 type->data.maybe.resolve_status = ResolveStatusLLVMFwdDecl;
7771 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
7772 }
7773
7774 LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type);
7775 ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type);
7776 if (type->data.maybe.resolve_status >= wanted_resolve_status) return;
7777
76947778 LLVMTypeRef elem_types[] = {
76957779 get_llvm_type(g, child_type),
76967780 LLVMInt1Type(),
76977781 };
7698 type->llvm_type = LLVMStructType(elem_types, 2, false);
7699
7700 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7701 ZigLLVMDIFile *di_file = nullptr;
7702 unsigned line = 0;
7703 type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7704 ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name),
7705 compile_unit_scope, di_file, line);
7782 LLVMStructSetBody(type->llvm_type, elem_types, 2, false);
77067783
77077784 uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_llvm_type);
77087785 uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_llvm_type);
......@@ -7737,6 +7814,7 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
77377814
77387815 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
77397816 type->llvm_di_type = replacement_di_type;
7817 type->data.maybe.resolve_status = ResolveStatusLLVMFull;
77407818}
77417819
77427820static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
......@@ -8180,7 +8258,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
81808258 case ZigTypeIdInt:
81818259 return resolve_llvm_types_integer(g, type);
81828260 case ZigTypeIdOptional:
8183 return resolve_llvm_types_optional(g, type);
8261 return resolve_llvm_types_optional(g, type, wanted_resolve_status);
81848262 case ZigTypeIdErrorUnion:
81858263 return resolve_llvm_types_error_union(g, type);
81868264 case ZigTypeIdArray:
src/analyze.hpp+1
......@@ -248,5 +248,6 @@ bool fn_is_async(ZigFn *fn);
248248
249249Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);
250250ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field);
251ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field);
251252
252253#endif
src/ir.cpp+54-41
......@@ -17127,11 +17127,14 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
1712717127 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)
1712817128{
1712917129 Error err;
17130 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
17130 ZigType *field_type = resolve_struct_field_type(ira->codegen, field);
17131 if (field_type == nullptr)
17132 return ira->codegen->invalid_instruction;
17133 switch (type_has_one_possible_value(ira->codegen, field_type)) {
1713117134 case OnePossibleValueInvalid:
1713217135 return ira->codegen->invalid_instruction;
1713317136 case OnePossibleValueYes: {
17134 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
17137 IrInstruction *elem = ir_const(ira, source_instr, field_type);
1713517138 return ir_get_ref(ira, source_instr, elem, false, false);
1713617139 }
1713717140 case OnePossibleValueNo:
......@@ -17146,7 +17149,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
1714617149 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
1714717150 bool is_const = struct_ptr->value.type->data.pointer.is_const;
1714817151 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
17149 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17152 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
1715017153 is_const, is_volatile, PtrLenSingle, field->align,
1715117154 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
1715217155 (uint32_t)host_int_bytes_for_result_type, false);
......@@ -17945,48 +17948,14 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1794517948 return ira->codegen->invalid_instruction;
1794617949 }
1794717950
17948 lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child);
17949 if (type_is_invalid(lazy_slice_type->elem_type))
17951 lazy_slice_type->elem_type = slice_type_instruction->child_type->child;
17952 if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr)
1795017953 return ira->codegen->invalid_instruction;
1795117954
1795217955 lazy_slice_type->is_const = slice_type_instruction->is_const;
1795317956 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile;
1795417957 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero;
1795517958
17956 switch (lazy_slice_type->elem_type->id) {
17957 case ZigTypeIdInvalid: // handled above
17958 zig_unreachable();
17959 case ZigTypeIdUnreachable:
17960 case ZigTypeIdUndefined:
17961 case ZigTypeIdNull:
17962 case ZigTypeIdArgTuple:
17963 case ZigTypeIdOpaque:
17964 ir_add_error_node(ira, slice_type_instruction->base.source_node,
17965 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name)));
17966 return ira->codegen->invalid_instruction;
17967 case ZigTypeIdMetaType:
17968 case ZigTypeIdVoid:
17969 case ZigTypeIdBool:
17970 case ZigTypeIdInt:
17971 case ZigTypeIdFloat:
17972 case ZigTypeIdPointer:
17973 case ZigTypeIdArray:
17974 case ZigTypeIdStruct:
17975 case ZigTypeIdComptimeFloat:
17976 case ZigTypeIdComptimeInt:
17977 case ZigTypeIdEnumLiteral:
17978 case ZigTypeIdOptional:
17979 case ZigTypeIdErrorUnion:
17980 case ZigTypeIdErrorSet:
17981 case ZigTypeIdEnum:
17982 case ZigTypeIdUnion:
17983 case ZigTypeIdFn:
17984 case ZigTypeIdBoundFn:
17985 case ZigTypeIdVector:
17986 case ZigTypeIdFnFrame:
17987 case ZigTypeIdAnyFrame:
17988 break;
17989 }
1799017959 return result;
1799117960}
1799217961
......@@ -20430,6 +20399,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
2043020399 inner_fields[1].special = ConstValSpecialStatic;
2043120400 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
2043220401
20402 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field);
20403 if (field_type == nullptr)
20404 return ErrorSemanticAnalyzeFail;
20405 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
20406 return err;
2043320407 if (!type_has_bits(struct_field->type_entry)) {
2043420408 inner_fields[1].data.x_optional = nullptr;
2043520409 } else {
......@@ -25588,11 +25562,50 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) {
2558825562 if (!ir_resolve_align(ira, lazy_slice_type->align_inst, &align_bytes))
2558925563 return ErrorSemanticAnalyzeFail;
2559025564 }
25565 ZigType *elem_type = ir_resolve_type(ira, lazy_slice_type->elem_type);
25566 if (type_is_invalid(elem_type))
25567 return ErrorSemanticAnalyzeFail;
25568
25569 switch (elem_type->id) {
25570 case ZigTypeIdInvalid: // handled above
25571 zig_unreachable();
25572 case ZigTypeIdUnreachable:
25573 case ZigTypeIdUndefined:
25574 case ZigTypeIdNull:
25575 case ZigTypeIdArgTuple:
25576 case ZigTypeIdOpaque:
25577 ir_add_error(ira, lazy_slice_type->elem_type,
25578 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name)));
25579 return ErrorSemanticAnalyzeFail;
25580 case ZigTypeIdMetaType:
25581 case ZigTypeIdVoid:
25582 case ZigTypeIdBool:
25583 case ZigTypeIdInt:
25584 case ZigTypeIdFloat:
25585 case ZigTypeIdPointer:
25586 case ZigTypeIdArray:
25587 case ZigTypeIdStruct:
25588 case ZigTypeIdComptimeFloat:
25589 case ZigTypeIdComptimeInt:
25590 case ZigTypeIdEnumLiteral:
25591 case ZigTypeIdOptional:
25592 case ZigTypeIdErrorUnion:
25593 case ZigTypeIdErrorSet:
25594 case ZigTypeIdEnum:
25595 case ZigTypeIdUnion:
25596 case ZigTypeIdFn:
25597 case ZigTypeIdBoundFn:
25598 case ZigTypeIdVector:
25599 case ZigTypeIdFnFrame:
25600 case ZigTypeIdAnyFrame:
25601 break;
25602 }
25603
2559125604 ResolveStatus needed_status = (align_bytes == 0) ?
2559225605 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
25593 if ((err = type_resolve(ira->codegen, lazy_slice_type->elem_type, needed_status)))
25606 if ((err = type_resolve(ira->codegen, elem_type, needed_status)))
2559425607 return err;
25595 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, lazy_slice_type->elem_type,
25608 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type,
2559625609 lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes,
2559725610 0, 0, lazy_slice_type->is_allowzero);
2559825611 val->special = ConstValSpecialStatic;
test/stage1/behavior/optional.zig+19
......@@ -100,3 +100,22 @@ test "nested orelse" {
100100 S.entry();
101101 comptime S.entry();
102102}
103
104test "self-referential struct through a slice of optional" {
105 const S = struct {
106 const Node = struct {
107 children: []?Node,
108 data: ?u8,
109
110 fn new() Node {
111 return Node{
112 .children = undefined,
113 .data = null,
114 };
115 }
116 };
117 };
118
119 var n = S.Node.new();
120 expect(n.data == null);
121}