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 {...@@ -302,6 +302,7 @@ enum LazyValueId {
302 LazyValueIdInvalid,302 LazyValueIdInvalid,
303 LazyValueIdAlignOf,303 LazyValueIdAlignOf,
304 LazyValueIdPtrType,304 LazyValueIdPtrType,
305 LazyValueIdOptType,
305 LazyValueIdSliceType,306 LazyValueIdSliceType,
306 LazyValueIdFnType,307 LazyValueIdFnType,
307};308};
...@@ -340,6 +341,13 @@ struct LazyValuePtrType {...@@ -340,6 +341,13 @@ struct LazyValuePtrType {
340 uint32_t host_int_bytes;341 uint32_t host_int_bytes;
341};342};
342343
344struct LazyValueOptType {
345 LazyValue base;
346
347 ConstExprValue *payload_type_val;
348 AstNode *payload_type_src_node;
349};
350
343struct LazyValueFnType {351struct LazyValueFnType {
344 LazyValue base;352 LazyValue base;
345 bool is_generic;353 bool is_generic;
src/analyze.cpp+11
...@@ -992,6 +992,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi...@@ -992,6 +992,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
992 parent_type_val, is_zero_bits);992 parent_type_val, is_zero_bits);
993 }993 }
994 }994 }
995 case LazyValueIdOptType:
995 case LazyValueIdSliceType:996 case LazyValueIdSliceType:
996 *is_zero_bits = false;997 *is_zero_bits = false;
997 return ErrorNone;998 return ErrorNone;
...@@ -1017,6 +1018,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool...@@ -1017,6 +1018,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool
1017 case LazyValueIdSliceType:1018 case LazyValueIdSliceType:
1018 case LazyValueIdPtrType:1019 case LazyValueIdPtrType:
1019 case LazyValueIdFnType:1020 case LazyValueIdFnType:
1021 case LazyValueIdOptType:
1020 *is_opaque_type = false;1022 *is_opaque_type = false;
1021 return ErrorNone;1023 return ErrorNone;
1022 }1024 }
...@@ -1041,6 +1043,10 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1041,6 +1043,10 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1041 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);1043 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1042 return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val);1044 return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val);
1043 }1045 }
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 }
1044 case LazyValueIdFnType: {1050 case LazyValueIdFnType: {
1045 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);1051 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
1046 if (lazy_fn_type->is_generic)1052 if (lazy_fn_type->is_generic)
...@@ -1091,6 +1097,10 @@ static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, si...@@ -1091,6 +1097,10 @@ static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, si
1091 case LazyValueIdFnType:1097 case LazyValueIdFnType:
1092 *abi_align = g->builtin_types.entry_usize->abi_align;1098 *abi_align = g->builtin_types.entry_usize->abi_align;
1093 return ErrorNone;1099 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 }
1094 }1104 }
1095 zig_unreachable();1105 zig_unreachable();
1096}1106}
...@@ -1104,6 +1114,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons...@@ -1104,6 +1114,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons
1104 case LazyValueIdAlignOf:1114 case LazyValueIdAlignOf:
1105 zig_unreachable();1115 zig_unreachable();
1106 case LazyValueIdSliceType: // it has the len field1116 case LazyValueIdSliceType: // it has the len field
1117 case LazyValueIdOptType: // it has the optional bit
1107 case LazyValueIdFnType:1118 case LazyValueIdFnType:
1108 return OnePossibleValueNo;1119 return OnePossibleValueNo;
1109 case LazyValueIdPtrType: {1120 case LazyValueIdPtrType: {
src/ir.cpp+38-47
...@@ -8212,6 +8212,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast...@@ -8212,6 +8212,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast
8212{8212{
8213 Error err;8213 Error err;
8214 assert(ptr_val->type->id == ZigTypeIdPointer);8214 assert(ptr_val->type->id == ZigTypeIdPointer);
8215 assert(ptr_val->special == ConstValSpecialStatic);
8215 ConstExprValue tmp = {};8216 ConstExprValue tmp = {};
8216 tmp.special = ConstValSpecialStatic;8217 tmp.special = ConstValSpecialStatic;
8217 tmp.type = ptr_val->type->data.pointer.child_type;8218 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...@@ -16150,51 +16151,21 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
16150 zig_unreachable();16151 zig_unreachable();
16151}16152}
1615216153
16153static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {16154static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) {
16154 Error err;16155 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
16155 IrInstruction *value = un_op_instruction->value->child;16156 result->value.special = ConstValSpecialLazy;
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;
1616116157
16162 switch (type_entry->id) {16158 LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1);
16163 case ZigTypeIdInvalid:16159 result->value.data.x_lazy = &lazy_opt_type->base;
16164 zig_unreachable();16160 lazy_opt_type->base.id = LazyValueIdOptType;
16165 case ZigTypeIdMetaType:16161 lazy_opt_type->base.exec = ira->new_irb.exec;
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));
1619016162
16191 case ZigTypeIdUnreachable:16163 lazy_opt_type->payload_type_val = ir_resolve_type_lazy(ira, instruction->value->child);
16192 case ZigTypeIdOpaque:16164 if (lazy_opt_type->payload_type_val == nullptr)
16193 ir_add_error_node(ira, un_op_instruction->base.source_node,16165 return ira->codegen->invalid_instruction;
16194 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name)));16166 lazy_opt_type->payload_type_src_node = instruction->value->source_node;
16195 return ira->codegen->invalid_instruction;16167
16196 }16168 return result;
16197 zig_unreachable();
16198}16169}
1619916170
16200static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type,16171static 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...@@ -19658,11 +19629,9 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
1965819629
19659 ZigVar *var = tld->var;19630 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
19664 assert(var->const_value->type->id == ZigTypeIdMetaType);19632 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);
19666}19635}
1966719636
19668static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,19637static 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...@@ -25633,6 +25602,28 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx
25633 val->special = ConstValSpecialStatic;25602 val->special = ConstValSpecialStatic;
25634 return ErrorNone;25603 return ErrorNone;
25635 }25604 }
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 }
25636 case LazyValueIdFnType: {25627 case LazyValueIdFnType: {
25637 ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node,25628 ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node,
25638 reinterpret_cast<LazyValueFnType *>(val->data.x_lazy));25629 reinterpret_cast<LazyValueFnType *>(val->data.x_lazy));