mirror of
https://github.com/ziglang/zig.git
synced 2025-12-07 14:53:08 +00:00
add the anyframe and anyframe->T types
This commit is contained in:
parent
018a89c7a1
commit
ee64a22045
@ -1,6 +1,4 @@
|
|||||||
* reimplement @frameSize with Prefix Data
|
* make the anyframe type and anyframe->T type work with resume
|
||||||
* reimplement with function splitting rather than switch
|
|
||||||
* add the `anyframe` type and `anyframe->T`
|
|
||||||
* await
|
* await
|
||||||
* await of a non async function
|
* await of a non async function
|
||||||
* await in single-threaded mode
|
* await in single-threaded mode
|
||||||
@ -12,3 +10,5 @@
|
|||||||
* implicit cast of normal function to async function should be allowed when it is inferred to be async
|
* implicit cast of normal function to async function should be allowed when it is inferred to be async
|
||||||
* go over the commented out tests
|
* go over the commented out tests
|
||||||
* revive std.event.Loop
|
* revive std.event.Loop
|
||||||
|
* reimplement with function splitting rather than switch
|
||||||
|
* @typeInfo for @Frame(func)
|
||||||
|
|||||||
@ -479,6 +479,7 @@ enum NodeType {
|
|||||||
NodeTypeResume,
|
NodeTypeResume,
|
||||||
NodeTypeAwaitExpr,
|
NodeTypeAwaitExpr,
|
||||||
NodeTypeSuspend,
|
NodeTypeSuspend,
|
||||||
|
NodeTypeAnyFrameType,
|
||||||
NodeTypeEnumLiteral,
|
NodeTypeEnumLiteral,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -936,6 +937,10 @@ struct AstNodeSuspend {
|
|||||||
AstNode *block;
|
AstNode *block;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstNodeAnyFrameType {
|
||||||
|
AstNode *payload_type; // can be NULL
|
||||||
|
};
|
||||||
|
|
||||||
struct AstNodeEnumLiteral {
|
struct AstNodeEnumLiteral {
|
||||||
Token *period;
|
Token *period;
|
||||||
Token *identifier;
|
Token *identifier;
|
||||||
@ -1001,6 +1006,7 @@ struct AstNode {
|
|||||||
AstNodeResumeExpr resume_expr;
|
AstNodeResumeExpr resume_expr;
|
||||||
AstNodeAwaitExpr await_expr;
|
AstNodeAwaitExpr await_expr;
|
||||||
AstNodeSuspend suspend;
|
AstNodeSuspend suspend;
|
||||||
|
AstNodeAnyFrameType anyframe_type;
|
||||||
AstNodeEnumLiteral enum_literal;
|
AstNodeEnumLiteral enum_literal;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
@ -1253,6 +1259,7 @@ enum ZigTypeId {
|
|||||||
ZigTypeIdArgTuple,
|
ZigTypeIdArgTuple,
|
||||||
ZigTypeIdOpaque,
|
ZigTypeIdOpaque,
|
||||||
ZigTypeIdCoroFrame,
|
ZigTypeIdCoroFrame,
|
||||||
|
ZigTypeIdAnyFrame,
|
||||||
ZigTypeIdVector,
|
ZigTypeIdVector,
|
||||||
ZigTypeIdEnumLiteral,
|
ZigTypeIdEnumLiteral,
|
||||||
};
|
};
|
||||||
@ -1272,6 +1279,10 @@ struct ZigTypeCoroFrame {
|
|||||||
ZigType *locals_struct;
|
ZigType *locals_struct;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ZigTypeAnyFrame {
|
||||||
|
ZigType *result_type; // null if `anyframe` instead of `anyframe->T`
|
||||||
|
};
|
||||||
|
|
||||||
struct ZigType {
|
struct ZigType {
|
||||||
ZigTypeId id;
|
ZigTypeId id;
|
||||||
Buf name;
|
Buf name;
|
||||||
@ -1298,11 +1309,13 @@ struct ZigType {
|
|||||||
ZigTypeVector vector;
|
ZigTypeVector vector;
|
||||||
ZigTypeOpaque opaque;
|
ZigTypeOpaque opaque;
|
||||||
ZigTypeCoroFrame frame;
|
ZigTypeCoroFrame frame;
|
||||||
|
ZigTypeAnyFrame any_frame;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
// use these fields to make sure we don't duplicate type table entries for the same type
|
// use these fields to make sure we don't duplicate type table entries for the same type
|
||||||
ZigType *pointer_parent[2]; // [0 - mut, 1 - const]
|
ZigType *pointer_parent[2]; // [0 - mut, 1 - const]
|
||||||
ZigType *optional_parent;
|
ZigType *optional_parent;
|
||||||
|
ZigType *any_frame_parent;
|
||||||
// If we generate a constant name value for this type, we memoize it here.
|
// If we generate a constant name value for this type, we memoize it here.
|
||||||
// The type of this is array
|
// The type of this is array
|
||||||
ConstExprValue *cached_const_name_val;
|
ConstExprValue *cached_const_name_val;
|
||||||
@ -1781,6 +1794,7 @@ struct CodeGen {
|
|||||||
ZigType *entry_arg_tuple;
|
ZigType *entry_arg_tuple;
|
||||||
ZigType *entry_enum_literal;
|
ZigType *entry_enum_literal;
|
||||||
ZigType *entry_frame_header;
|
ZigType *entry_frame_header;
|
||||||
|
ZigType *entry_any_frame;
|
||||||
} builtin_types;
|
} builtin_types;
|
||||||
ZigType *align_amt_type;
|
ZigType *align_amt_type;
|
||||||
ZigType *stack_trace_type;
|
ZigType *stack_trace_type;
|
||||||
@ -2208,6 +2222,7 @@ enum IrInstructionId {
|
|||||||
IrInstructionIdSetRuntimeSafety,
|
IrInstructionIdSetRuntimeSafety,
|
||||||
IrInstructionIdSetFloatMode,
|
IrInstructionIdSetFloatMode,
|
||||||
IrInstructionIdArrayType,
|
IrInstructionIdArrayType,
|
||||||
|
IrInstructionIdAnyFrameType,
|
||||||
IrInstructionIdSliceType,
|
IrInstructionIdSliceType,
|
||||||
IrInstructionIdGlobalAsm,
|
IrInstructionIdGlobalAsm,
|
||||||
IrInstructionIdAsm,
|
IrInstructionIdAsm,
|
||||||
@ -2709,6 +2724,12 @@ struct IrInstructionPtrType {
|
|||||||
bool is_allow_zero;
|
bool is_allow_zero;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IrInstructionAnyFrameType {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *payload_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct IrInstructionSliceType {
|
struct IrInstructionSliceType {
|
||||||
IrInstruction base;
|
IrInstruction base;
|
||||||
|
|
||||||
|
|||||||
111
src/analyze.cpp
111
src/analyze.cpp
@ -256,6 +256,7 @@ AstNode *type_decl_node(ZigType *type_entry) {
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -322,6 +323,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -354,6 +356,31 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
|
|||||||
return get_int_type(g, false, bits_needed_for_unsigned(x));
|
return get_int_type(g, false, bits_needed_for_unsigned(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type) {
|
||||||
|
if (result_type != nullptr && result_type->any_frame_parent != nullptr) {
|
||||||
|
return result_type->any_frame_parent;
|
||||||
|
} else if (result_type == nullptr && g->builtin_types.entry_any_frame != nullptr) {
|
||||||
|
return g->builtin_types.entry_any_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigType *entry = new_type_table_entry(ZigTypeIdAnyFrame);
|
||||||
|
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||||
|
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
|
||||||
|
entry->abi_align = g->builtin_types.entry_usize->abi_align;
|
||||||
|
entry->data.any_frame.result_type = result_type;
|
||||||
|
buf_init_from_str(&entry->name, "anyframe");
|
||||||
|
if (result_type != nullptr) {
|
||||||
|
buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result_type != nullptr) {
|
||||||
|
result_type->any_frame_parent = entry;
|
||||||
|
} else if (result_type == nullptr) {
|
||||||
|
g->builtin_types.entry_any_frame = entry;
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *ptr_len_to_star_str(PtrLen ptr_len) {
|
static const char *ptr_len_to_star_str(PtrLen ptr_len) {
|
||||||
switch (ptr_len) {
|
switch (ptr_len) {
|
||||||
case PtrLenSingle:
|
case PtrLenSingle:
|
||||||
@ -1080,6 +1107,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
|||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
add_node_error(g, source_node,
|
add_node_error(g, source_node,
|
||||||
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||||
buf_ptr(&type_entry->name)));
|
buf_ptr(&type_entry->name)));
|
||||||
@ -1169,6 +1197,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
|
|||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdVoid:
|
case ZigTypeIdVoid:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return false;
|
return false;
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
@ -1340,6 +1369,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
switch (type_requires_comptime(g, type_entry)) {
|
switch (type_requires_comptime(g, type_entry)) {
|
||||||
case ReqCompTimeNo:
|
case ReqCompTimeNo:
|
||||||
break;
|
break;
|
||||||
@ -1436,6 +1466,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
switch (type_requires_comptime(g, fn_type_id.return_type)) {
|
switch (type_requires_comptime(g, fn_type_id.return_type)) {
|
||||||
case ReqCompTimeInvalid:
|
case ReqCompTimeInvalid:
|
||||||
return g->builtin_types.entry_invalid;
|
return g->builtin_types.entry_invalid;
|
||||||
@ -2997,6 +3028,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
|||||||
case NodeTypeAwaitExpr:
|
case NodeTypeAwaitExpr:
|
||||||
case NodeTypeSuspend:
|
case NodeTypeSuspend:
|
||||||
case NodeTypeEnumLiteral:
|
case NodeTypeEnumLiteral:
|
||||||
|
case NodeTypeAnyFrameType:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3049,6 +3081,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return type_entry;
|
return type_entry;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -3550,6 +3583,7 @@ bool is_container(ZigType *type_entry) {
|
|||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -3607,6 +3641,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
|
|||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -3615,11 +3650,13 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
|
|||||||
ZigType *get_src_ptr_type(ZigType *type) {
|
ZigType *get_src_ptr_type(ZigType *type) {
|
||||||
if (type->id == ZigTypeIdPointer) return type;
|
if (type->id == ZigTypeIdPointer) return type;
|
||||||
if (type->id == ZigTypeIdFn) return type;
|
if (type->id == ZigTypeIdFn) return type;
|
||||||
|
if (type->id == ZigTypeIdAnyFrame) return type;
|
||||||
if (type->id == ZigTypeIdOptional) {
|
if (type->id == ZigTypeIdOptional) {
|
||||||
if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
|
if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
|
||||||
return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
|
return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
|
||||||
}
|
}
|
||||||
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
|
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
|
||||||
|
if (type->data.maybe.child_type->id == ZigTypeIdAnyFrame) return type->data.maybe.child_type;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -3635,6 +3672,13 @@ bool type_is_nonnull_ptr(ZigType *type) {
|
|||||||
return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type);
|
return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t get_coro_frame_align_bytes(CodeGen *g) {
|
||||||
|
uint32_t a = g->pointer_size_bytes * 2;
|
||||||
|
// promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw
|
||||||
|
if (a < 8) a = 8;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
||||||
ZigType *ptr_type = get_src_ptr_type(type);
|
ZigType *ptr_type = get_src_ptr_type(type);
|
||||||
if (ptr_type->id == ZigTypeIdPointer) {
|
if (ptr_type->id == ZigTypeIdPointer) {
|
||||||
@ -3646,6 +3690,8 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
|||||||
// when getting the alignment of `?extern fn() void`.
|
// when getting the alignment of `?extern fn() void`.
|
||||||
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
|
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
|
||||||
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
|
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
|
||||||
|
} else if (ptr_type->id == ZigTypeIdAnyFrame) {
|
||||||
|
return get_coro_frame_align_bytes(g);
|
||||||
} else {
|
} else {
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -3657,6 +3703,8 @@ bool get_ptr_const(ZigType *type) {
|
|||||||
return ptr_type->data.pointer.is_const;
|
return ptr_type->data.pointer.is_const;
|
||||||
} else if (ptr_type->id == ZigTypeIdFn) {
|
} else if (ptr_type->id == ZigTypeIdFn) {
|
||||||
return true;
|
return true;
|
||||||
|
} else if (ptr_type->id == ZigTypeIdAnyFrame) {
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -4153,6 +4201,7 @@ bool handle_is_ptr(ZigType *type_entry) {
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdEnum:
|
case ZigTypeIdEnum:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return false;
|
return false;
|
||||||
case ZigTypeIdArray:
|
case ZigTypeIdArray:
|
||||||
case ZigTypeIdStruct:
|
case ZigTypeIdStruct:
|
||||||
@ -4404,6 +4453,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
|
|||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
// TODO better hashing algorithm
|
// TODO better hashing algorithm
|
||||||
return 675741936;
|
return 675741936;
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
// TODO better hashing algorithm
|
||||||
|
return 3747294894;
|
||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdInvalid:
|
case ZigTypeIdInvalid:
|
||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
@ -4469,6 +4521,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
|
|||||||
case ZigTypeIdErrorSet:
|
case ZigTypeIdErrorSet:
|
||||||
case ZigTypeIdEnum:
|
case ZigTypeIdEnum:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case ZigTypeIdPointer:
|
case ZigTypeIdPointer:
|
||||||
@ -4541,6 +4594,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
|
|||||||
case ZigTypeIdPointer:
|
case ZigTypeIdPointer:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ZigTypeIdArray:
|
case ZigTypeIdArray:
|
||||||
@ -4673,6 +4727,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
|||||||
case ZigTypeIdFloat:
|
case ZigTypeIdFloat:
|
||||||
case ZigTypeIdErrorUnion:
|
case ZigTypeIdErrorUnion:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return OnePossibleValueNo;
|
return OnePossibleValueNo;
|
||||||
case ZigTypeIdUndefined:
|
case ZigTypeIdUndefined:
|
||||||
case ZigTypeIdNull:
|
case ZigTypeIdNull:
|
||||||
@ -4761,6 +4816,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
|
|||||||
case ZigTypeIdVoid:
|
case ZigTypeIdVoid:
|
||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return ReqCompTimeNo;
|
return ReqCompTimeNo;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
@ -5433,6 +5489,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
|
|||||||
return true;
|
return true;
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO");
|
zig_panic("TODO");
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
zig_panic("TODO");
|
||||||
case ZigTypeIdUndefined:
|
case ZigTypeIdUndefined:
|
||||||
zig_panic("TODO");
|
zig_panic("TODO");
|
||||||
case ZigTypeIdNull:
|
case ZigTypeIdNull:
|
||||||
@ -5786,7 +5844,11 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
buf_appendf(buf, "(TODO: coroutine frame value)");
|
buf_appendf(buf, "(TODO: async function frame value)");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
buf_appendf(buf, "(TODO: anyframe value)");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5836,6 +5898,7 @@ uint32_t type_id_hash(TypeId x) {
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case ZigTypeIdErrorUnion:
|
case ZigTypeIdErrorUnion:
|
||||||
return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
|
return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
|
||||||
@ -5885,6 +5948,7 @@ bool type_id_eql(TypeId a, TypeId b) {
|
|||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case ZigTypeIdErrorUnion:
|
case ZigTypeIdErrorUnion:
|
||||||
return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
|
return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
|
||||||
@ -6051,6 +6115,7 @@ static const ZigTypeId all_type_ids[] = {
|
|||||||
ZigTypeIdArgTuple,
|
ZigTypeIdArgTuple,
|
||||||
ZigTypeIdOpaque,
|
ZigTypeIdOpaque,
|
||||||
ZigTypeIdCoroFrame,
|
ZigTypeIdCoroFrame,
|
||||||
|
ZigTypeIdAnyFrame,
|
||||||
ZigTypeIdVector,
|
ZigTypeIdVector,
|
||||||
ZigTypeIdEnumLiteral,
|
ZigTypeIdEnumLiteral,
|
||||||
};
|
};
|
||||||
@ -6116,10 +6181,12 @@ size_t type_id_index(ZigType *entry) {
|
|||||||
return 21;
|
return 21;
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
return 22;
|
return 22;
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdAnyFrame:
|
||||||
return 23;
|
return 23;
|
||||||
case ZigTypeIdEnumLiteral:
|
case ZigTypeIdVector:
|
||||||
return 24;
|
return 24;
|
||||||
|
case ZigTypeIdEnumLiteral:
|
||||||
|
return 25;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -6178,6 +6245,8 @@ const char *type_id_name(ZigTypeId id) {
|
|||||||
return "Vector";
|
return "Vector";
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
return "Frame";
|
return "Frame";
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
return "AnyFrame";
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -7398,6 +7467,40 @@ static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, Resol
|
|||||||
frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
|
frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, ResolveStatus wanted_resolve_status) {
|
||||||
|
if (any_frame_type->llvm_di_type != nullptr) return;
|
||||||
|
|
||||||
|
ZigType *result_type = any_frame_type->data.any_frame.result_type;
|
||||||
|
Buf *name = buf_sprintf("(%s header)", buf_ptr(&any_frame_type->name));
|
||||||
|
|
||||||
|
ZigType *frame_header_type;
|
||||||
|
if (result_type == nullptr || !type_has_bits(result_type)) {
|
||||||
|
const char *field_names[] = {"resume_index", "fn_ptr", "awaiter"};
|
||||||
|
ZigType *field_types[] = {
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
};
|
||||||
|
frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 3);
|
||||||
|
} else {
|
||||||
|
ZigType *ptr_result_type = get_pointer_to_type(g, result_type, false);
|
||||||
|
|
||||||
|
const char *field_names[] = {"resume_index", "fn_ptr", "awaiter", "result_ptr", "result"};
|
||||||
|
ZigType *field_types[] = {
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
g->builtin_types.entry_usize,
|
||||||
|
ptr_result_type,
|
||||||
|
result_type,
|
||||||
|
};
|
||||||
|
frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigType *ptr_type = get_pointer_to_type(g, frame_header_type, false);
|
||||||
|
any_frame_type->llvm_type = get_llvm_type(g, ptr_type);
|
||||||
|
any_frame_type->llvm_di_type = get_llvm_di_type(g, ptr_type);
|
||||||
|
}
|
||||||
|
|
||||||
static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
|
static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
|
||||||
assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
|
assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
|
||||||
assert(wanted_resolve_status > ResolveStatusSizeKnown);
|
assert(wanted_resolve_status > ResolveStatusSizeKnown);
|
||||||
@ -7460,6 +7563,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
|
|||||||
}
|
}
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status);
|
return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status);
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
return resolve_llvm_types_any_frame(g, type, wanted_resolve_status);
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,7 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c
|
|||||||
ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
|
ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
|
||||||
ZigType *field_types[], size_t field_count);
|
ZigType *field_types[], size_t field_count);
|
||||||
ZigType *get_test_fn_type(CodeGen *g);
|
ZigType *get_test_fn_type(CodeGen *g);
|
||||||
|
ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
|
||||||
bool handle_is_ptr(ZigType *type_entry);
|
bool handle_is_ptr(ZigType *type_entry);
|
||||||
|
|
||||||
bool type_has_bits(ZigType *type_entry);
|
bool type_has_bits(ZigType *type_entry);
|
||||||
|
|||||||
@ -259,6 +259,8 @@ static const char *node_type_str(NodeType node_type) {
|
|||||||
return "Suspend";
|
return "Suspend";
|
||||||
case NodeTypePointerType:
|
case NodeTypePointerType:
|
||||||
return "PointerType";
|
return "PointerType";
|
||||||
|
case NodeTypeAnyFrameType:
|
||||||
|
return "AnyFrameType";
|
||||||
case NodeTypeEnumLiteral:
|
case NodeTypeEnumLiteral:
|
||||||
return "EnumLiteral";
|
return "EnumLiteral";
|
||||||
}
|
}
|
||||||
@ -847,6 +849,14 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
|||||||
render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
|
render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NodeTypeAnyFrameType: {
|
||||||
|
fprintf(ar->f, "anyframe");
|
||||||
|
if (node->data.anyframe_type.payload_type != nullptr) {
|
||||||
|
fprintf(ar->f, "->");
|
||||||
|
render_node_grouped(ar, node->data.anyframe_type.payload_type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NodeTypeErrorType:
|
case NodeTypeErrorType:
|
||||||
fprintf(ar->f, "anyerror");
|
fprintf(ar->f, "anyerror");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -4947,6 +4947,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||||||
case IrInstructionIdSetRuntimeSafety:
|
case IrInstructionIdSetRuntimeSafety:
|
||||||
case IrInstructionIdSetFloatMode:
|
case IrInstructionIdSetFloatMode:
|
||||||
case IrInstructionIdArrayType:
|
case IrInstructionIdArrayType:
|
||||||
|
case IrInstructionIdAnyFrameType:
|
||||||
case IrInstructionIdSliceType:
|
case IrInstructionIdSliceType:
|
||||||
case IrInstructionIdSizeOf:
|
case IrInstructionIdSizeOf:
|
||||||
case IrInstructionIdSwitchTarget:
|
case IrInstructionIdSwitchTarget:
|
||||||
@ -5438,7 +5439,9 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO bit pack a coroutine frame");
|
zig_panic("TODO bit pack an async function frame");
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
zig_panic("TODO bit pack an anyframe");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -5961,6 +5964,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
|
|||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO");
|
zig_panic("TODO");
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
zig_panic("TODO");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -7176,6 +7181,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
|||||||
" ArgTuple: void,\n"
|
" ArgTuple: void,\n"
|
||||||
" Opaque: void,\n"
|
" Opaque: void,\n"
|
||||||
" Frame: void,\n"
|
" Frame: void,\n"
|
||||||
|
" AnyFrame: AnyFrame,\n"
|
||||||
" Vector: Vector,\n"
|
" Vector: Vector,\n"
|
||||||
" EnumLiteral: void,\n"
|
" EnumLiteral: void,\n"
|
||||||
"\n\n"
|
"\n\n"
|
||||||
@ -7291,6 +7297,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
|||||||
" args: []FnArg,\n"
|
" args: []FnArg,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" pub const AnyFrame = struct {\n"
|
||||||
|
" child: ?type,\n"
|
||||||
|
" };\n"
|
||||||
|
"\n"
|
||||||
" pub const Vector = struct {\n"
|
" pub const Vector = struct {\n"
|
||||||
" len: comptime_int,\n"
|
" len: comptime_int,\n"
|
||||||
" child: type,\n"
|
" child: type,\n"
|
||||||
@ -8448,6 +8458,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
|
|||||||
case ZigTypeIdErrorUnion:
|
case ZigTypeIdErrorUnion:
|
||||||
case ZigTypeIdErrorSet:
|
case ZigTypeIdErrorSet:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case ZigTypeIdVoid:
|
case ZigTypeIdVoid:
|
||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
@ -8632,6 +8643,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
|
|||||||
case ZigTypeIdNull:
|
case ZigTypeIdNull:
|
||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8800,7 +8812,9 @@ static void gen_h_file(CodeGen *g) {
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
|
|
||||||
case ZigTypeIdEnum:
|
case ZigTypeIdEnum:
|
||||||
if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
|
if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
|
||||||
fprintf(out_h, "enum %s {\n", buf_ptr(type_h_name(type_entry)));
|
fprintf(out_h, "enum %s {\n", buf_ptr(type_h_name(type_entry)));
|
||||||
|
|||||||
86
src/ir.cpp
86
src/ir.cpp
@ -303,6 +303,7 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdErrorSet:
|
case ZigTypeIdErrorSet:
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return true;
|
return true;
|
||||||
case ZigTypeIdFloat:
|
case ZigTypeIdFloat:
|
||||||
return a->data.floating.bit_count == b->data.floating.bit_count;
|
return a->data.floating.bit_count == b->data.floating.bit_count;
|
||||||
@ -563,6 +564,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) {
|
|||||||
return IrInstructionIdArrayType;
|
return IrInstructionIdArrayType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) {
|
||||||
|
return IrInstructionIdAnyFrameType;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) {
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) {
|
||||||
return IrInstructionIdSliceType;
|
return IrInstructionIdSliceType;
|
||||||
}
|
}
|
||||||
@ -1696,6 +1701,16 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode
|
|||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||||
|
IrInstruction *payload_type)
|
||||||
|
{
|
||||||
|
IrInstructionAnyFrameType *instruction = ir_build_instruction<IrInstructionAnyFrameType>(irb, scope, source_node);
|
||||||
|
instruction->payload_type = payload_type;
|
||||||
|
|
||||||
|
if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block);
|
||||||
|
|
||||||
|
return &instruction->base;
|
||||||
|
}
|
||||||
static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||||
IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero)
|
IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero)
|
||||||
{
|
{
|
||||||
@ -6515,6 +6530,22 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) {
|
||||||
|
assert(node->type == NodeTypeAnyFrameType);
|
||||||
|
|
||||||
|
AstNode *payload_type_node = node->data.anyframe_type.payload_type;
|
||||||
|
IrInstruction *payload_type_value = nullptr;
|
||||||
|
|
||||||
|
if (payload_type_node != nullptr) {
|
||||||
|
payload_type_value = ir_gen_node(irb, payload_type_node, scope);
|
||||||
|
if (payload_type_value == irb->codegen->invalid_instruction)
|
||||||
|
return payload_type_value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ir_build_anyframe_type(irb, scope, node, payload_type_value);
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
|
static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
|
||||||
assert(node->type == NodeTypeUndefinedLiteral);
|
assert(node->type == NodeTypeUndefinedLiteral);
|
||||||
return ir_build_const_undefined(irb, scope, node);
|
return ir_build_const_undefined(irb, scope, node);
|
||||||
@ -7884,6 +7915,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
|
|||||||
return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
|
||||||
case NodeTypePointerType:
|
case NodeTypePointerType:
|
||||||
return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
|
||||||
|
case NodeTypeAnyFrameType:
|
||||||
|
return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc);
|
||||||
case NodeTypeStringLiteral:
|
case NodeTypeStringLiteral:
|
||||||
return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
|
||||||
case NodeTypeUndefinedLiteral:
|
case NodeTypeUndefinedLiteral:
|
||||||
@ -12775,6 +12808,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
|
|||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdEnum:
|
case ZigTypeIdEnum:
|
||||||
case ZigTypeIdEnumLiteral:
|
case ZigTypeIdEnumLiteral:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
operator_allowed = is_equality_cmp;
|
operator_allowed = is_equality_cmp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -14155,6 +14189,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
ir_add_error(ira, target,
|
ir_add_error(ira, target,
|
||||||
buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
|
buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
|
||||||
break;
|
break;
|
||||||
@ -14180,6 +14215,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdEnumLiteral:
|
case ZigTypeIdEnumLiteral:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
ir_add_error(ira, target,
|
ir_add_error(ira, target,
|
||||||
buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
|
buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
|
||||||
break;
|
break;
|
||||||
@ -15720,7 +15756,9 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdArgTuple:
|
case ZigTypeIdArgTuple:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
|
return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
|
||||||
|
|
||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
ir_add_error_node(ira, un_op_instruction->base.source_node,
|
ir_add_error_node(ira, un_op_instruction->base.source_node,
|
||||||
@ -17443,6 +17481,20 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
|
|||||||
return ir_const_void(ira, &instruction->base);
|
return ir_const_void(ira, &instruction->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira,
|
||||||
|
IrInstructionAnyFrameType *instruction)
|
||||||
|
{
|
||||||
|
ZigType *payload_type = nullptr;
|
||||||
|
if (instruction->payload_type != nullptr) {
|
||||||
|
payload_type = ir_resolve_type(ira, instruction->payload_type->child);
|
||||||
|
if (type_is_invalid(payload_type))
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type);
|
||||||
|
return ir_const_type(ira, &instruction->base, any_frame_type);
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
|
static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
|
||||||
IrInstructionSliceType *slice_type_instruction)
|
IrInstructionSliceType *slice_type_instruction)
|
||||||
{
|
{
|
||||||
@ -17492,6 +17544,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
{
|
{
|
||||||
ResolveStatus needed_status = (align_bytes == 0) ?
|
ResolveStatus needed_status = (align_bytes == 0) ?
|
||||||
ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
|
ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
|
||||||
@ -17607,6 +17660,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
|
|||||||
case ZigTypeIdBoundFn:
|
case ZigTypeIdBoundFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
{
|
{
|
||||||
if ((err = ensure_complete_type(ira->codegen, child_type)))
|
if ((err = ensure_complete_type(ira->codegen, child_type)))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
@ -17658,6 +17712,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
{
|
{
|
||||||
uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
|
uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
|
||||||
return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
|
return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
|
||||||
@ -18222,6 +18277,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
|
|||||||
case ZigTypeIdOpaque:
|
case ZigTypeIdOpaque:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
ir_add_error(ira, &switch_target_instruction->base,
|
ir_add_error(ira, &switch_target_instruction->base,
|
||||||
buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
|
buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
@ -19656,6 +19712,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ZigTypeIdAnyFrame: {
|
||||||
|
result = create_const_vals(1);
|
||||||
|
result->special = ConstValSpecialStatic;
|
||||||
|
result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);
|
||||||
|
|
||||||
|
ConstExprValue *fields = create_const_vals(1);
|
||||||
|
result->data.x_struct.fields = fields;
|
||||||
|
|
||||||
|
// child: ?type
|
||||||
|
ensure_field_index(result->type, "child", 0);
|
||||||
|
fields[0].special = ConstValSpecialStatic;
|
||||||
|
fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
|
fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :
|
||||||
|
create_const_type(ira->codegen, type_entry->data.any_frame.result_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ZigTypeIdEnum:
|
case ZigTypeIdEnum:
|
||||||
{
|
{
|
||||||
result = create_const_vals(1);
|
result = create_const_vals(1);
|
||||||
@ -20062,7 +20134,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO @typeInfo for coro frames");
|
zig_panic("TODO @typeInfo for async function frames");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
@ -21852,6 +21924,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
|
|||||||
case ZigTypeIdFn:
|
case ZigTypeIdFn:
|
||||||
case ZigTypeIdVector:
|
case ZigTypeIdVector:
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
{
|
{
|
||||||
uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
|
uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
|
||||||
return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
|
return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
|
||||||
@ -23004,7 +23077,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
|
|||||||
case ZigTypeIdUnion:
|
case ZigTypeIdUnion:
|
||||||
zig_panic("TODO buf_write_value_bytes union type");
|
zig_panic("TODO buf_write_value_bytes union type");
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO buf_write_value_bytes coro frame type");
|
zig_panic("TODO buf_write_value_bytes async fn frame type");
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
zig_panic("TODO buf_write_value_bytes anyframe type");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -23185,7 +23260,9 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
|
|||||||
case ZigTypeIdUnion:
|
case ZigTypeIdUnion:
|
||||||
zig_panic("TODO buf_read_value_bytes union type");
|
zig_panic("TODO buf_read_value_bytes union type");
|
||||||
case ZigTypeIdCoroFrame:
|
case ZigTypeIdCoroFrame:
|
||||||
zig_panic("TODO buf_read_value_bytes coro frame type");
|
zig_panic("TODO buf_read_value_bytes async fn frame type");
|
||||||
|
case ZigTypeIdAnyFrame:
|
||||||
|
zig_panic("TODO buf_read_value_bytes anyframe type");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -24327,6 +24404,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
|
|||||||
return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
|
return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
|
||||||
case IrInstructionIdSetFloatMode:
|
case IrInstructionIdSetFloatMode:
|
||||||
return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
|
return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
|
||||||
|
case IrInstructionIdAnyFrameType:
|
||||||
|
return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction);
|
||||||
case IrInstructionIdSliceType:
|
case IrInstructionIdSliceType:
|
||||||
return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction);
|
return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction);
|
||||||
case IrInstructionIdGlobalAsm:
|
case IrInstructionIdGlobalAsm:
|
||||||
@ -24707,6 +24786,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
|||||||
case IrInstructionIdStructFieldPtr:
|
case IrInstructionIdStructFieldPtr:
|
||||||
case IrInstructionIdArrayType:
|
case IrInstructionIdArrayType:
|
||||||
case IrInstructionIdSliceType:
|
case IrInstructionIdSliceType:
|
||||||
|
case IrInstructionIdAnyFrameType:
|
||||||
case IrInstructionIdSizeOf:
|
case IrInstructionIdSizeOf:
|
||||||
case IrInstructionIdTestNonNull:
|
case IrInstructionIdTestNonNull:
|
||||||
case IrInstructionIdOptionalUnwrapPtr:
|
case IrInstructionIdOptionalUnwrapPtr:
|
||||||
|
|||||||
@ -471,6 +471,15 @@ static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instructio
|
|||||||
ir_print_other_instruction(irp, instruction->child_type);
|
ir_print_other_instruction(irp, instruction->child_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ir_print_any_frame_type(IrPrint *irp, IrInstructionAnyFrameType *instruction) {
|
||||||
|
if (instruction->payload_type == nullptr) {
|
||||||
|
fprintf(irp->f, "anyframe");
|
||||||
|
} else {
|
||||||
|
fprintf(irp->f, "anyframe->");
|
||||||
|
ir_print_other_instruction(irp, instruction->payload_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ir_print_global_asm(IrPrint *irp, IrInstructionGlobalAsm *instruction) {
|
static void ir_print_global_asm(IrPrint *irp, IrInstructionGlobalAsm *instruction) {
|
||||||
fprintf(irp->f, "asm(\"%s\")", buf_ptr(instruction->asm_code));
|
fprintf(irp->f, "asm(\"%s\")", buf_ptr(instruction->asm_code));
|
||||||
}
|
}
|
||||||
@ -1629,6 +1638,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
|||||||
case IrInstructionIdSliceType:
|
case IrInstructionIdSliceType:
|
||||||
ir_print_slice_type(irp, (IrInstructionSliceType *)instruction);
|
ir_print_slice_type(irp, (IrInstructionSliceType *)instruction);
|
||||||
break;
|
break;
|
||||||
|
case IrInstructionIdAnyFrameType:
|
||||||
|
ir_print_any_frame_type(irp, (IrInstructionAnyFrameType *)instruction);
|
||||||
|
break;
|
||||||
case IrInstructionIdGlobalAsm:
|
case IrInstructionIdGlobalAsm:
|
||||||
ir_print_global_asm(irp, (IrInstructionGlobalAsm *)instruction);
|
ir_print_global_asm(irp, (IrInstructionGlobalAsm *)instruction);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -282,6 +282,9 @@ static AstNode *ast_parse_prefix_op_expr(
|
|||||||
case NodeTypeAwaitExpr:
|
case NodeTypeAwaitExpr:
|
||||||
right = &prefix->data.await_expr.expr;
|
right = &prefix->data.await_expr.expr;
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeAnyFrameType:
|
||||||
|
right = &prefix->data.anyframe_type.payload_type;
|
||||||
|
break;
|
||||||
case NodeTypeArrayType:
|
case NodeTypeArrayType:
|
||||||
right = &prefix->data.array_type.child_type;
|
right = &prefix->data.array_type.child_type;
|
||||||
break;
|
break;
|
||||||
@ -1640,6 +1643,10 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
|
|||||||
if (null != nullptr)
|
if (null != nullptr)
|
||||||
return ast_create_node(pc, NodeTypeNullLiteral, null);
|
return ast_create_node(pc, NodeTypeNullLiteral, null);
|
||||||
|
|
||||||
|
Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
|
||||||
|
if (anyframe != nullptr)
|
||||||
|
return ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
|
||||||
|
|
||||||
Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
|
Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
|
||||||
if (true_token != nullptr) {
|
if (true_token != nullptr) {
|
||||||
AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
|
AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
|
||||||
@ -2510,7 +2517,7 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
|
|||||||
|
|
||||||
// PrefixTypeOp
|
// PrefixTypeOp
|
||||||
// <- QUESTIONMARK
|
// <- QUESTIONMARK
|
||||||
// / KEYWORD_promise MINUSRARROW
|
// / KEYWORD_anyframe MINUSRARROW
|
||||||
// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
|
// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
|
||||||
// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
|
// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
|
||||||
static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
|
static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
|
||||||
@ -2521,6 +2528,16 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
|
||||||
|
if (anyframe != nullptr) {
|
||||||
|
if (eat_token_if(pc, TokenIdArrow) != nullptr) {
|
||||||
|
AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
put_back_token(pc);
|
||||||
|
}
|
||||||
|
|
||||||
AstNode *array = ast_parse_array_type_start(pc);
|
AstNode *array = ast_parse_array_type_start(pc);
|
||||||
if (array != nullptr) {
|
if (array != nullptr) {
|
||||||
assert(array->type == NodeTypeArrayType);
|
assert(array->type == NodeTypeArrayType);
|
||||||
@ -3005,6 +3022,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
|||||||
case NodeTypeInferredArrayType:
|
case NodeTypeInferredArrayType:
|
||||||
visit_field(&node->data.array_type.child_type, visit, context);
|
visit_field(&node->data.array_type.child_type, visit, context);
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeAnyFrameType:
|
||||||
|
visit_field(&node->data.anyframe_type.payload_type, visit, context);
|
||||||
|
break;
|
||||||
case NodeTypeErrorType:
|
case NodeTypeErrorType:
|
||||||
// none
|
// none
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -109,6 +109,7 @@ static const struct ZigKeyword zig_keywords[] = {
|
|||||||
{"align", TokenIdKeywordAlign},
|
{"align", TokenIdKeywordAlign},
|
||||||
{"allowzero", TokenIdKeywordAllowZero},
|
{"allowzero", TokenIdKeywordAllowZero},
|
||||||
{"and", TokenIdKeywordAnd},
|
{"and", TokenIdKeywordAnd},
|
||||||
|
{"anyframe", TokenIdKeywordAnyFrame},
|
||||||
{"asm", TokenIdKeywordAsm},
|
{"asm", TokenIdKeywordAsm},
|
||||||
{"async", TokenIdKeywordAsync},
|
{"async", TokenIdKeywordAsync},
|
||||||
{"await", TokenIdKeywordAwait},
|
{"await", TokenIdKeywordAwait},
|
||||||
@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) {
|
|||||||
case TokenIdKeywordCancel: return "cancel";
|
case TokenIdKeywordCancel: return "cancel";
|
||||||
case TokenIdKeywordAlign: return "align";
|
case TokenIdKeywordAlign: return "align";
|
||||||
case TokenIdKeywordAnd: return "and";
|
case TokenIdKeywordAnd: return "and";
|
||||||
|
case TokenIdKeywordAnyFrame: return "anyframe";
|
||||||
case TokenIdKeywordAsm: return "asm";
|
case TokenIdKeywordAsm: return "asm";
|
||||||
case TokenIdKeywordBreak: return "break";
|
case TokenIdKeywordBreak: return "break";
|
||||||
case TokenIdKeywordCatch: return "catch";
|
case TokenIdKeywordCatch: return "catch";
|
||||||
|
|||||||
@ -53,6 +53,7 @@ enum TokenId {
|
|||||||
TokenIdKeywordAlign,
|
TokenIdKeywordAlign,
|
||||||
TokenIdKeywordAllowZero,
|
TokenIdKeywordAllowZero,
|
||||||
TokenIdKeywordAnd,
|
TokenIdKeywordAnd,
|
||||||
|
TokenIdKeywordAnyFrame,
|
||||||
TokenIdKeywordAsm,
|
TokenIdKeywordAsm,
|
||||||
TokenIdKeywordAsync,
|
TokenIdKeywordAsync,
|
||||||
TokenIdKeywordAwait,
|
TokenIdKeywordAwait,
|
||||||
|
|||||||
@ -540,6 +540,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
|
|||||||
.Undefined,
|
.Undefined,
|
||||||
.ArgTuple,
|
.ArgTuple,
|
||||||
.Frame,
|
.Frame,
|
||||||
|
.AnyFrame,
|
||||||
=> @compileError("cannot hash this type"),
|
=> @compileError("cannot hash this type"),
|
||||||
|
|
||||||
.Void,
|
.Void,
|
||||||
|
|||||||
@ -30,6 +30,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
|
|||||||
.ArgTuple,
|
.ArgTuple,
|
||||||
.Opaque,
|
.Opaque,
|
||||||
.Frame,
|
.Frame,
|
||||||
|
.AnyFrame,
|
||||||
=> @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"),
|
=> @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"),
|
||||||
|
|
||||||
.Undefined,
|
.Undefined,
|
||||||
|
|||||||
@ -400,7 +400,7 @@ pub const Node = struct {
|
|||||||
VarType,
|
VarType,
|
||||||
ErrorType,
|
ErrorType,
|
||||||
FnProto,
|
FnProto,
|
||||||
PromiseType,
|
AnyFrameType,
|
||||||
|
|
||||||
// Primary expressions
|
// Primary expressions
|
||||||
IntegerLiteral,
|
IntegerLiteral,
|
||||||
@ -952,9 +952,9 @@ pub const Node = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PromiseType = struct {
|
pub const AnyFrameType = struct {
|
||||||
base: Node,
|
base: Node,
|
||||||
promise_token: TokenIndex,
|
anyframe_token: TokenIndex,
|
||||||
result: ?Result,
|
result: ?Result,
|
||||||
|
|
||||||
pub const Result = struct {
|
pub const Result = struct {
|
||||||
@ -962,7 +962,7 @@ pub const Node = struct {
|
|||||||
return_type: *Node,
|
return_type: *Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn iterate(self: *PromiseType, index: usize) ?*Node {
|
pub fn iterate(self: *AnyFrameType, index: usize) ?*Node {
|
||||||
var i = index;
|
var i = index;
|
||||||
|
|
||||||
if (self.result) |result| {
|
if (self.result) |result| {
|
||||||
@ -973,13 +973,13 @@ pub const Node = struct {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn firstToken(self: *const PromiseType) TokenIndex {
|
pub fn firstToken(self: *const AnyFrameType) TokenIndex {
|
||||||
return self.promise_token;
|
return self.anyframe_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lastToken(self: *const PromiseType) TokenIndex {
|
pub fn lastToken(self: *const AnyFrameType) TokenIndex {
|
||||||
if (self.result) |result| return result.return_type.lastToken();
|
if (self.result) |result| return result.return_type.lastToken();
|
||||||
return self.promise_token;
|
return self.anyframe_token;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1201,7 +1201,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||||||
/// / KEYWORD_error DOT IDENTIFIER
|
/// / KEYWORD_error DOT IDENTIFIER
|
||||||
/// / KEYWORD_false
|
/// / KEYWORD_false
|
||||||
/// / KEYWORD_null
|
/// / KEYWORD_null
|
||||||
/// / KEYWORD_promise
|
/// / KEYWORD_anyframe
|
||||||
/// / KEYWORD_true
|
/// / KEYWORD_true
|
||||||
/// / KEYWORD_undefined
|
/// / KEYWORD_undefined
|
||||||
/// / KEYWORD_unreachable
|
/// / KEYWORD_unreachable
|
||||||
@ -1256,11 +1256,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
|
|||||||
}
|
}
|
||||||
if (eatToken(it, .Keyword_false)) |token| return createLiteral(arena, Node.BoolLiteral, token);
|
if (eatToken(it, .Keyword_false)) |token| return createLiteral(arena, Node.BoolLiteral, token);
|
||||||
if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);
|
if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);
|
||||||
if (eatToken(it, .Keyword_promise)) |token| {
|
if (eatToken(it, .Keyword_anyframe)) |token| {
|
||||||
const node = try arena.create(Node.PromiseType);
|
const node = try arena.create(Node.AnyFrameType);
|
||||||
node.* = Node.PromiseType{
|
node.* = Node.AnyFrameType{
|
||||||
.base = Node{ .id = .PromiseType },
|
.base = Node{ .id = .AnyFrameType },
|
||||||
.promise_token = token,
|
.anyframe_token = token,
|
||||||
.result = null,
|
.result = null,
|
||||||
};
|
};
|
||||||
return &node.base;
|
return &node.base;
|
||||||
@ -2194,7 +2194,7 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||||||
|
|
||||||
/// PrefixTypeOp
|
/// PrefixTypeOp
|
||||||
/// <- QUESTIONMARK
|
/// <- QUESTIONMARK
|
||||||
/// / KEYWORD_promise MINUSRARROW
|
/// / KEYWORD_anyframe MINUSRARROW
|
||||||
/// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
/// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||||
/// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
/// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||||
fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||||
@ -2209,20 +2209,20 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
|
|||||||
return &node.base;
|
return &node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Returning a PromiseType instead of PrefixOp makes casting and setting .rhs or
|
// TODO: Returning a AnyFrameType instead of PrefixOp makes casting and setting .rhs or
|
||||||
// .return_type more difficult for the caller (see parsePrefixOpExpr helper).
|
// .return_type more difficult for the caller (see parsePrefixOpExpr helper).
|
||||||
// Consider making the PromiseType a member of PrefixOp and add a
|
// Consider making the AnyFrameType a member of PrefixOp and add a
|
||||||
// PrefixOp.PromiseType variant?
|
// PrefixOp.AnyFrameType variant?
|
||||||
if (eatToken(it, .Keyword_promise)) |token| {
|
if (eatToken(it, .Keyword_anyframe)) |token| {
|
||||||
const arrow = eatToken(it, .Arrow) orelse {
|
const arrow = eatToken(it, .Arrow) orelse {
|
||||||
putBackToken(it, token);
|
putBackToken(it, token);
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
const node = try arena.create(Node.PromiseType);
|
const node = try arena.create(Node.AnyFrameType);
|
||||||
node.* = Node.PromiseType{
|
node.* = Node.AnyFrameType{
|
||||||
.base = Node{ .id = .PromiseType },
|
.base = Node{ .id = .AnyFrameType },
|
||||||
.promise_token = token,
|
.anyframe_token = token,
|
||||||
.result = Node.PromiseType.Result{
|
.result = Node.AnyFrameType.Result{
|
||||||
.arrow_token = arrow,
|
.arrow_token = arrow,
|
||||||
.return_type = undefined, // set by caller
|
.return_type = undefined, // set by caller
|
||||||
},
|
},
|
||||||
@ -2903,8 +2903,8 @@ fn parsePrefixOpExpr(
|
|||||||
rightmost_op = rhs;
|
rightmost_op = rhs;
|
||||||
} else break;
|
} else break;
|
||||||
},
|
},
|
||||||
.PromiseType => {
|
.AnyFrameType => {
|
||||||
const prom = rightmost_op.cast(Node.PromiseType).?;
|
const prom = rightmost_op.cast(Node.AnyFrameType).?;
|
||||||
if (try opParseFn(arena, it, tree)) |rhs| {
|
if (try opParseFn(arena, it, tree)) |rhs| {
|
||||||
prom.result.?.return_type = rhs;
|
prom.result.?.return_type = rhs;
|
||||||
rightmost_op = rhs;
|
rightmost_op = rhs;
|
||||||
@ -2922,8 +2922,8 @@ fn parsePrefixOpExpr(
|
|||||||
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.PromiseType => {
|
.AnyFrameType => {
|
||||||
const prom = rightmost_op.cast(Node.PromiseType).?;
|
const prom = rightmost_op.cast(Node.AnyFrameType).?;
|
||||||
prom.result.?.return_type = try expectNode(arena, it, tree, childParseFn, AstError{
|
prom.result.?.return_type = try expectNode(arena, it, tree, childParseFn, AstError{
|
||||||
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2111,12 +2111,12 @@ test "zig fmt: coroutines" {
|
|||||||
\\ suspend;
|
\\ suspend;
|
||||||
\\ x += 1;
|
\\ x += 1;
|
||||||
\\ suspend;
|
\\ suspend;
|
||||||
\\ const p: promise->void = async simpleAsyncFn() catch unreachable;
|
\\ const p: anyframe->void = async simpleAsyncFn() catch unreachable;
|
||||||
\\ await p;
|
\\ await p;
|
||||||
\\}
|
\\}
|
||||||
\\
|
\\
|
||||||
\\test "coroutine suspend, resume, cancel" {
|
\\test "coroutine suspend, resume, cancel" {
|
||||||
\\ const p: promise = try async<std.debug.global_allocator> testAsyncSeq();
|
\\ const p: anyframe = try async<std.debug.global_allocator> testAsyncSeq();
|
||||||
\\ resume p;
|
\\ resume p;
|
||||||
\\ cancel p;
|
\\ cancel p;
|
||||||
\\}
|
\\}
|
||||||
|
|||||||
@ -1205,15 +1205,15 @@ fn renderExpression(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ast.Node.Id.PromiseType => {
|
ast.Node.Id.AnyFrameType => {
|
||||||
const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
|
const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base);
|
||||||
|
|
||||||
if (promise_type.result) |result| {
|
if (anyframe_type.result) |result| {
|
||||||
try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise
|
try renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, Space.None); // anyframe
|
||||||
try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
|
try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
|
||||||
return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
|
return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
|
||||||
} else {
|
} else {
|
||||||
return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise
|
return renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, space); // anyframe
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ pub const Token = struct {
|
|||||||
Keyword{ .bytes = "align", .id = Id.Keyword_align },
|
Keyword{ .bytes = "align", .id = Id.Keyword_align },
|
||||||
Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero },
|
Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero },
|
||||||
Keyword{ .bytes = "and", .id = Id.Keyword_and },
|
Keyword{ .bytes = "and", .id = Id.Keyword_and },
|
||||||
|
Keyword{ .bytes = "anyframe", .id = Id.Keyword_anyframe },
|
||||||
Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
|
Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
|
||||||
Keyword{ .bytes = "async", .id = Id.Keyword_async },
|
Keyword{ .bytes = "async", .id = Id.Keyword_async },
|
||||||
Keyword{ .bytes = "await", .id = Id.Keyword_await },
|
Keyword{ .bytes = "await", .id = Id.Keyword_await },
|
||||||
@ -42,7 +43,6 @@ pub const Token = struct {
|
|||||||
Keyword{ .bytes = "or", .id = Id.Keyword_or },
|
Keyword{ .bytes = "or", .id = Id.Keyword_or },
|
||||||
Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse },
|
Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse },
|
||||||
Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
|
Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
|
||||||
Keyword{ .bytes = "promise", .id = Id.Keyword_promise },
|
|
||||||
Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
|
Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
|
||||||
Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
|
Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
|
||||||
Keyword{ .bytes = "return", .id = Id.Keyword_return },
|
Keyword{ .bytes = "return", .id = Id.Keyword_return },
|
||||||
@ -174,7 +174,7 @@ pub const Token = struct {
|
|||||||
Keyword_or,
|
Keyword_or,
|
||||||
Keyword_orelse,
|
Keyword_orelse,
|
||||||
Keyword_packed,
|
Keyword_packed,
|
||||||
Keyword_promise,
|
Keyword_anyframe,
|
||||||
Keyword_pub,
|
Keyword_pub,
|
||||||
Keyword_resume,
|
Keyword_resume,
|
||||||
Keyword_return,
|
Keyword_return,
|
||||||
|
|||||||
@ -177,11 +177,11 @@ fn testUnion() void {
|
|||||||
expect(TypeId(typeinfo_info) == TypeId.Union);
|
expect(TypeId(typeinfo_info) == TypeId.Union);
|
||||||
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||||
expect(typeinfo_info.Union.tag_type.? == TypeId);
|
expect(typeinfo_info.Union.tag_type.? == TypeId);
|
||||||
expect(typeinfo_info.Union.fields.len == 25);
|
expect(typeinfo_info.Union.fields.len == 26);
|
||||||
expect(typeinfo_info.Union.fields[4].enum_field != null);
|
expect(typeinfo_info.Union.fields[4].enum_field != null);
|
||||||
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
||||||
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
||||||
expect(typeinfo_info.Union.decls.len == 20);
|
expect(typeinfo_info.Union.decls.len == 21);
|
||||||
|
|
||||||
const TestNoTagUnion = union {
|
const TestNoTagUnion = union {
|
||||||
Foo: void,
|
Foo: void,
|
||||||
@ -280,6 +280,25 @@ fn testVector() void {
|
|||||||
expect(vec_info.Vector.child == i32);
|
expect(vec_info.Vector.child == i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "type info: anyframe and anyframe->T" {
|
||||||
|
testAnyFrame();
|
||||||
|
comptime testAnyFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testAnyFrame() void {
|
||||||
|
{
|
||||||
|
const anyframe_info = @typeInfo(anyframe->i32);
|
||||||
|
expect(TypeId(anyframe_info) == .AnyFrame);
|
||||||
|
expect(anyframe_info.AnyFrame.child.? == i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const anyframe_info = @typeInfo(anyframe);
|
||||||
|
expect(TypeId(anyframe_info) == .AnyFrame);
|
||||||
|
expect(anyframe_info.AnyFrame.child == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "type info: optional field unwrapping" {
|
test "type info: optional field unwrapping" {
|
||||||
const Struct = struct {
|
const Struct = struct {
|
||||||
cdOffset: u32,
|
cdOffset: u32,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user