authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-08 17:38:03+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-08 17:29:59-05:00
logd5e788072d8b207334c0eab0f1289317a55c9344
tree66fe3803e92c7926732f96f3c98c40f9f8ee4799
parent1cb19d1a461d5181c8e367cdd863720e5e695823
signaturelock-open Commit is signed but in an unrecognized format.

Make array types (quasi-)lazy

Fixes #3843

4 files changed, 131 insertions(+), 58 deletions(-)

src/all_types.hpp+10
......@@ -322,6 +322,7 @@ enum LazyValueId {
322322 LazyValueIdSliceType,
323323 LazyValueIdFnType,
324324 LazyValueIdErrUnionType,
325 LazyValueIdArrayType,
325326};
326327
327328struct LazyValue {
......@@ -355,6 +356,15 @@ struct LazyValueSliceType {
355356 bool is_allowzero;
356357};
357358
359struct LazyValueArrayType {
360 LazyValue base;
361
362 IrAnalyze *ira;
363 IrInstruction *sentinel; // can be null
364 IrInstruction *elem_type;
365 uint64_t length;
366};
367
358368struct LazyValuePtrType {
359369 LazyValue base;
360370
src/analyze.cpp+33
......@@ -1147,6 +1147,21 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
11471147 parent_type_val, is_zero_bits);
11481148 }
11491149 }
1150 case LazyValueIdArrayType: {
1151 LazyValueArrayType *lazy_array_type =
1152 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1153
1154 if (lazy_array_type->length < 1) {
1155 *is_zero_bits = true;
1156 return ErrorNone;
1157 }
1158
1159 if ((err = type_val_resolve_zero_bits(g, lazy_array_type->elem_type->value,
1160 parent_type, nullptr, is_zero_bits)))
1161 return err;
1162
1163 return ErrorNone;
1164 }
11501165 case LazyValueIdOptType:
11511166 case LazyValueIdSliceType:
11521167 case LazyValueIdErrUnionType:
......@@ -1181,6 +1196,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o
11811196 case LazyValueIdFnType:
11821197 case LazyValueIdOptType:
11831198 case LazyValueIdErrUnionType:
1199 case LazyValueIdArrayType:
11841200 *is_opaque_type = false;
11851201 return ErrorNone;
11861202 }
......@@ -1208,6 +1224,10 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
12081224 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
12091225 return type_val_resolve_requires_comptime(g, lazy_opt_type->payload_type->value);
12101226 }
1227 case LazyValueIdArrayType: {
1228 LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1229 return type_val_resolve_requires_comptime(g, lazy_array_type->elem_type->value);
1230 }
12111231 case LazyValueIdFnType: {
12121232 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
12131233 if (lazy_fn_type->is_generic)
......@@ -1305,6 +1325,7 @@ start_over:
13051325 return ErrorNone;
13061326 case LazyValueIdOptType:
13071327 case LazyValueIdErrUnionType:
1328 case LazyValueIdArrayType:
13081329 if ((err = ir_resolve_lazy(g, source_node, type_val)))
13091330 return err;
13101331 goto start_over;
......@@ -1340,6 +1361,11 @@ Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_a
13401361 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
13411362 return type_val_resolve_abi_align(g, lazy_opt_type->payload_type->value, abi_align);
13421363 }
1364 case LazyValueIdArrayType: {
1365 LazyValueArrayType *lazy_array_type =
1366 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1367 return type_val_resolve_abi_align(g, lazy_array_type->elem_type->value, abi_align);
1368 }
13431369 case LazyValueIdErrUnionType: {
13441370 LazyValueErrUnionType *lazy_err_union_type =
13451371 reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
......@@ -1370,6 +1396,13 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
13701396 case LazyValueIdOptType: // it has the optional bit
13711397 case LazyValueIdFnType:
13721398 return OnePossibleValueNo;
1399 case LazyValueIdArrayType: {
1400 LazyValueArrayType *lazy_array_type =
1401 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1402 if (lazy_array_type->length < 1)
1403 return OnePossibleValueYes;
1404 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
1405 }
13731406 case LazyValueIdPtrType: {
13741407 Error err;
13751408 bool zero_bits;
src/ir.cpp+79-58
......@@ -20551,73 +20551,28 @@ static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAs
2055120551static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
2055220552 IrInstructionArrayType *array_type_instruction)
2055320553{
20554 Error err;
20554 IrInstruction *result = ir_const(ira, &array_type_instruction->base, ira->codegen->builtin_types.entry_type);
20555 result->value->special = ConstValSpecialLazy;
20556
20557 LazyValueArrayType *lazy_array_type = allocate<LazyValueArrayType>(1, "LazyValueArrayType");
20558 lazy_array_type->ira = ira; ira_ref(ira);
20559 result->value->data.x_lazy = &lazy_array_type->base;
20560 lazy_array_type->base.id = LazyValueIdArrayType;
2055520561
20556 IrInstruction *size_value = array_type_instruction->size->child;
20557 uint64_t size;
20558 if (!ir_resolve_usize(ira, size_value, &size))
20562 lazy_array_type->elem_type = array_type_instruction->child_type->child;
20563 if (ir_resolve_type_lazy(ira, lazy_array_type->elem_type) == nullptr)
2055920564 return ira->codegen->invalid_instruction;
2056020565
20561 IrInstruction *child_type_value = array_type_instruction->child_type->child;
20562 ZigType *child_type = ir_resolve_type(ira, child_type_value);
20563 if (type_is_invalid(child_type))
20566 if (!ir_resolve_usize(ira, array_type_instruction->size->child, &lazy_array_type->length))
2056420567 return ira->codegen->invalid_instruction;
2056520568
20566 ZigValue *sentinel_val;
2056720569 if (array_type_instruction->sentinel != nullptr) {
20568 IrInstruction *uncasted_sentinel = array_type_instruction->sentinel->child;
20569 if (type_is_invalid(uncasted_sentinel->value->type))
20570 return ira->codegen->invalid_instruction;
20571 IrInstruction *sentinel = ir_implicit_cast(ira, uncasted_sentinel, child_type);
20572 if (type_is_invalid(sentinel->value->type))
20573 return ira->codegen->invalid_instruction;
20574 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad);
20575 if (sentinel_val == nullptr)
20570 lazy_array_type->sentinel = array_type_instruction->sentinel->child;
20571 if (ir_resolve_const(ira, lazy_array_type->sentinel, LazyOk) == nullptr)
2057620572 return ira->codegen->invalid_instruction;
20577 } else {
20578 sentinel_val = nullptr;
2057920573 }
2058020574
20581 switch (child_type->id) {
20582 case ZigTypeIdInvalid: // handled above
20583 zig_unreachable();
20584 case ZigTypeIdUnreachable:
20585 case ZigTypeIdUndefined:
20586 case ZigTypeIdNull:
20587 case ZigTypeIdArgTuple:
20588 case ZigTypeIdOpaque:
20589 ir_add_error_node(ira, array_type_instruction->base.source_node,
20590 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name)));
20591 return ira->codegen->invalid_instruction;
20592 case ZigTypeIdMetaType:
20593 case ZigTypeIdVoid:
20594 case ZigTypeIdBool:
20595 case ZigTypeIdInt:
20596 case ZigTypeIdFloat:
20597 case ZigTypeIdPointer:
20598 case ZigTypeIdArray:
20599 case ZigTypeIdStruct:
20600 case ZigTypeIdComptimeFloat:
20601 case ZigTypeIdComptimeInt:
20602 case ZigTypeIdEnumLiteral:
20603 case ZigTypeIdOptional:
20604 case ZigTypeIdErrorUnion:
20605 case ZigTypeIdErrorSet:
20606 case ZigTypeIdEnum:
20607 case ZigTypeIdUnion:
20608 case ZigTypeIdFn:
20609 case ZigTypeIdBoundFn:
20610 case ZigTypeIdVector:
20611 case ZigTypeIdFnFrame:
20612 case ZigTypeIdAnyFrame:
20613 {
20614 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown)))
20615 return ira->codegen->invalid_instruction;
20616 ZigType *result_type = get_array_type(ira->codegen, child_type, size, sentinel_val);
20617 return ir_const_type(ira, &array_type_instruction->base, result_type);
20618 }
20619 }
20620 zig_unreachable();
20575 return result;
2062120576}
2062220577
2062320578static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *instruction) {
......@@ -29016,6 +28971,72 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
2901628971 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
2901728972 return ErrorNone;
2901828973 }
28974 case LazyValueIdArrayType: {
28975 LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(val->data.x_lazy);
28976 IrAnalyze *ira = lazy_array_type->ira;
28977
28978 ZigType *elem_type = ir_resolve_type(ira, lazy_array_type->elem_type);
28979 if (type_is_invalid(elem_type))
28980 return ErrorSemanticAnalyzeFail;
28981
28982 switch (elem_type->id) {
28983 case ZigTypeIdInvalid: // handled above
28984 zig_unreachable();
28985 case ZigTypeIdUnreachable:
28986 case ZigTypeIdUndefined:
28987 case ZigTypeIdNull:
28988 case ZigTypeIdArgTuple:
28989 case ZigTypeIdOpaque:
28990 ir_add_error(ira, lazy_array_type->elem_type,
28991 buf_sprintf("array of type '%s' not allowed",
28992 buf_ptr(&elem_type->name)));
28993 return ErrorSemanticAnalyzeFail;
28994 case ZigTypeIdMetaType:
28995 case ZigTypeIdVoid:
28996 case ZigTypeIdBool:
28997 case ZigTypeIdInt:
28998 case ZigTypeIdFloat:
28999 case ZigTypeIdPointer:
29000 case ZigTypeIdArray:
29001 case ZigTypeIdStruct:
29002 case ZigTypeIdComptimeFloat:
29003 case ZigTypeIdComptimeInt:
29004 case ZigTypeIdEnumLiteral:
29005 case ZigTypeIdOptional:
29006 case ZigTypeIdErrorUnion:
29007 case ZigTypeIdErrorSet:
29008 case ZigTypeIdEnum:
29009 case ZigTypeIdUnion:
29010 case ZigTypeIdFn:
29011 case ZigTypeIdBoundFn:
29012 case ZigTypeIdVector:
29013 case ZigTypeIdFnFrame:
29014 case ZigTypeIdAnyFrame:
29015 break;
29016 }
29017
29018 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown)))
29019 return err;
29020
29021 ZigValue *sentinel_val = nullptr;
29022 if (lazy_array_type->sentinel != nullptr) {
29023 if (type_is_invalid(lazy_array_type->sentinel->value->type))
29024 return ErrorSemanticAnalyzeFail;
29025 IrInstruction *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type);
29026 if (type_is_invalid(sentinel->value->type))
29027 return ErrorSemanticAnalyzeFail;
29028 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad);
29029 if (sentinel_val == nullptr)
29030 return ErrorSemanticAnalyzeFail;
29031 }
29032
29033 assert(val->type->id == ZigTypeIdMetaType);
29034 val->data.x_type = get_array_type(ira->codegen, elem_type, lazy_array_type->length, sentinel_val);
29035 val->special = ConstValSpecialStatic;
29036
29037 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
29038 return ErrorNone;
29039 }
2901929040 case LazyValueIdOptType: {
2902029041 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy);
2902129042 IrAnalyze *ira = lazy_opt_type->ira;
test/stage1/behavior/struct.zig+9
......@@ -813,3 +813,12 @@ test "anon struct literal field value initialized with fn call" {
813813 S.doTheTest();
814814 comptime S.doTheTest();
815815}
816
817test "self-referencing struct via array member" {
818 const T = struct {
819 children: [1]*@This(),
820 };
821 var x: T = undefined;
822 x = T{ .children = .{&x} };
823 expect(x.children[0] == &x);
824}