authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 17:14:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 17:14:51-04:00
log101440c1990de653bbfb19713915d86d7a5bc182
tree95aebc6ff11474878ffcf0befd9ae54986c859fa
parentf0034495fa74d7a2c36e4a75520f030bb0cdb16a
signaturelock-open Commit is signed but in an unrecognized format.

add lazy value support for optional types

this case works now: ```zig const Node = struct { node: ?*Node, }; ```

3 files changed, 57 insertions(+), 47 deletions(-)

src/all_types.hpp+8
......@@ -302,6 +302,7 @@ enum LazyValueId {
302302 LazyValueIdInvalid,
303303 LazyValueIdAlignOf,
304304 LazyValueIdPtrType,
305 LazyValueIdOptType,
305306 LazyValueIdSliceType,
306307 LazyValueIdFnType,
307308};
......@@ -340,6 +341,13 @@ struct LazyValuePtrType {
340341 uint32_t host_int_bytes;
341342};
342343
344struct LazyValueOptType {
345 LazyValue base;
346
347 ConstExprValue *payload_type_val;
348 AstNode *payload_type_src_node;
349};
350
343351struct LazyValueFnType {
344352 LazyValue base;
345353 bool is_generic;
src/analyze.cpp+11
......@@ -992,6 +992,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
992992 parent_type_val, is_zero_bits);
993993 }
994994 }
995 case LazyValueIdOptType:
995996 case LazyValueIdSliceType:
996997 *is_zero_bits = false;
997998 return ErrorNone;
......@@ -1017,6 +1018,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool
10171018 case LazyValueIdSliceType:
10181019 case LazyValueIdPtrType:
10191020 case LazyValueIdFnType:
1021 case LazyValueIdOptType:
10201022 *is_opaque_type = false;
10211023 return ErrorNone;
10221024 }
......@@ -1041,6 +1043,10 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
10411043 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
10421044 return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val);
10431045 }
1046 case LazyValueIdOptType: {
1047 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
1048 return type_val_resolve_requires_comptime(g, lazy_opt_type->payload_type_val);
1049 }
10441050 case LazyValueIdFnType: {
10451051 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
10461052 if (lazy_fn_type->is_generic)
......@@ -1091,6 +1097,10 @@ static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, si
10911097 case LazyValueIdFnType:
10921098 *abi_align = g->builtin_types.entry_usize->abi_align;
10931099 return ErrorNone;
1100 case LazyValueIdOptType: {
1101 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
1102 return type_val_resolve_abi_align(g, lazy_opt_type->payload_type_val, abi_align);
1103 }
10941104 }
10951105 zig_unreachable();
10961106}
......@@ -1104,6 +1114,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons
11041114 case LazyValueIdAlignOf:
11051115 zig_unreachable();
11061116 case LazyValueIdSliceType: // it has the len field
1117 case LazyValueIdOptType: // it has the optional bit
11071118 case LazyValueIdFnType:
11081119 return OnePossibleValueNo;
11091120 case LazyValueIdPtrType: {
src/ir.cpp+38-47
......@@ -8212,6 +8212,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast
82128212{
82138213 Error err;
82148214 assert(ptr_val->type->id == ZigTypeIdPointer);
8215 assert(ptr_val->special == ConstValSpecialStatic);
82158216 ConstExprValue tmp = {};
82168217 tmp.special = ConstValSpecialStatic;
82178218 tmp.type = ptr_val->type->data.pointer.child_type;
......@@ -16150,51 +16151,21 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
1615016151 zig_unreachable();
1615116152}
1615216153
16153static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
16154 Error err;
16155 IrInstruction *value = un_op_instruction->value->child;
16156 ZigType *type_entry = ir_resolve_type(ira, value);
16157 if (type_is_invalid(type_entry))
16158 return ira->codegen->invalid_instruction;
16159 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
16160 return ira->codegen->invalid_instruction;
16154static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) {
16155 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
16156 result->value.special = ConstValSpecialLazy;
1616116157
16162 switch (type_entry->id) {
16163 case ZigTypeIdInvalid:
16164 zig_unreachable();
16165 case ZigTypeIdMetaType:
16166 case ZigTypeIdVoid:
16167 case ZigTypeIdBool:
16168 case ZigTypeIdInt:
16169 case ZigTypeIdVector:
16170 case ZigTypeIdFloat:
16171 case ZigTypeIdPointer:
16172 case ZigTypeIdArray:
16173 case ZigTypeIdStruct:
16174 case ZigTypeIdComptimeFloat:
16175 case ZigTypeIdComptimeInt:
16176 case ZigTypeIdEnumLiteral:
16177 case ZigTypeIdUndefined:
16178 case ZigTypeIdNull:
16179 case ZigTypeIdOptional:
16180 case ZigTypeIdErrorUnion:
16181 case ZigTypeIdErrorSet:
16182 case ZigTypeIdEnum:
16183 case ZigTypeIdUnion:
16184 case ZigTypeIdFn:
16185 case ZigTypeIdBoundFn:
16186 case ZigTypeIdArgTuple:
16187 case ZigTypeIdFnFrame:
16188 case ZigTypeIdAnyFrame:
16189 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
16158 LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1);
16159 result->value.data.x_lazy = &lazy_opt_type->base;
16160 lazy_opt_type->base.id = LazyValueIdOptType;
16161 lazy_opt_type->base.exec = ira->new_irb.exec;
1619016162
16191 case ZigTypeIdUnreachable:
16192 case ZigTypeIdOpaque:
16193 ir_add_error_node(ira, un_op_instruction->base.source_node,
16194 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name)));
16195 return ira->codegen->invalid_instruction;
16196 }
16197 zig_unreachable();
16163 lazy_opt_type->payload_type_val = ir_resolve_type_lazy(ira, instruction->value->child);
16164 if (lazy_opt_type->payload_type_val == nullptr)
16165 return ira->codegen->invalid_instruction;
16166 lazy_opt_type->payload_type_src_node = instruction->value->source_node;
16167
16168 return result;
1619816169}
1619916170
1620016171static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type,
......@@ -19658,11 +19629,9 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
1965819629
1965919630 ZigVar *var = tld->var;
1966019631
19661 if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown)))
19662 return ira->codegen->builtin_types.entry_invalid;
19663
1966419632 assert(var->const_value->type->id == ZigTypeIdMetaType);
19665 return var->const_value->data.x_type;
19633
19634 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value);
1966619635}
1966719636
1966819637static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,
......@@ -25633,6 +25602,28 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx
2563325602 val->special = ConstValSpecialStatic;
2563425603 return ErrorNone;
2563525604 }
25605 case LazyValueIdOptType: {
25606 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy);
25607
25608 ZigType *payload_type = ir_resolve_const_type(codegen, exec, lazy_opt_type->payload_type_src_node,
25609 lazy_opt_type->payload_type_val);
25610 if (type_is_invalid(payload_type))
25611 return ErrorSemanticAnalyzeFail;
25612
25613 if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) {
25614 exec_add_error_node(codegen, exec, lazy_opt_type->payload_type_src_node,
25615 buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name)));
25616 return ErrorSemanticAnalyzeFail;
25617 }
25618
25619 if ((err = type_resolve(codegen, payload_type, ResolveStatusSizeKnown)))
25620 return err;
25621
25622 assert(val->type->id == ZigTypeIdMetaType);
25623 val->data.x_type = get_optional_type(codegen, payload_type);
25624 val->special = ConstValSpecialStatic;
25625 return ErrorNone;
25626 }
2563625627 case LazyValueIdFnType: {
2563725628 ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node,
2563825629 reinterpret_cast<LazyValueFnType *>(val->data.x_lazy));