diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 8 | ||||
| -rw-r--r-- | src/analyze.cpp | 11 | ||||
| -rw-r--r-- | src/ir.cpp | 85 |
3 files changed, 57 insertions, 47 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 2a20d3c860..61dde995af 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -302,6 +302,7 @@ enum LazyValueId { LazyValueIdInvalid, LazyValueIdAlignOf, LazyValueIdPtrType, + LazyValueIdOptType, LazyValueIdSliceType, LazyValueIdFnType, }; @@ -340,6 +341,13 @@ struct LazyValuePtrType { uint32_t host_int_bytes; }; +struct LazyValueOptType { + LazyValue base; + + ConstExprValue *payload_type_val; + AstNode *payload_type_src_node; +}; + struct LazyValueFnType { LazyValue base; bool is_generic; diff --git a/src/analyze.cpp b/src/analyze.cpp index 0b65210eea..5159dbb05a 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -992,6 +992,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi parent_type_val, is_zero_bits); } } + case LazyValueIdOptType: case LazyValueIdSliceType: *is_zero_bits = false; return ErrorNone; @@ -1017,6 +1018,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool case LazyValueIdSliceType: case LazyValueIdPtrType: case LazyValueIdFnType: + case LazyValueIdOptType: *is_opaque_type = false; return ErrorNone; } @@ -1041,6 +1043,10 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy); return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val); } + case LazyValueIdOptType: { + LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy); + return type_val_resolve_requires_comptime(g, lazy_opt_type->payload_type_val); + } case LazyValueIdFnType: { LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); if (lazy_fn_type->is_generic) @@ -1091,6 +1097,10 @@ static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, si case LazyValueIdFnType: *abi_align = g->builtin_types.entry_usize->abi_align; return ErrorNone; + case LazyValueIdOptType: { + LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy); + return type_val_resolve_abi_align(g, lazy_opt_type->payload_type_val, abi_align); + } } zig_unreachable(); } @@ -1104,6 +1114,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons case LazyValueIdAlignOf: zig_unreachable(); case LazyValueIdSliceType: // it has the len field + case LazyValueIdOptType: // it has the optional bit case LazyValueIdFnType: return OnePossibleValueNo; case LazyValueIdPtrType: { diff --git a/src/ir.cpp b/src/ir.cpp index 70dc894f86..2f38b42221 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8212,6 +8212,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast { Error err; assert(ptr_val->type->id == ZigTypeIdPointer); + assert(ptr_val->special == ConstValSpecialStatic); ConstExprValue tmp = {}; tmp.special = ConstValSpecialStatic; 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 zig_unreachable(); } -static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { - Error err; - IrInstruction *value = un_op_instruction->value->child; - ZigType *type_entry = ir_resolve_type(ira, value); - if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; - if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; +static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) { + IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); + result->value.special = ConstValSpecialLazy; - switch (type_entry->id) { - case ZigTypeIdInvalid: - zig_unreachable(); - case ZigTypeIdMetaType: - case ZigTypeIdVoid: - case ZigTypeIdBool: - case ZigTypeIdInt: - case ZigTypeIdVector: - case ZigTypeIdFloat: - case ZigTypeIdPointer: - case ZigTypeIdArray: - case ZigTypeIdStruct: - case ZigTypeIdComptimeFloat: - case ZigTypeIdComptimeInt: - case ZigTypeIdEnumLiteral: - case ZigTypeIdUndefined: - case ZigTypeIdNull: - case ZigTypeIdOptional: - case ZigTypeIdErrorUnion: - case ZigTypeIdErrorSet: - case ZigTypeIdEnum: - case ZigTypeIdUnion: - case ZigTypeIdFn: - case ZigTypeIdBoundFn: - case ZigTypeIdArgTuple: - case ZigTypeIdFnFrame: - case ZigTypeIdAnyFrame: - return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); + LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1); + result->value.data.x_lazy = &lazy_opt_type->base; + lazy_opt_type->base.id = LazyValueIdOptType; + lazy_opt_type->base.exec = ira->new_irb.exec; - case ZigTypeIdUnreachable: - case ZigTypeIdOpaque: - ir_add_error_node(ira, un_op_instruction->base.source_node, - buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); - return ira->codegen->invalid_instruction; - } - zig_unreachable(); + lazy_opt_type->payload_type_val = ir_resolve_type_lazy(ira, instruction->value->child); + if (lazy_opt_type->payload_type_val == nullptr) + return ira->codegen->invalid_instruction; + lazy_opt_type->payload_type_src_node = instruction->value->source_node; + + return result; } static 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 ZigVar *var = tld->var; - if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) - return ira->codegen->builtin_types.entry_invalid; - assert(var->const_value->type->id == ZigTypeIdMetaType); - return var->const_value->data.x_type; + + return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); } static 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 val->special = ConstValSpecialStatic; return ErrorNone; } + case LazyValueIdOptType: { + LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); + + ZigType *payload_type = ir_resolve_const_type(codegen, exec, lazy_opt_type->payload_type_src_node, + lazy_opt_type->payload_type_val); + if (type_is_invalid(payload_type)) + return ErrorSemanticAnalyzeFail; + + if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { + exec_add_error_node(codegen, exec, lazy_opt_type->payload_type_src_node, + buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); + return ErrorSemanticAnalyzeFail; + } + + if ((err = type_resolve(codegen, payload_type, ResolveStatusSizeKnown))) + return err; + + assert(val->type->id == ZigTypeIdMetaType); + val->data.x_type = get_optional_type(codegen, payload_type); + val->special = ConstValSpecialStatic; + return ErrorNone; + } case LazyValueIdFnType: { ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, reinterpret_cast<LazyValueFnType *>(val->data.x_lazy)); |
