| author | |
| committer | |
| log | ee64a22045ccbc39773779d4e386e25f563c8a90 |
| tree | 95263984be9a72a1c9cc102b55e715a83a38b8eb |
| parent | 018a89c7a1b2763a50375f6d6d168dfa1f877f6a |
| signature |
19 files changed, 337 insertions(+), 50 deletions(-)
BRANCH_TODO+3-3| ... | ... | @@ -1,6 +1,4 @@ |
| 1 | * reimplement @frameSize with Prefix Data | |
| 2 | * reimplement with function splitting rather than switch | |
| 3 | * add the `anyframe` type and `anyframe->T` | |
| 1 | * make the anyframe type and anyframe->T type work with resume | |
| 4 | 2 | * await |
| 5 | 3 | * await of a non async function |
| 6 | 4 | * await in single-threaded mode |
| ... | ... | @@ -12,3 +10,5 @@ |
| 12 | 10 | * implicit cast of normal function to async function should be allowed when it is inferred to be async |
| 13 | 11 | * go over the commented out tests |
| 14 | 12 | * revive std.event.Loop |
| 13 | * reimplement with function splitting rather than switch | |
| 14 | * @typeInfo for @Frame(func) |
src/all_types.hpp+21| ... | ... | @@ -479,6 +479,7 @@ enum NodeType { |
| 479 | 479 | NodeTypeResume, |
| 480 | 480 | NodeTypeAwaitExpr, |
| 481 | 481 | NodeTypeSuspend, |
| 482 | NodeTypeAnyFrameType, | |
| 482 | 483 | NodeTypeEnumLiteral, |
| 483 | 484 | }; |
| 484 | 485 | |
| ... | ... | @@ -936,6 +937,10 @@ struct AstNodeSuspend { |
| 936 | 937 | AstNode *block; |
| 937 | 938 | }; |
| 938 | 939 | |
| 940 | struct AstNodeAnyFrameType { | |
| 941 | AstNode *payload_type; // can be NULL | |
| 942 | }; | |
| 943 | ||
| 939 | 944 | struct AstNodeEnumLiteral { |
| 940 | 945 | Token *period; |
| 941 | 946 | Token *identifier; |
| ... | ... | @@ -1001,6 +1006,7 @@ struct AstNode { |
| 1001 | 1006 | AstNodeResumeExpr resume_expr; |
| 1002 | 1007 | AstNodeAwaitExpr await_expr; |
| 1003 | 1008 | AstNodeSuspend suspend; |
| 1009 | AstNodeAnyFrameType anyframe_type; | |
| 1004 | 1010 | AstNodeEnumLiteral enum_literal; |
| 1005 | 1011 | } data; |
| 1006 | 1012 | }; |
| ... | ... | @@ -1253,6 +1259,7 @@ enum ZigTypeId { |
| 1253 | 1259 | ZigTypeIdArgTuple, |
| 1254 | 1260 | ZigTypeIdOpaque, |
| 1255 | 1261 | ZigTypeIdCoroFrame, |
| 1262 | ZigTypeIdAnyFrame, | |
| 1256 | 1263 | ZigTypeIdVector, |
| 1257 | 1264 | ZigTypeIdEnumLiteral, |
| 1258 | 1265 | }; |
| ... | ... | @@ -1272,6 +1279,10 @@ struct ZigTypeCoroFrame { |
| 1272 | 1279 | ZigType *locals_struct; |
| 1273 | 1280 | }; |
| 1274 | 1281 | |
| 1282 | struct ZigTypeAnyFrame { | |
| 1283 | ZigType *result_type; // null if `anyframe` instead of `anyframe->T` | |
| 1284 | }; | |
| 1285 | ||
| 1275 | 1286 | struct ZigType { |
| 1276 | 1287 | ZigTypeId id; |
| 1277 | 1288 | Buf name; |
| ... | ... | @@ -1298,11 +1309,13 @@ struct ZigType { |
| 1298 | 1309 | ZigTypeVector vector; |
| 1299 | 1310 | ZigTypeOpaque opaque; |
| 1300 | 1311 | ZigTypeCoroFrame frame; |
| 1312 | ZigTypeAnyFrame any_frame; | |
| 1301 | 1313 | } data; |
| 1302 | 1314 | |
| 1303 | 1315 | // use these fields to make sure we don't duplicate type table entries for the same type |
| 1304 | 1316 | ZigType *pointer_parent[2]; // [0 - mut, 1 - const] |
| 1305 | 1317 | ZigType *optional_parent; |
| 1318 | ZigType *any_frame_parent; | |
| 1306 | 1319 | // If we generate a constant name value for this type, we memoize it here. |
| 1307 | 1320 | // The type of this is array |
| 1308 | 1321 | ConstExprValue *cached_const_name_val; |
| ... | ... | @@ -1781,6 +1794,7 @@ struct CodeGen { |
| 1781 | 1794 | ZigType *entry_arg_tuple; |
| 1782 | 1795 | ZigType *entry_enum_literal; |
| 1783 | 1796 | ZigType *entry_frame_header; |
| 1797 | ZigType *entry_any_frame; | |
| 1784 | 1798 | } builtin_types; |
| 1785 | 1799 | ZigType *align_amt_type; |
| 1786 | 1800 | ZigType *stack_trace_type; |
| ... | ... | @@ -2208,6 +2222,7 @@ enum IrInstructionId { |
| 2208 | 2222 | IrInstructionIdSetRuntimeSafety, |
| 2209 | 2223 | IrInstructionIdSetFloatMode, |
| 2210 | 2224 | IrInstructionIdArrayType, |
| 2225 | IrInstructionIdAnyFrameType, | |
| 2211 | 2226 | IrInstructionIdSliceType, |
| 2212 | 2227 | IrInstructionIdGlobalAsm, |
| 2213 | 2228 | IrInstructionIdAsm, |
| ... | ... | @@ -2709,6 +2724,12 @@ struct IrInstructionPtrType { |
| 2709 | 2724 | bool is_allow_zero; |
| 2710 | 2725 | }; |
| 2711 | 2726 | |
| 2727 | struct IrInstructionAnyFrameType { | |
| 2728 | IrInstruction base; | |
| 2729 | ||
| 2730 | IrInstruction *payload_type; | |
| 2731 | }; | |
| 2732 | ||
| 2712 | 2733 | struct IrInstructionSliceType { |
| 2713 | 2734 | IrInstruction base; |
| 2714 | 2735 |
src/analyze.cpp+108-3| ... | ... | @@ -256,6 +256,7 @@ AstNode *type_decl_node(ZigType *type_entry) { |
| 256 | 256 | case ZigTypeIdBoundFn: |
| 257 | 257 | case ZigTypeIdArgTuple: |
| 258 | 258 | case ZigTypeIdVector: |
| 259 | case ZigTypeIdAnyFrame: | |
| 259 | 260 | return nullptr; |
| 260 | 261 | } |
| 261 | 262 | zig_unreachable(); |
| ... | ... | @@ -322,6 +323,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 322 | 323 | case ZigTypeIdBoundFn: |
| 323 | 324 | case ZigTypeIdArgTuple: |
| 324 | 325 | case ZigTypeIdVector: |
| 326 | case ZigTypeIdAnyFrame: | |
| 325 | 327 | return true; |
| 326 | 328 | } |
| 327 | 329 | zig_unreachable(); |
| ... | ... | @@ -354,6 +356,31 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { |
| 354 | 356 | return get_int_type(g, false, bits_needed_for_unsigned(x)); |
| 355 | 357 | } |
| 356 | 358 | |
| 359 | ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type) { | |
| 360 | if (result_type != nullptr && result_type->any_frame_parent != nullptr) { | |
| 361 | return result_type->any_frame_parent; | |
| 362 | } else if (result_type == nullptr && g->builtin_types.entry_any_frame != nullptr) { | |
| 363 | return g->builtin_types.entry_any_frame; | |
| 364 | } | |
| 365 | ||
| 366 | ZigType *entry = new_type_table_entry(ZigTypeIdAnyFrame); | |
| 367 | entry->abi_size = g->builtin_types.entry_usize->abi_size; | |
| 368 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | |
| 369 | entry->abi_align = g->builtin_types.entry_usize->abi_align; | |
| 370 | entry->data.any_frame.result_type = result_type; | |
| 371 | buf_init_from_str(&entry->name, "anyframe"); | |
| 372 | if (result_type != nullptr) { | |
| 373 | buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name)); | |
| 374 | } | |
| 375 | ||
| 376 | if (result_type != nullptr) { | |
| 377 | result_type->any_frame_parent = entry; | |
| 378 | } else if (result_type == nullptr) { | |
| 379 | g->builtin_types.entry_any_frame = entry; | |
| 380 | } | |
| 381 | return entry; | |
| 382 | } | |
| 383 | ||
| 357 | 384 | static const char *ptr_len_to_star_str(PtrLen ptr_len) { |
| 358 | 385 | switch (ptr_len) { |
| 359 | 386 | case PtrLenSingle: |
| ... | ... | @@ -1080,6 +1107,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType |
| 1080 | 1107 | case ZigTypeIdArgTuple: |
| 1081 | 1108 | case ZigTypeIdOpaque: |
| 1082 | 1109 | case ZigTypeIdCoroFrame: |
| 1110 | case ZigTypeIdAnyFrame: | |
| 1083 | 1111 | add_node_error(g, source_node, |
| 1084 | 1112 | buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation", |
| 1085 | 1113 | buf_ptr(&type_entry->name))); |
| ... | ... | @@ -1169,6 +1197,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) { |
| 1169 | 1197 | case ZigTypeIdArgTuple: |
| 1170 | 1198 | case ZigTypeIdVoid: |
| 1171 | 1199 | case ZigTypeIdCoroFrame: |
| 1200 | case ZigTypeIdAnyFrame: | |
| 1172 | 1201 | return false; |
| 1173 | 1202 | case ZigTypeIdOpaque: |
| 1174 | 1203 | case ZigTypeIdUnreachable: |
| ... | ... | @@ -1340,6 +1369,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1340 | 1369 | case ZigTypeIdFn: |
| 1341 | 1370 | case ZigTypeIdVector: |
| 1342 | 1371 | case ZigTypeIdCoroFrame: |
| 1372 | case ZigTypeIdAnyFrame: | |
| 1343 | 1373 | switch (type_requires_comptime(g, type_entry)) { |
| 1344 | 1374 | case ReqCompTimeNo: |
| 1345 | 1375 | break; |
| ... | ... | @@ -1436,6 +1466,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1436 | 1466 | case ZigTypeIdFn: |
| 1437 | 1467 | case ZigTypeIdVector: |
| 1438 | 1468 | case ZigTypeIdCoroFrame: |
| 1469 | case ZigTypeIdAnyFrame: | |
| 1439 | 1470 | switch (type_requires_comptime(g, fn_type_id.return_type)) { |
| 1440 | 1471 | case ReqCompTimeInvalid: |
| 1441 | 1472 | return g->builtin_types.entry_invalid; |
| ... | ... | @@ -2997,6 +3028,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2997 | 3028 | case NodeTypeAwaitExpr: |
| 2998 | 3029 | case NodeTypeSuspend: |
| 2999 | 3030 | case NodeTypeEnumLiteral: |
| 3031 | case NodeTypeAnyFrameType: | |
| 3000 | 3032 | zig_unreachable(); |
| 3001 | 3033 | } |
| 3002 | 3034 | } |
| ... | ... | @@ -3049,6 +3081,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry |
| 3049 | 3081 | case ZigTypeIdBoundFn: |
| 3050 | 3082 | case ZigTypeIdVector: |
| 3051 | 3083 | case ZigTypeIdCoroFrame: |
| 3084 | case ZigTypeIdAnyFrame: | |
| 3052 | 3085 | return type_entry; |
| 3053 | 3086 | } |
| 3054 | 3087 | zig_unreachable(); |
| ... | ... | @@ -3550,6 +3583,7 @@ bool is_container(ZigType *type_entry) { |
| 3550 | 3583 | case ZigTypeIdOpaque: |
| 3551 | 3584 | case ZigTypeIdVector: |
| 3552 | 3585 | case ZigTypeIdCoroFrame: |
| 3586 | case ZigTypeIdAnyFrame: | |
| 3553 | 3587 | return false; |
| 3554 | 3588 | } |
| 3555 | 3589 | zig_unreachable(); |
| ... | ... | @@ -3607,6 +3641,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 3607 | 3641 | case ZigTypeIdOpaque: |
| 3608 | 3642 | case ZigTypeIdVector: |
| 3609 | 3643 | case ZigTypeIdCoroFrame: |
| 3644 | case ZigTypeIdAnyFrame: | |
| 3610 | 3645 | zig_unreachable(); |
| 3611 | 3646 | } |
| 3612 | 3647 | zig_unreachable(); |
| ... | ... | @@ -3615,11 +3650,13 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 3615 | 3650 | ZigType *get_src_ptr_type(ZigType *type) { |
| 3616 | 3651 | if (type->id == ZigTypeIdPointer) return type; |
| 3617 | 3652 | if (type->id == ZigTypeIdFn) return type; |
| 3653 | if (type->id == ZigTypeIdAnyFrame) return type; | |
| 3618 | 3654 | if (type->id == ZigTypeIdOptional) { |
| 3619 | 3655 | if (type->data.maybe.child_type->id == ZigTypeIdPointer) { |
| 3620 | 3656 | return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type; |
| 3621 | 3657 | } |
| 3622 | 3658 | if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type; |
| 3659 | if (type->data.maybe.child_type->id == ZigTypeIdAnyFrame) return type->data.maybe.child_type; | |
| 3623 | 3660 | } |
| 3624 | 3661 | return nullptr; |
| 3625 | 3662 | } |
| ... | ... | @@ -3635,6 +3672,13 @@ bool type_is_nonnull_ptr(ZigType *type) { |
| 3635 | 3672 | return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type); |
| 3636 | 3673 | } |
| 3637 | 3674 | |
| 3675 | static uint32_t get_coro_frame_align_bytes(CodeGen *g) { | |
| 3676 | uint32_t a = g->pointer_size_bytes * 2; | |
| 3677 | // promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw | |
| 3678 | if (a < 8) a = 8; | |
| 3679 | return a; | |
| 3680 | } | |
| 3681 | ||
| 3638 | 3682 | uint32_t get_ptr_align(CodeGen *g, ZigType *type) { |
| 3639 | 3683 | ZigType *ptr_type = get_src_ptr_type(type); |
| 3640 | 3684 | if (ptr_type->id == ZigTypeIdPointer) { |
| ... | ... | @@ -3646,6 +3690,8 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) { |
| 3646 | 3690 | // when getting the alignment of `?extern fn() void`. |
| 3647 | 3691 | // See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html |
| 3648 | 3692 | return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment; |
| 3693 | } else if (ptr_type->id == ZigTypeIdAnyFrame) { | |
| 3694 | return get_coro_frame_align_bytes(g); | |
| 3649 | 3695 | } else { |
| 3650 | 3696 | zig_unreachable(); |
| 3651 | 3697 | } |
| ... | ... | @@ -3657,6 +3703,8 @@ bool get_ptr_const(ZigType *type) { |
| 3657 | 3703 | return ptr_type->data.pointer.is_const; |
| 3658 | 3704 | } else if (ptr_type->id == ZigTypeIdFn) { |
| 3659 | 3705 | return true; |
| 3706 | } else if (ptr_type->id == ZigTypeIdAnyFrame) { | |
| 3707 | return true; | |
| 3660 | 3708 | } else { |
| 3661 | 3709 | zig_unreachable(); |
| 3662 | 3710 | } |
| ... | ... | @@ -4153,6 +4201,7 @@ bool handle_is_ptr(ZigType *type_entry) { |
| 4153 | 4201 | case ZigTypeIdFn: |
| 4154 | 4202 | case ZigTypeIdEnum: |
| 4155 | 4203 | case ZigTypeIdVector: |
| 4204 | case ZigTypeIdAnyFrame: | |
| 4156 | 4205 | return false; |
| 4157 | 4206 | case ZigTypeIdArray: |
| 4158 | 4207 | case ZigTypeIdStruct: |
| ... | ... | @@ -4404,6 +4453,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) { |
| 4404 | 4453 | case ZigTypeIdCoroFrame: |
| 4405 | 4454 | // TODO better hashing algorithm |
| 4406 | 4455 | return 675741936; |
| 4456 | case ZigTypeIdAnyFrame: | |
| 4457 | // TODO better hashing algorithm | |
| 4458 | return 3747294894; | |
| 4407 | 4459 | case ZigTypeIdBoundFn: |
| 4408 | 4460 | case ZigTypeIdInvalid: |
| 4409 | 4461 | case ZigTypeIdUnreachable: |
| ... | ... | @@ -4469,6 +4521,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { |
| 4469 | 4521 | case ZigTypeIdErrorSet: |
| 4470 | 4522 | case ZigTypeIdEnum: |
| 4471 | 4523 | case ZigTypeIdCoroFrame: |
| 4524 | case ZigTypeIdAnyFrame: | |
| 4472 | 4525 | return false; |
| 4473 | 4526 | |
| 4474 | 4527 | case ZigTypeIdPointer: |
| ... | ... | @@ -4541,6 +4594,7 @@ static bool return_type_is_cacheable(ZigType *return_type) { |
| 4541 | 4594 | case ZigTypeIdPointer: |
| 4542 | 4595 | case ZigTypeIdVector: |
| 4543 | 4596 | case ZigTypeIdCoroFrame: |
| 4597 | case ZigTypeIdAnyFrame: | |
| 4544 | 4598 | return true; |
| 4545 | 4599 | |
| 4546 | 4600 | case ZigTypeIdArray: |
| ... | ... | @@ -4673,6 +4727,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { |
| 4673 | 4727 | case ZigTypeIdFloat: |
| 4674 | 4728 | case ZigTypeIdErrorUnion: |
| 4675 | 4729 | case ZigTypeIdCoroFrame: |
| 4730 | case ZigTypeIdAnyFrame: | |
| 4676 | 4731 | return OnePossibleValueNo; |
| 4677 | 4732 | case ZigTypeIdUndefined: |
| 4678 | 4733 | case ZigTypeIdNull: |
| ... | ... | @@ -4761,6 +4816,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { |
| 4761 | 4816 | case ZigTypeIdVoid: |
| 4762 | 4817 | case ZigTypeIdUnreachable: |
| 4763 | 4818 | case ZigTypeIdCoroFrame: |
| 4819 | case ZigTypeIdAnyFrame: | |
| 4764 | 4820 | return ReqCompTimeNo; |
| 4765 | 4821 | } |
| 4766 | 4822 | zig_unreachable(); |
| ... | ... | @@ -5433,6 +5489,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { |
| 5433 | 5489 | return true; |
| 5434 | 5490 | case ZigTypeIdCoroFrame: |
| 5435 | 5491 | zig_panic("TODO"); |
| 5492 | case ZigTypeIdAnyFrame: | |
| 5493 | zig_panic("TODO"); | |
| 5436 | 5494 | case ZigTypeIdUndefined: |
| 5437 | 5495 | zig_panic("TODO"); |
| 5438 | 5496 | case ZigTypeIdNull: |
| ... | ... | @@ -5786,7 +5844,11 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5786 | 5844 | return; |
| 5787 | 5845 | } |
| 5788 | 5846 | case ZigTypeIdCoroFrame: |
| 5789 | buf_appendf(buf, "(TODO: coroutine frame value)"); | |
| 5847 | buf_appendf(buf, "(TODO: async function frame value)"); | |
| 5848 | return; | |
| 5849 | ||
| 5850 | case ZigTypeIdAnyFrame: | |
| 5851 | buf_appendf(buf, "(TODO: anyframe value)"); | |
| 5790 | 5852 | return; |
| 5791 | 5853 | |
| 5792 | 5854 | } |
| ... | ... | @@ -5836,6 +5898,7 @@ uint32_t type_id_hash(TypeId x) { |
| 5836 | 5898 | case ZigTypeIdBoundFn: |
| 5837 | 5899 | case ZigTypeIdArgTuple: |
| 5838 | 5900 | case ZigTypeIdCoroFrame: |
| 5901 | case ZigTypeIdAnyFrame: | |
| 5839 | 5902 | zig_unreachable(); |
| 5840 | 5903 | case ZigTypeIdErrorUnion: |
| 5841 | 5904 | 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) { |
| 5885 | 5948 | case ZigTypeIdArgTuple: |
| 5886 | 5949 | case ZigTypeIdOpaque: |
| 5887 | 5950 | case ZigTypeIdCoroFrame: |
| 5951 | case ZigTypeIdAnyFrame: | |
| 5888 | 5952 | zig_unreachable(); |
| 5889 | 5953 | case ZigTypeIdErrorUnion: |
| 5890 | 5954 | 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[] = { |
| 6051 | 6115 | ZigTypeIdArgTuple, |
| 6052 | 6116 | ZigTypeIdOpaque, |
| 6053 | 6117 | ZigTypeIdCoroFrame, |
| 6118 | ZigTypeIdAnyFrame, | |
| 6054 | 6119 | ZigTypeIdVector, |
| 6055 | 6120 | ZigTypeIdEnumLiteral, |
| 6056 | 6121 | }; |
| ... | ... | @@ -6116,10 +6181,12 @@ size_t type_id_index(ZigType *entry) { |
| 6116 | 6181 | return 21; |
| 6117 | 6182 | case ZigTypeIdCoroFrame: |
| 6118 | 6183 | return 22; |
| 6119 | case ZigTypeIdVector: | |
| 6184 | case ZigTypeIdAnyFrame: | |
| 6120 | 6185 | return 23; |
| 6121 | case ZigTypeIdEnumLiteral: | |
| 6186 | case ZigTypeIdVector: | |
| 6122 | 6187 | return 24; |
| 6188 | case ZigTypeIdEnumLiteral: | |
| 6189 | return 25; | |
| 6123 | 6190 | } |
| 6124 | 6191 | zig_unreachable(); |
| 6125 | 6192 | } |
| ... | ... | @@ -6178,6 +6245,8 @@ const char *type_id_name(ZigTypeId id) { |
| 6178 | 6245 | return "Vector"; |
| 6179 | 6246 | case ZigTypeIdCoroFrame: |
| 6180 | 6247 | return "Frame"; |
| 6248 | case ZigTypeIdAnyFrame: | |
| 6249 | return "AnyFrame"; | |
| 6181 | 6250 | } |
| 6182 | 6251 | zig_unreachable(); |
| 6183 | 6252 | } |
| ... | ... | @@ -7398,6 +7467,40 @@ static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, Resol |
| 7398 | 7467 | frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type; |
| 7399 | 7468 | } |
| 7400 | 7469 | |
| 7470 | static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, ResolveStatus wanted_resolve_status) { | |
| 7471 | if (any_frame_type->llvm_di_type != nullptr) return; | |
| 7472 | ||
| 7473 | ZigType *result_type = any_frame_type->data.any_frame.result_type; | |
| 7474 | Buf *name = buf_sprintf("(%s header)", buf_ptr(&any_frame_type->name)); | |
| 7475 | ||
| 7476 | ZigType *frame_header_type; | |
| 7477 | if (result_type == nullptr || !type_has_bits(result_type)) { | |
| 7478 | const char *field_names[] = {"resume_index", "fn_ptr", "awaiter"}; | |
| 7479 | ZigType *field_types[] = { | |
| 7480 | g->builtin_types.entry_usize, | |
| 7481 | g->builtin_types.entry_usize, | |
| 7482 | g->builtin_types.entry_usize, | |
| 7483 | }; | |
| 7484 | frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 3); | |
| 7485 | } else { | |
| 7486 | ZigType *ptr_result_type = get_pointer_to_type(g, result_type, false); | |
| 7487 | ||
| 7488 | const char *field_names[] = {"resume_index", "fn_ptr", "awaiter", "result_ptr", "result"}; | |
| 7489 | ZigType *field_types[] = { | |
| 7490 | g->builtin_types.entry_usize, | |
| 7491 | g->builtin_types.entry_usize, | |
| 7492 | g->builtin_types.entry_usize, | |
| 7493 | ptr_result_type, | |
| 7494 | result_type, | |
| 7495 | }; | |
| 7496 | frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 5); | |
| 7497 | } | |
| 7498 | ||
| 7499 | ZigType *ptr_type = get_pointer_to_type(g, frame_header_type, false); | |
| 7500 | any_frame_type->llvm_type = get_llvm_type(g, ptr_type); | |
| 7501 | any_frame_type->llvm_di_type = get_llvm_di_type(g, ptr_type); | |
| 7502 | } | |
| 7503 | ||
| 7401 | 7504 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
| 7402 | 7505 | assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown)); |
| 7403 | 7506 | assert(wanted_resolve_status > ResolveStatusSizeKnown); |
| ... | ... | @@ -7460,6 +7563,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r |
| 7460 | 7563 | } |
| 7461 | 7564 | case ZigTypeIdCoroFrame: |
| 7462 | 7565 | return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status); |
| 7566 | case ZigTypeIdAnyFrame: | |
| 7567 | return resolve_llvm_types_any_frame(g, type, wanted_resolve_status); | |
| 7463 | 7568 | } |
| 7464 | 7569 | zig_unreachable(); |
| 7465 | 7570 | } |
src/analyze.hpp+1| ... | ... | @@ -41,6 +41,7 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c |
| 41 | 41 | ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[], |
| 42 | 42 | ZigType *field_types[], size_t field_count); |
| 43 | 43 | ZigType *get_test_fn_type(CodeGen *g); |
| 44 | ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type); | |
| 44 | 45 | bool handle_is_ptr(ZigType *type_entry); |
| 45 | 46 | |
| 46 | 47 | bool type_has_bits(ZigType *type_entry); |
src/ast_render.cpp+10| ... | ... | @@ -259,6 +259,8 @@ static const char *node_type_str(NodeType node_type) { |
| 259 | 259 | return "Suspend"; |
| 260 | 260 | case NodeTypePointerType: |
| 261 | 261 | return "PointerType"; |
| 262 | case NodeTypeAnyFrameType: | |
| 263 | return "AnyFrameType"; | |
| 262 | 264 | case NodeTypeEnumLiteral: |
| 263 | 265 | return "EnumLiteral"; |
| 264 | 266 | } |
| ... | ... | @@ -847,6 +849,14 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 847 | 849 | render_node_ungrouped(ar, node->data.inferred_array_type.child_type); |
| 848 | 850 | break; |
| 849 | 851 | } |
| 852 | case NodeTypeAnyFrameType: { | |
| 853 | fprintf(ar->f, "anyframe"); | |
| 854 | if (node->data.anyframe_type.payload_type != nullptr) { | |
| 855 | fprintf(ar->f, "->"); | |
| 856 | render_node_grouped(ar, node->data.anyframe_type.payload_type); | |
| 857 | } | |
| 858 | break; | |
| 859 | } | |
| 850 | 860 | case NodeTypeErrorType: |
| 851 | 861 | fprintf(ar->f, "anyerror"); |
| 852 | 862 | break; |
src/codegen.cpp+15-1| ... | ... | @@ -4947,6 +4947,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 4947 | 4947 | case IrInstructionIdSetRuntimeSafety: |
| 4948 | 4948 | case IrInstructionIdSetFloatMode: |
| 4949 | 4949 | case IrInstructionIdArrayType: |
| 4950 | case IrInstructionIdAnyFrameType: | |
| 4950 | 4951 | case IrInstructionIdSliceType: |
| 4951 | 4952 | case IrInstructionIdSizeOf: |
| 4952 | 4953 | case IrInstructionIdSwitchTarget: |
| ... | ... | @@ -5438,7 +5439,9 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con |
| 5438 | 5439 | return val; |
| 5439 | 5440 | } |
| 5440 | 5441 | case ZigTypeIdCoroFrame: |
| 5441 | zig_panic("TODO bit pack a coroutine frame"); | |
| 5442 | zig_panic("TODO bit pack an async function frame"); | |
| 5443 | case ZigTypeIdAnyFrame: | |
| 5444 | zig_panic("TODO bit pack an anyframe"); | |
| 5442 | 5445 | } |
| 5443 | 5446 | zig_unreachable(); |
| 5444 | 5447 | } |
| ... | ... | @@ -5961,6 +5964,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 5961 | 5964 | zig_unreachable(); |
| 5962 | 5965 | case ZigTypeIdCoroFrame: |
| 5963 | 5966 | zig_panic("TODO"); |
| 5967 | case ZigTypeIdAnyFrame: | |
| 5968 | zig_panic("TODO"); | |
| 5964 | 5969 | } |
| 5965 | 5970 | zig_unreachable(); |
| 5966 | 5971 | } |
| ... | ... | @@ -7176,6 +7181,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7176 | 7181 | " ArgTuple: void,\n" |
| 7177 | 7182 | " Opaque: void,\n" |
| 7178 | 7183 | " Frame: void,\n" |
| 7184 | " AnyFrame: AnyFrame,\n" | |
| 7179 | 7185 | " Vector: Vector,\n" |
| 7180 | 7186 | " EnumLiteral: void,\n" |
| 7181 | 7187 | "\n\n" |
| ... | ... | @@ -7291,6 +7297,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7291 | 7297 | " args: []FnArg,\n" |
| 7292 | 7298 | " };\n" |
| 7293 | 7299 | "\n" |
| 7300 | " pub const AnyFrame = struct {\n" | |
| 7301 | " child: ?type,\n" | |
| 7302 | " };\n" | |
| 7303 | "\n" | |
| 7294 | 7304 | " pub const Vector = struct {\n" |
| 7295 | 7305 | " len: comptime_int,\n" |
| 7296 | 7306 | " child: type,\n" |
| ... | ... | @@ -8448,6 +8458,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e |
| 8448 | 8458 | case ZigTypeIdErrorUnion: |
| 8449 | 8459 | case ZigTypeIdErrorSet: |
| 8450 | 8460 | case ZigTypeIdCoroFrame: |
| 8461 | case ZigTypeIdAnyFrame: | |
| 8451 | 8462 | zig_unreachable(); |
| 8452 | 8463 | case ZigTypeIdVoid: |
| 8453 | 8464 | case ZigTypeIdUnreachable: |
| ... | ... | @@ -8632,6 +8643,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu |
| 8632 | 8643 | case ZigTypeIdNull: |
| 8633 | 8644 | case ZigTypeIdArgTuple: |
| 8634 | 8645 | case ZigTypeIdCoroFrame: |
| 8646 | case ZigTypeIdAnyFrame: | |
| 8635 | 8647 | zig_unreachable(); |
| 8636 | 8648 | } |
| 8637 | 8649 | } |
| ... | ... | @@ -8800,7 +8812,9 @@ static void gen_h_file(CodeGen *g) { |
| 8800 | 8812 | case ZigTypeIdFn: |
| 8801 | 8813 | case ZigTypeIdVector: |
| 8802 | 8814 | case ZigTypeIdCoroFrame: |
| 8815 | case ZigTypeIdAnyFrame: | |
| 8803 | 8816 | zig_unreachable(); |
| 8817 | ||
| 8804 | 8818 | case ZigTypeIdEnum: |
| 8805 | 8819 | if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { |
| 8806 | 8820 | fprintf(out_h, "enum %s {\n", buf_ptr(type_h_name(type_entry))); |
src/ir.cpp+83-3| ... | ... | @@ -303,6 +303,7 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| 303 | 303 | case ZigTypeIdBoundFn: |
| 304 | 304 | case ZigTypeIdErrorSet: |
| 305 | 305 | case ZigTypeIdOpaque: |
| 306 | case ZigTypeIdAnyFrame: | |
| 306 | 307 | return true; |
| 307 | 308 | case ZigTypeIdFloat: |
| 308 | 309 | return a->data.floating.bit_count == b->data.floating.bit_count; |
| ... | ... | @@ -563,6 +564,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { |
| 563 | 564 | return IrInstructionIdArrayType; |
| 564 | 565 | } |
| 565 | 566 | |
| 567 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) { | |
| 568 | return IrInstructionIdAnyFrameType; | |
| 569 | } | |
| 570 | ||
| 566 | 571 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { |
| 567 | 572 | return IrInstructionIdSliceType; |
| 568 | 573 | } |
| ... | ... | @@ -1696,6 +1701,16 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode |
| 1696 | 1701 | return &instruction->base; |
| 1697 | 1702 | } |
| 1698 | 1703 | |
| 1704 | static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 1705 | IrInstruction *payload_type) | |
| 1706 | { | |
| 1707 | IrInstructionAnyFrameType *instruction = ir_build_instruction<IrInstructionAnyFrameType>(irb, scope, source_node); | |
| 1708 | instruction->payload_type = payload_type; | |
| 1709 | ||
| 1710 | if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); | |
| 1711 | ||
| 1712 | return &instruction->base; | |
| 1713 | } | |
| 1699 | 1714 | static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1700 | 1715 | IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero) |
| 1701 | 1716 | { |
| ... | ... | @@ -6515,6 +6530,22 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 6515 | 6530 | } |
| 6516 | 6531 | } |
| 6517 | 6532 | |
| 6533 | static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) { | |
| 6534 | assert(node->type == NodeTypeAnyFrameType); | |
| 6535 | ||
| 6536 | AstNode *payload_type_node = node->data.anyframe_type.payload_type; | |
| 6537 | IrInstruction *payload_type_value = nullptr; | |
| 6538 | ||
| 6539 | if (payload_type_node != nullptr) { | |
| 6540 | payload_type_value = ir_gen_node(irb, payload_type_node, scope); | |
| 6541 | if (payload_type_value == irb->codegen->invalid_instruction) | |
| 6542 | return payload_type_value; | |
| 6543 | ||
| 6544 | } | |
| 6545 | ||
| 6546 | return ir_build_anyframe_type(irb, scope, node, payload_type_value); | |
| 6547 | } | |
| 6548 | ||
| 6518 | 6549 | static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6519 | 6550 | assert(node->type == NodeTypeUndefinedLiteral); |
| 6520 | 6551 | return ir_build_const_undefined(irb, scope, node); |
| ... | ... | @@ -7884,6 +7915,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7884 | 7915 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); |
| 7885 | 7916 | case NodeTypePointerType: |
| 7886 | 7917 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); |
| 7918 | case NodeTypeAnyFrameType: | |
| 7919 | return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); | |
| 7887 | 7920 | case NodeTypeStringLiteral: |
| 7888 | 7921 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); |
| 7889 | 7922 | case NodeTypeUndefinedLiteral: |
| ... | ... | @@ -12775,6 +12808,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 12775 | 12808 | case ZigTypeIdArgTuple: |
| 12776 | 12809 | case ZigTypeIdEnum: |
| 12777 | 12810 | case ZigTypeIdEnumLiteral: |
| 12811 | case ZigTypeIdAnyFrame: | |
| 12778 | 12812 | operator_allowed = is_equality_cmp; |
| 12779 | 12813 | break; |
| 12780 | 12814 | |
| ... | ... | @@ -14155,6 +14189,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 14155 | 14189 | case ZigTypeIdArgTuple: |
| 14156 | 14190 | case ZigTypeIdOpaque: |
| 14157 | 14191 | case ZigTypeIdCoroFrame: |
| 14192 | case ZigTypeIdAnyFrame: | |
| 14158 | 14193 | ir_add_error(ira, target, |
| 14159 | 14194 | buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); |
| 14160 | 14195 | break; |
| ... | ... | @@ -14180,6 +14215,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 14180 | 14215 | case ZigTypeIdOpaque: |
| 14181 | 14216 | case ZigTypeIdEnumLiteral: |
| 14182 | 14217 | case ZigTypeIdCoroFrame: |
| 14218 | case ZigTypeIdAnyFrame: | |
| 14183 | 14219 | ir_add_error(ira, target, |
| 14184 | 14220 | buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); |
| 14185 | 14221 | break; |
| ... | ... | @@ -15720,7 +15756,9 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp |
| 15720 | 15756 | case ZigTypeIdBoundFn: |
| 15721 | 15757 | case ZigTypeIdArgTuple: |
| 15722 | 15758 | case ZigTypeIdCoroFrame: |
| 15759 | case ZigTypeIdAnyFrame: | |
| 15723 | 15760 | return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); |
| 15761 | ||
| 15724 | 15762 | case ZigTypeIdUnreachable: |
| 15725 | 15763 | case ZigTypeIdOpaque: |
| 15726 | 15764 | 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, |
| 17443 | 17481 | return ir_const_void(ira, &instruction->base); |
| 17444 | 17482 | } |
| 17445 | 17483 | |
| 17484 | static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, | |
| 17485 | IrInstructionAnyFrameType *instruction) | |
| 17486 | { | |
| 17487 | ZigType *payload_type = nullptr; | |
| 17488 | if (instruction->payload_type != nullptr) { | |
| 17489 | payload_type = ir_resolve_type(ira, instruction->payload_type->child); | |
| 17490 | if (type_is_invalid(payload_type)) | |
| 17491 | return ira->codegen->invalid_instruction; | |
| 17492 | } | |
| 17493 | ||
| 17494 | ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); | |
| 17495 | return ir_const_type(ira, &instruction->base, any_frame_type); | |
| 17496 | } | |
| 17497 | ||
| 17446 | 17498 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17447 | 17499 | IrInstructionSliceType *slice_type_instruction) |
| 17448 | 17500 | { |
| ... | ... | @@ -17492,6 +17544,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17492 | 17544 | case ZigTypeIdBoundFn: |
| 17493 | 17545 | case ZigTypeIdVector: |
| 17494 | 17546 | case ZigTypeIdCoroFrame: |
| 17547 | case ZigTypeIdAnyFrame: | |
| 17495 | 17548 | { |
| 17496 | 17549 | ResolveStatus needed_status = (align_bytes == 0) ? |
| 17497 | 17550 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| ... | ... | @@ -17607,6 +17660,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 17607 | 17660 | case ZigTypeIdBoundFn: |
| 17608 | 17661 | case ZigTypeIdVector: |
| 17609 | 17662 | case ZigTypeIdCoroFrame: |
| 17663 | case ZigTypeIdAnyFrame: | |
| 17610 | 17664 | { |
| 17611 | 17665 | if ((err = ensure_complete_type(ira->codegen, child_type))) |
| 17612 | 17666 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -17658,6 +17712,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 17658 | 17712 | case ZigTypeIdFn: |
| 17659 | 17713 | case ZigTypeIdVector: |
| 17660 | 17714 | case ZigTypeIdCoroFrame: |
| 17715 | case ZigTypeIdAnyFrame: | |
| 17661 | 17716 | { |
| 17662 | 17717 | uint64_t size_in_bytes = type_size(ira->codegen, type_entry); |
| 17663 | 17718 | 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, |
| 18222 | 18277 | case ZigTypeIdOpaque: |
| 18223 | 18278 | case ZigTypeIdVector: |
| 18224 | 18279 | case ZigTypeIdCoroFrame: |
| 18280 | case ZigTypeIdAnyFrame: | |
| 18225 | 18281 | ir_add_error(ira, &switch_target_instruction->base, |
| 18226 | 18282 | buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); |
| 18227 | 18283 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -19656,6 +19712,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 19656 | 19712 | |
| 19657 | 19713 | break; |
| 19658 | 19714 | } |
| 19715 | case ZigTypeIdAnyFrame: { | |
| 19716 | result = create_const_vals(1); | |
| 19717 | result->special = ConstValSpecialStatic; | |
| 19718 | result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); | |
| 19719 | ||
| 19720 | ConstExprValue *fields = create_const_vals(1); | |
| 19721 | result->data.x_struct.fields = fields; | |
| 19722 | ||
| 19723 | // child: ?type | |
| 19724 | ensure_field_index(result->type, "child", 0); | |
| 19725 | fields[0].special = ConstValSpecialStatic; | |
| 19726 | fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); | |
| 19727 | fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : | |
| 19728 | create_const_type(ira->codegen, type_entry->data.any_frame.result_type); | |
| 19729 | break; | |
| 19730 | } | |
| 19659 | 19731 | case ZigTypeIdEnum: |
| 19660 | 19732 | { |
| 19661 | 19733 | result = create_const_vals(1); |
| ... | ... | @@ -20062,7 +20134,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 20062 | 20134 | break; |
| 20063 | 20135 | } |
| 20064 | 20136 | case ZigTypeIdCoroFrame: |
| 20065 | zig_panic("TODO @typeInfo for coro frames"); | |
| 20137 | zig_panic("TODO @typeInfo for async function frames"); | |
| 20066 | 20138 | } |
| 20067 | 20139 | |
| 20068 | 20140 | assert(result != nullptr); |
| ... | ... | @@ -21852,6 +21924,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 21852 | 21924 | case ZigTypeIdFn: |
| 21853 | 21925 | case ZigTypeIdVector: |
| 21854 | 21926 | case ZigTypeIdCoroFrame: |
| 21927 | case ZigTypeIdAnyFrame: | |
| 21855 | 21928 | { |
| 21856 | 21929 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 21857 | 21930 | 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 |
| 23004 | 23077 | case ZigTypeIdUnion: |
| 23005 | 23078 | zig_panic("TODO buf_write_value_bytes union type"); |
| 23006 | 23079 | case ZigTypeIdCoroFrame: |
| 23007 | zig_panic("TODO buf_write_value_bytes coro frame type"); | |
| 23080 | zig_panic("TODO buf_write_value_bytes async fn frame type"); | |
| 23081 | case ZigTypeIdAnyFrame: | |
| 23082 | zig_panic("TODO buf_write_value_bytes anyframe type"); | |
| 23008 | 23083 | } |
| 23009 | 23084 | zig_unreachable(); |
| 23010 | 23085 | } |
| ... | ... | @@ -23185,7 +23260,9 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 23185 | 23260 | case ZigTypeIdUnion: |
| 23186 | 23261 | zig_panic("TODO buf_read_value_bytes union type"); |
| 23187 | 23262 | case ZigTypeIdCoroFrame: |
| 23188 | zig_panic("TODO buf_read_value_bytes coro frame type"); | |
| 23263 | zig_panic("TODO buf_read_value_bytes async fn frame type"); | |
| 23264 | case ZigTypeIdAnyFrame: | |
| 23265 | zig_panic("TODO buf_read_value_bytes anyframe type"); | |
| 23189 | 23266 | } |
| 23190 | 23267 | zig_unreachable(); |
| 23191 | 23268 | } |
| ... | ... | @@ -24327,6 +24404,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 24327 | 24404 | return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); |
| 24328 | 24405 | case IrInstructionIdSetFloatMode: |
| 24329 | 24406 | return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); |
| 24407 | case IrInstructionIdAnyFrameType: | |
| 24408 | return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction); | |
| 24330 | 24409 | case IrInstructionIdSliceType: |
| 24331 | 24410 | return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); |
| 24332 | 24411 | case IrInstructionIdGlobalAsm: |
| ... | ... | @@ -24707,6 +24786,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24707 | 24786 | case IrInstructionIdStructFieldPtr: |
| 24708 | 24787 | case IrInstructionIdArrayType: |
| 24709 | 24788 | case IrInstructionIdSliceType: |
| 24789 | case IrInstructionIdAnyFrameType: | |
| 24710 | 24790 | case IrInstructionIdSizeOf: |
| 24711 | 24791 | case IrInstructionIdTestNonNull: |
| 24712 | 24792 | case IrInstructionIdOptionalUnwrapPtr: |
src/ir_print.cpp+12| ... | ... | @@ -471,6 +471,15 @@ static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instructio |
| 471 | 471 | ir_print_other_instruction(irp, instruction->child_type); |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | static void ir_print_any_frame_type(IrPrint *irp, IrInstructionAnyFrameType *instruction) { | |
| 475 | if (instruction->payload_type == nullptr) { | |
| 476 | fprintf(irp->f, "anyframe"); | |
| 477 | } else { | |
| 478 | fprintf(irp->f, "anyframe->"); | |
| 479 | ir_print_other_instruction(irp, instruction->payload_type); | |
| 480 | } | |
| 481 | } | |
| 482 | ||
| 474 | 483 | static void ir_print_global_asm(IrPrint *irp, IrInstructionGlobalAsm *instruction) { |
| 475 | 484 | fprintf(irp->f, "asm(\"%s\")", buf_ptr(instruction->asm_code)); |
| 476 | 485 | } |
| ... | ... | @@ -1629,6 +1638,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1629 | 1638 | case IrInstructionIdSliceType: |
| 1630 | 1639 | ir_print_slice_type(irp, (IrInstructionSliceType *)instruction); |
| 1631 | 1640 | break; |
| 1641 | case IrInstructionIdAnyFrameType: | |
| 1642 | ir_print_any_frame_type(irp, (IrInstructionAnyFrameType *)instruction); | |
| 1643 | break; | |
| 1632 | 1644 | case IrInstructionIdGlobalAsm: |
| 1633 | 1645 | ir_print_global_asm(irp, (IrInstructionGlobalAsm *)instruction); |
| 1634 | 1646 | break; |
src/parser.cpp+21-1| ... | ... | @@ -282,6 +282,9 @@ static AstNode *ast_parse_prefix_op_expr( |
| 282 | 282 | case NodeTypeAwaitExpr: |
| 283 | 283 | right = &prefix->data.await_expr.expr; |
| 284 | 284 | break; |
| 285 | case NodeTypeAnyFrameType: | |
| 286 | right = &prefix->data.anyframe_type.payload_type; | |
| 287 | break; | |
| 285 | 288 | case NodeTypeArrayType: |
| 286 | 289 | right = &prefix->data.array_type.child_type; |
| 287 | 290 | break; |
| ... | ... | @@ -1640,6 +1643,10 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) { |
| 1640 | 1643 | if (null != nullptr) |
| 1641 | 1644 | return ast_create_node(pc, NodeTypeNullLiteral, null); |
| 1642 | 1645 | |
| 1646 | Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame); | |
| 1647 | if (anyframe != nullptr) | |
| 1648 | return ast_create_node(pc, NodeTypeAnyFrameType, anyframe); | |
| 1649 | ||
| 1643 | 1650 | Token *true_token = eat_token_if(pc, TokenIdKeywordTrue); |
| 1644 | 1651 | if (true_token != nullptr) { |
| 1645 | 1652 | AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token); |
| ... | ... | @@ -2510,7 +2517,7 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) { |
| 2510 | 2517 | |
| 2511 | 2518 | // PrefixTypeOp |
| 2512 | 2519 | // <- QUESTIONMARK |
| 2513 | // / KEYWORD_promise MINUSRARROW | |
| 2520 | // / KEYWORD_anyframe MINUSRARROW | |
| 2514 | 2521 | // / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)* |
| 2515 | 2522 | // / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)* |
| 2516 | 2523 | static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { |
| ... | ... | @@ -2521,6 +2528,16 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { |
| 2521 | 2528 | return res; |
| 2522 | 2529 | } |
| 2523 | 2530 | |
| 2531 | Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame); | |
| 2532 | if (anyframe != nullptr) { | |
| 2533 | if (eat_token_if(pc, TokenIdArrow) != nullptr) { | |
| 2534 | AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe); | |
| 2535 | return res; | |
| 2536 | } | |
| 2537 | ||
| 2538 | put_back_token(pc); | |
| 2539 | } | |
| 2540 | ||
| 2524 | 2541 | AstNode *array = ast_parse_array_type_start(pc); |
| 2525 | 2542 | if (array != nullptr) { |
| 2526 | 2543 | assert(array->type == NodeTypeArrayType); |
| ... | ... | @@ -3005,6 +3022,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 3005 | 3022 | case NodeTypeInferredArrayType: |
| 3006 | 3023 | visit_field(&node->data.array_type.child_type, visit, context); |
| 3007 | 3024 | break; |
| 3025 | case NodeTypeAnyFrameType: | |
| 3026 | visit_field(&node->data.anyframe_type.payload_type, visit, context); | |
| 3027 | break; | |
| 3008 | 3028 | case NodeTypeErrorType: |
| 3009 | 3029 | // none |
| 3010 | 3030 | break; |
src/tokenizer.cpp+2| ... | ... | @@ -109,6 +109,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 109 | 109 | {"align", TokenIdKeywordAlign}, |
| 110 | 110 | {"allowzero", TokenIdKeywordAllowZero}, |
| 111 | 111 | {"and", TokenIdKeywordAnd}, |
| 112 | {"anyframe", TokenIdKeywordAnyFrame}, | |
| 112 | 113 | {"asm", TokenIdKeywordAsm}, |
| 113 | 114 | {"async", TokenIdKeywordAsync}, |
| 114 | 115 | {"await", TokenIdKeywordAwait}, |
| ... | ... | @@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) { |
| 1533 | 1534 | case TokenIdKeywordCancel: return "cancel"; |
| 1534 | 1535 | case TokenIdKeywordAlign: return "align"; |
| 1535 | 1536 | case TokenIdKeywordAnd: return "and"; |
| 1537 | case TokenIdKeywordAnyFrame: return "anyframe"; | |
| 1536 | 1538 | case TokenIdKeywordAsm: return "asm"; |
| 1537 | 1539 | case TokenIdKeywordBreak: return "break"; |
| 1538 | 1540 | case TokenIdKeywordCatch: return "catch"; |
src/tokenizer.hpp+1| ... | ... | @@ -53,6 +53,7 @@ enum TokenId { |
| 53 | 53 | TokenIdKeywordAlign, |
| 54 | 54 | TokenIdKeywordAllowZero, |
| 55 | 55 | TokenIdKeywordAnd, |
| 56 | TokenIdKeywordAnyFrame, | |
| 56 | 57 | TokenIdKeywordAsm, |
| 57 | 58 | TokenIdKeywordAsync, |
| 58 | 59 | TokenIdKeywordAwait, |
std/hash_map.zig+1| ... | ... | @@ -540,6 +540,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type |
| 540 | 540 | .Undefined, |
| 541 | 541 | .ArgTuple, |
| 542 | 542 | .Frame, |
| 543 | .AnyFrame, | |
| 543 | 544 | => @compileError("cannot hash this type"), |
| 544 | 545 | |
| 545 | 546 | .Void, |
std/testing.zig+1| ... | ... | @@ -30,6 +30,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void { |
| 30 | 30 | .ArgTuple, |
| 31 | 31 | .Opaque, |
| 32 | 32 | .Frame, |
| 33 | .AnyFrame, | |
| 33 | 34 | => @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"), |
| 34 | 35 | |
| 35 | 36 | .Undefined, |
std/zig/ast.zig+8-8| ... | ... | @@ -400,7 +400,7 @@ pub const Node = struct { |
| 400 | 400 | VarType, |
| 401 | 401 | ErrorType, |
| 402 | 402 | FnProto, |
| 403 | PromiseType, | |
| 403 | AnyFrameType, | |
| 404 | 404 | |
| 405 | 405 | // Primary expressions |
| 406 | 406 | IntegerLiteral, |
| ... | ... | @@ -952,9 +952,9 @@ pub const Node = struct { |
| 952 | 952 | } |
| 953 | 953 | }; |
| 954 | 954 | |
| 955 | pub const PromiseType = struct { | |
| 955 | pub const AnyFrameType = struct { | |
| 956 | 956 | base: Node, |
| 957 | promise_token: TokenIndex, | |
| 957 | anyframe_token: TokenIndex, | |
| 958 | 958 | result: ?Result, |
| 959 | 959 | |
| 960 | 960 | pub const Result = struct { |
| ... | ... | @@ -962,7 +962,7 @@ pub const Node = struct { |
| 962 | 962 | return_type: *Node, |
| 963 | 963 | }; |
| 964 | 964 | |
| 965 | pub fn iterate(self: *PromiseType, index: usize) ?*Node { | |
| 965 | pub fn iterate(self: *AnyFrameType, index: usize) ?*Node { | |
| 966 | 966 | var i = index; |
| 967 | 967 | |
| 968 | 968 | if (self.result) |result| { |
| ... | ... | @@ -973,13 +973,13 @@ pub const Node = struct { |
| 973 | 973 | return null; |
| 974 | 974 | } |
| 975 | 975 | |
| 976 | pub fn firstToken(self: *const PromiseType) TokenIndex { | |
| 977 | return self.promise_token; | |
| 976 | pub fn firstToken(self: *const AnyFrameType) TokenIndex { | |
| 977 | return self.anyframe_token; | |
| 978 | 978 | } |
| 979 | 979 | |
| 980 | pub fn lastToken(self: *const PromiseType) TokenIndex { | |
| 980 | pub fn lastToken(self: *const AnyFrameType) TokenIndex { | |
| 981 | 981 | if (self.result) |result| return result.return_type.lastToken(); |
| 982 | return self.promise_token; | |
| 982 | return self.anyframe_token; | |
| 983 | 983 | } |
| 984 | 984 | }; |
| 985 | 985 |
std/zig/parse.zig+20-20| ... | ... | @@ -1201,7 +1201,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1201 | 1201 | /// / KEYWORD_error DOT IDENTIFIER |
| 1202 | 1202 | /// / KEYWORD_false |
| 1203 | 1203 | /// / KEYWORD_null |
| 1204 | /// / KEYWORD_promise | |
| 1204 | /// / KEYWORD_anyframe | |
| 1205 | 1205 | /// / KEYWORD_true |
| 1206 | 1206 | /// / KEYWORD_undefined |
| 1207 | 1207 | /// / KEYWORD_unreachable |
| ... | ... | @@ -1256,11 +1256,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N |
| 1256 | 1256 | } |
| 1257 | 1257 | if (eatToken(it, .Keyword_false)) |token| return createLiteral(arena, Node.BoolLiteral, token); |
| 1258 | 1258 | if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token); |
| 1259 | if (eatToken(it, .Keyword_promise)) |token| { | |
| 1260 | const node = try arena.create(Node.PromiseType); | |
| 1261 | node.* = Node.PromiseType{ | |
| 1262 | .base = Node{ .id = .PromiseType }, | |
| 1263 | .promise_token = token, | |
| 1259 | if (eatToken(it, .Keyword_anyframe)) |token| { | |
| 1260 | const node = try arena.create(Node.AnyFrameType); | |
| 1261 | node.* = Node.AnyFrameType{ | |
| 1262 | .base = Node{ .id = .AnyFrameType }, | |
| 1263 | .anyframe_token = token, | |
| 1264 | 1264 | .result = null, |
| 1265 | 1265 | }; |
| 1266 | 1266 | return &node.base; |
| ... | ... | @@ -2194,7 +2194,7 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 2194 | 2194 | |
| 2195 | 2195 | /// PrefixTypeOp |
| 2196 | 2196 | /// <- QUESTIONMARK |
| 2197 | /// / KEYWORD_promise MINUSRARROW | |
| 2197 | /// / KEYWORD_anyframe MINUSRARROW | |
| 2198 | 2198 | /// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* |
| 2199 | 2199 | /// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* |
| 2200 | 2200 | fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| ... | ... | @@ -2209,20 +2209,20 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 2209 | 2209 | return &node.base; |
| 2210 | 2210 | } |
| 2211 | 2211 | |
| 2212 | // TODO: Returning a PromiseType instead of PrefixOp makes casting and setting .rhs or | |
| 2212 | // TODO: Returning a AnyFrameType instead of PrefixOp makes casting and setting .rhs or | |
| 2213 | 2213 | // .return_type more difficult for the caller (see parsePrefixOpExpr helper). |
| 2214 | // Consider making the PromiseType a member of PrefixOp and add a | |
| 2215 | // PrefixOp.PromiseType variant? | |
| 2216 | if (eatToken(it, .Keyword_promise)) |token| { | |
| 2214 | // Consider making the AnyFrameType a member of PrefixOp and add a | |
| 2215 | // PrefixOp.AnyFrameType variant? | |
| 2216 | if (eatToken(it, .Keyword_anyframe)) |token| { | |
| 2217 | 2217 | const arrow = eatToken(it, .Arrow) orelse { |
| 2218 | 2218 | putBackToken(it, token); |
| 2219 | 2219 | return null; |
| 2220 | 2220 | }; |
| 2221 | const node = try arena.create(Node.PromiseType); | |
| 2222 | node.* = Node.PromiseType{ | |
| 2223 | .base = Node{ .id = .PromiseType }, | |
| 2224 | .promise_token = token, | |
| 2225 | .result = Node.PromiseType.Result{ | |
| 2221 | const node = try arena.create(Node.AnyFrameType); | |
| 2222 | node.* = Node.AnyFrameType{ | |
| 2223 | .base = Node{ .id = .AnyFrameType }, | |
| 2224 | .anyframe_token = token, | |
| 2225 | .result = Node.AnyFrameType.Result{ | |
| 2226 | 2226 | .arrow_token = arrow, |
| 2227 | 2227 | .return_type = undefined, // set by caller |
| 2228 | 2228 | }, |
| ... | ... | @@ -2903,8 +2903,8 @@ fn parsePrefixOpExpr( |
| 2903 | 2903 | rightmost_op = rhs; |
| 2904 | 2904 | } else break; |
| 2905 | 2905 | }, |
| 2906 | .PromiseType => { | |
| 2907 | const prom = rightmost_op.cast(Node.PromiseType).?; | |
| 2906 | .AnyFrameType => { | |
| 2907 | const prom = rightmost_op.cast(Node.AnyFrameType).?; | |
| 2908 | 2908 | if (try opParseFn(arena, it, tree)) |rhs| { |
| 2909 | 2909 | prom.result.?.return_type = rhs; |
| 2910 | 2910 | rightmost_op = rhs; |
| ... | ... | @@ -2922,8 +2922,8 @@ fn parsePrefixOpExpr( |
| 2922 | 2922 | .InvalidToken = AstError.InvalidToken{ .token = it.index }, |
| 2923 | 2923 | }); |
| 2924 | 2924 | }, |
| 2925 | .PromiseType => { | |
| 2926 | const prom = rightmost_op.cast(Node.PromiseType).?; | |
| 2925 | .AnyFrameType => { | |
| 2926 | const prom = rightmost_op.cast(Node.AnyFrameType).?; | |
| 2927 | 2927 | prom.result.?.return_type = try expectNode(arena, it, tree, childParseFn, AstError{ |
| 2928 | 2928 | .InvalidToken = AstError.InvalidToken{ .token = it.index }, |
| 2929 | 2929 | }); |
std/zig/parser_test.zig+2-2| ... | ... | @@ -2111,12 +2111,12 @@ test "zig fmt: coroutines" { |
| 2111 | 2111 | \\ suspend; |
| 2112 | 2112 | \\ x += 1; |
| 2113 | 2113 | \\ suspend; |
| 2114 | \\ const p: promise->void = async simpleAsyncFn() catch unreachable; | |
| 2114 | \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; | |
| 2115 | 2115 | \\ await p; |
| 2116 | 2116 | \\} |
| 2117 | 2117 | \\ |
| 2118 | 2118 | \\test "coroutine suspend, resume, cancel" { |
| 2119 | \\ const p: promise = try async<std.debug.global_allocator> testAsyncSeq(); | |
| 2119 | \\ const p: anyframe = try async<std.debug.global_allocator> testAsyncSeq(); | |
| 2120 | 2120 | \\ resume p; |
| 2121 | 2121 | \\ cancel p; |
| 2122 | 2122 | \\} |
std/zig/render.zig+5-5| ... | ... | @@ -1205,15 +1205,15 @@ fn renderExpression( |
| 1205 | 1205 | } |
| 1206 | 1206 | }, |
| 1207 | 1207 | |
| 1208 | ast.Node.Id.PromiseType => { | |
| 1209 | const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base); | |
| 1208 | ast.Node.Id.AnyFrameType => { | |
| 1209 | const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base); | |
| 1210 | 1210 | |
| 1211 | if (promise_type.result) |result| { | |
| 1212 | try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise | |
| 1211 | if (anyframe_type.result) |result| { | |
| 1212 | try renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, Space.None); // anyframe | |
| 1213 | 1213 | try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // -> |
| 1214 | 1214 | return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space); |
| 1215 | 1215 | } else { |
| 1216 | return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise | |
| 1216 | return renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, space); // anyframe | |
| 1217 | 1217 | } |
| 1218 | 1218 | }, |
| 1219 | 1219 |
std/zig/tokenizer.zig+2-2| ... | ... | @@ -15,6 +15,7 @@ pub const Token = struct { |
| 15 | 15 | Keyword{ .bytes = "align", .id = Id.Keyword_align }, |
| 16 | 16 | Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero }, |
| 17 | 17 | Keyword{ .bytes = "and", .id = Id.Keyword_and }, |
| 18 | Keyword{ .bytes = "anyframe", .id = Id.Keyword_anyframe }, | |
| 18 | 19 | Keyword{ .bytes = "asm", .id = Id.Keyword_asm }, |
| 19 | 20 | Keyword{ .bytes = "async", .id = Id.Keyword_async }, |
| 20 | 21 | Keyword{ .bytes = "await", .id = Id.Keyword_await }, |
| ... | ... | @@ -42,7 +43,6 @@ pub const Token = struct { |
| 42 | 43 | Keyword{ .bytes = "or", .id = Id.Keyword_or }, |
| 43 | 44 | Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse }, |
| 44 | 45 | Keyword{ .bytes = "packed", .id = Id.Keyword_packed }, |
| 45 | Keyword{ .bytes = "promise", .id = Id.Keyword_promise }, | |
| 46 | 46 | Keyword{ .bytes = "pub", .id = Id.Keyword_pub }, |
| 47 | 47 | Keyword{ .bytes = "resume", .id = Id.Keyword_resume }, |
| 48 | 48 | Keyword{ .bytes = "return", .id = Id.Keyword_return }, |
| ... | ... | @@ -174,7 +174,7 @@ pub const Token = struct { |
| 174 | 174 | Keyword_or, |
| 175 | 175 | Keyword_orelse, |
| 176 | 176 | Keyword_packed, |
| 177 | Keyword_promise, | |
| 177 | Keyword_anyframe, | |
| 178 | 178 | Keyword_pub, |
| 179 | 179 | Keyword_resume, |
| 180 | 180 | Keyword_return, |
test/stage1/behavior/type_info.zig+21-2| ... | ... | @@ -177,11 +177,11 @@ fn testUnion() void { |
| 177 | 177 | expect(TypeId(typeinfo_info) == TypeId.Union); |
| 178 | 178 | expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto); |
| 179 | 179 | expect(typeinfo_info.Union.tag_type.? == TypeId); |
| 180 | expect(typeinfo_info.Union.fields.len == 25); | |
| 180 | expect(typeinfo_info.Union.fields.len == 26); | |
| 181 | 181 | expect(typeinfo_info.Union.fields[4].enum_field != null); |
| 182 | 182 | expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4); |
| 183 | 183 | expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); |
| 184 | expect(typeinfo_info.Union.decls.len == 20); | |
| 184 | expect(typeinfo_info.Union.decls.len == 21); | |
| 185 | 185 | |
| 186 | 186 | const TestNoTagUnion = union { |
| 187 | 187 | Foo: void, |
| ... | ... | @@ -280,6 +280,25 @@ fn testVector() void { |
| 280 | 280 | expect(vec_info.Vector.child == i32); |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | test "type info: anyframe and anyframe->T" { | |
| 284 | testAnyFrame(); | |
| 285 | comptime testAnyFrame(); | |
| 286 | } | |
| 287 | ||
| 288 | fn testAnyFrame() void { | |
| 289 | { | |
| 290 | const anyframe_info = @typeInfo(anyframe->i32); | |
| 291 | expect(TypeId(anyframe_info) == .AnyFrame); | |
| 292 | expect(anyframe_info.AnyFrame.child.? == i32); | |
| 293 | } | |
| 294 | ||
| 295 | { | |
| 296 | const anyframe_info = @typeInfo(anyframe); | |
| 297 | expect(TypeId(anyframe_info) == .AnyFrame); | |
| 298 | expect(anyframe_info.AnyFrame.child == null); | |
| 299 | } | |
| 300 | } | |
| 301 | ||
| 283 | 302 | test "type info: optional field unwrapping" { |
| 284 | 303 | const Struct = struct { |
| 285 | 304 | cdOffset: u32, |