Commit 101440c199
Changed files (3)
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;
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: {
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));