mirror of
https://github.com/ziglang/zig.git
synced 2026-01-30 19:23:37 +00:00
add lazy value support for optional types
this case works now:
```zig
const Node = struct {
node: ?*Node,
};
```
This commit is contained in:
parent
f0034495fa
commit
101440c199
@ -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;
|
||||
|
||||
@ -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: {
|
||||
|
||||
85
src/ir.cpp
85
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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user