| author | |
| committer | |
| log | a8428b777c588e2dedfaebdd8c22a5b838d6b5ee |
| tree | d45f95557ee4a08febef2766efb628202c5ca3e7 |
| parent | ec3f362ae9722415223d15270ae58cfd3b50ddd0 |
34 files changed, 918 insertions(+), 181 deletions(-)
doc/langref.html.in+7| ... | ... | @@ -5769,6 +5769,13 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 5769 | 5769 | <p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p> |
| 5770 | 5770 | {#header_close#} |
| 5771 | 5771 | |
| 5772 | {#header_open|@Restricted#} | |
| 5773 | <pre>{#syntax#}@Restricted( | |
| 5774 | comptime Pointer: type, | |
| 5775 | ) type{#endsyntax#}</pre> | |
| 5776 | <p>Returns a restricted pointer type based on the specified pointer type.</p> | |
| 5777 | {#header_close#} | |
| 5778 | ||
| 5772 | 5779 | {#header_open|@Fn#} |
| 5773 | 5780 | <pre>{#syntax#}@Fn( |
| 5774 | 5781 | comptime param_types: []const type, |
lib/std/debug.zig+4| ... | ... | @@ -201,6 +201,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 201 | 201 | @branchHint(.cold); |
| 202 | 202 | call("'noreturn' function returned", @returnAddress()); |
| 203 | 203 | } |
| 204 | pub fn corruptRestrictedPointer() noreturn { | |
| 205 | @branchHint(.cold); | |
| 206 | call("corrupt restricted pointer value", @returnAddress()); | |
| 207 | } | |
| 204 | 208 | }; |
| 205 | 209 | } |
| 206 | 210 |
lib/std/debug/no_panic.zig+5| ... | ... | @@ -134,3 +134,8 @@ pub fn noreturnReturned() noreturn { |
| 134 | 134 | @branchHint(.cold); |
| 135 | 135 | @trap(); |
| 136 | 136 | } |
| 137 | ||
| 138 | pub fn corruptRestrictedPointer() noreturn { | |
| 139 | @branchHint(.cold); | |
| 140 | @trap(); | |
| 141 | } |
lib/std/debug/simple_panic.zig+4| ... | ... | @@ -126,3 +126,7 @@ pub fn memcpyAlias() noreturn { |
| 126 | 126 | pub fn noreturnReturned() noreturn { |
| 127 | 127 | call("'noreturn' function returned", null); |
| 128 | 128 | } |
| 129 | ||
| 130 | pub fn corruptRestrictedPointer() noreturn { | |
| 131 | call("corrupt restricted pointer value", null); | |
| 132 | } |
lib/std/zig/AstGen.zig+10-1| ... | ... | @@ -1208,7 +1208,7 @@ fn nameStratExpr( |
| 1208 | 1208 | const builtin_name = tree.tokenSlice(builtin_token); |
| 1209 | 1209 | const info = BuiltinFn.list.get(builtin_name) orelse return null; |
| 1210 | 1210 | switch (info.tag) { |
| 1211 | .Enum, .Struct, .Union => { | |
| 1211 | .Restricted, .Enum, .Struct, .Union => { | |
| 1212 | 1212 | var buf: [2]Ast.Node.Index = undefined; |
| 1213 | 1213 | const params = tree.builtinCallParams(&buf, node).?; |
| 1214 | 1214 | return try builtinCall(gz, scope, ri, node, params, false, name_strat); |
| ... | ... | @@ -9320,6 +9320,15 @@ fn builtinCall( |
| 9320 | 9320 | }); |
| 9321 | 9321 | return rvalue(gz, ri, result, node); |
| 9322 | 9322 | }, |
| 9323 | .Restricted => { | |
| 9324 | const unrestricted_ptr_ty = try typeExpr(gz, scope, params[0]); | |
| 9325 | const result = try gz.addExtendedPayloadSmall( | |
| 9326 | .reify_restricted, | |
| 9327 | @intFromEnum(reify_name_strat), | |
| 9328 | Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = unrestricted_ptr_ty }, | |
| 9329 | ); | |
| 9330 | return rvalue(gz, ri, result, node); | |
| 9331 | }, | |
| 9323 | 9332 | .Fn => { |
| 9324 | 9333 | const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes); |
| 9325 | 9334 | const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types); |
lib/std/zig/AstRlAnnotate.zig+1| ... | ... | @@ -903,6 +903,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 903 | 903 | .error_name, |
| 904 | 904 | .set_runtime_safety, |
| 905 | 905 | .Tuple, |
| 906 | .Restricted, | |
| 906 | 907 | .wasm_memory_size, |
| 907 | 908 | .splat, |
| 908 | 909 | .set_float_mode, |
lib/std/zig/BuiltinFn.zig+8| ... | ... | @@ -110,6 +110,7 @@ pub const Tag = enum { |
| 110 | 110 | Int, |
| 111 | 111 | Tuple, |
| 112 | 112 | Pointer, |
| 113 | Restricted, | |
| 113 | 114 | Fn, |
| 114 | 115 | Struct, |
| 115 | 116 | Union, |
| ... | ... | @@ -943,6 +944,13 @@ pub const list = list: { |
| 943 | 944 | .param_count = 4, |
| 944 | 945 | }, |
| 945 | 946 | }, |
| 947 | .{ | |
| 948 | "@Restricted", | |
| 949 | .{ | |
| 950 | .tag = .Restricted, | |
| 951 | .param_count = 1, | |
| 952 | }, | |
| 953 | }, | |
| 946 | 954 | .{ |
| 947 | 955 | "@Fn", |
| 948 | 956 | .{ |
lib/std/zig/Zir.zig+9-3| ... | ... | @@ -2062,6 +2062,10 @@ pub const Inst = struct { |
| 2062 | 2062 | /// Implements builtin `@Pointer`. |
| 2063 | 2063 | /// `operand` is payload index to `ReifyPointer`. |
| 2064 | 2064 | reify_pointer, |
| 2065 | /// Implements builtin `@Restricted`. | |
| 2066 | /// `operand` is payload index to `UnNode`. | |
| 2067 | /// `small` contains `NameStrategy`. | |
| 2068 | reify_restricted, | |
| 2065 | 2069 | /// Implements builtin `@Fn`. |
| 2066 | 2070 | /// `operand` is payload index to `ReifyFn`. |
| 2067 | 2071 | reify_fn, |
| ... | ... | @@ -4431,15 +4435,16 @@ fn findTrackableInner( |
| 4431 | 4435 | }, |
| 4432 | 4436 | |
| 4433 | 4437 | // Reifications need tracking. |
| 4434 | .reify_enum, | |
| 4438 | .reify_restricted, | |
| 4435 | 4439 | .reify_struct, |
| 4436 | 4440 | .reify_union, |
| 4441 | .reify_enum, | |
| 4437 | 4442 | => return contents.other.append(gpa, inst), |
| 4438 | 4443 | |
| 4439 | 4444 | // Type declarations need tracking. |
| 4440 | 4445 | .struct_decl, |
| 4441 | .union_decl, | |
| 4442 | 4446 | .enum_decl, |
| 4447 | .union_decl, | |
| 4443 | 4448 | .opaque_decl, |
| 4444 | 4449 | => return contents.type_decls.append(gpa, inst), |
| 4445 | 4450 | } |
| ... | ... | @@ -5232,9 +5237,10 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void { |
| 5232 | 5237 | .union_decl, |
| 5233 | 5238 | .enum_decl, |
| 5234 | 5239 | .opaque_decl, |
| 5235 | .reify_enum, | |
| 5240 | .reify_restricted, | |
| 5236 | 5241 | .reify_struct, |
| 5237 | 5242 | .reify_union, |
| 5243 | .reify_enum, | |
| 5238 | 5244 | => {}, // tracked in order, as the owner instructions of explicit container types |
| 5239 | 5245 | else => unreachable, // assertion failure; not trackable |
| 5240 | 5246 | }, |
src/Air.zig+14| ... | ... | @@ -633,6 +633,16 @@ pub const Inst = struct { |
| 633 | 633 | /// wrap from E to E!T |
| 634 | 634 | /// Uses the `ty_op` field. |
| 635 | 635 | wrap_errunion_err, |
| 636 | /// Converts a runtime restricted pointer into the corresponding unrestricted pointer. | |
| 637 | /// Uses the `ty_op` field. | |
| 638 | unwrap_restricted, | |
| 639 | /// Converts a runtime restricted pointer into the corresponding unrestricted pointer. | |
| 640 | /// All invalid pointers are a guaranteed safety panic, which is only applicable | |
| 641 | /// when the restricted pointer type belongs to a module with safety enabled. | |
| 642 | /// The panic handler function must be populated before lowering AIR | |
| 643 | /// that contains this instruction. | |
| 644 | /// Uses the `ty_op` field. | |
| 645 | unwrap_restricted_safe, | |
| 636 | 646 | /// Given a pointer to a struct or union and a field index, returns a pointer to the field. |
| 637 | 647 | /// Uses the `ty_pl` field, payload is `StructField`. |
| 638 | 648 | /// TODO rename to `agg_field_ptr`. |
| ... | ... | @@ -1681,6 +1691,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1681 | 1691 | .unwrap_errunion_err_ptr, |
| 1682 | 1692 | .wrap_errunion_payload, |
| 1683 | 1693 | .wrap_errunion_err, |
| 1694 | .unwrap_restricted, | |
| 1695 | .unwrap_restricted_safe, | |
| 1684 | 1696 | .slice_ptr, |
| 1685 | 1697 | .ptr_slice_len_ptr, |
| 1686 | 1698 | .ptr_slice_ptr_ptr, |
| ... | ... | @@ -1886,6 +1898,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1886 | 1898 | .unreach, |
| 1887 | 1899 | .optional_payload_ptr_set, |
| 1888 | 1900 | .errunion_payload_ptr_set, |
| 1901 | .unwrap_restricted_safe, | |
| 1889 | 1902 | .set_union_tag, |
| 1890 | 1903 | .memset, |
| 1891 | 1904 | .memset_safe, |
| ... | ... | @@ -2014,6 +2027,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 2014 | 2027 | .unwrap_errunion_payload_ptr, |
| 2015 | 2028 | .wrap_errunion_payload, |
| 2016 | 2029 | .wrap_errunion_err, |
| 2030 | .unwrap_restricted, | |
| 2017 | 2031 | .struct_field_ptr, |
| 2018 | 2032 | .struct_field_ptr_index_0, |
| 2019 | 2033 | .struct_field_ptr_index_1, |
src/Air/Legalize.zig+2| ... | ... | @@ -741,6 +741,8 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { |
| 741 | 741 | .errunion_payload_ptr_set, |
| 742 | 742 | .wrap_errunion_payload, |
| 743 | 743 | .wrap_errunion_err, |
| 744 | .unwrap_restricted, | |
| 745 | .unwrap_restricted_safe, | |
| 744 | 746 | .struct_field_ptr, |
| 745 | 747 | .struct_field_ptr_index_0, |
| 746 | 748 | .struct_field_ptr_index_1, |
src/Air/Liveness.zig+2| ... | ... | @@ -506,6 +506,8 @@ fn analyzeInst( |
| 506 | 506 | .unwrap_errunion_err_ptr, |
| 507 | 507 | .wrap_errunion_payload, |
| 508 | 508 | .wrap_errunion_err, |
| 509 | .unwrap_restricted, | |
| 510 | .unwrap_restricted_safe, | |
| 509 | 511 | .slice_ptr, |
| 510 | 512 | .slice_len, |
| 511 | 513 | .ptr_slice_len_ptr, |
src/Air/Liveness/Verify.zig+2| ... | ... | @@ -96,6 +96,8 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 96 | 96 | .unwrap_errunion_err_ptr, |
| 97 | 97 | .wrap_errunion_payload, |
| 98 | 98 | .wrap_errunion_err, |
| 99 | .unwrap_restricted, | |
| 100 | .unwrap_restricted_safe, | |
| 99 | 101 | .slice_ptr, |
| 100 | 102 | .slice_len, |
| 101 | 103 | .ptr_slice_len_ptr, |
src/Air/print.zig+2| ... | ... | @@ -250,6 +250,8 @@ const Writer = struct { |
| 250 | 250 | .unwrap_errunion_err_ptr, |
| 251 | 251 | .wrap_errunion_payload, |
| 252 | 252 | .wrap_errunion_err, |
| 253 | .unwrap_restricted, | |
| 254 | .unwrap_restricted_safe, | |
| 253 | 255 | .slice_ptr, |
| 254 | 256 | .slice_len, |
| 255 | 257 | .ptr_slice_len_ptr, |
src/InternPool.zig+176-54| ... | ... | @@ -1969,6 +1969,7 @@ pub const CaptureValue = packed struct(u32) { |
| 1969 | 1969 | pub const Key = union(enum) { |
| 1970 | 1970 | int_type: IntType, |
| 1971 | 1971 | ptr_type: PtrType, |
| 1972 | restricted_ptr_type: RestrictedPtrType, | |
| 1972 | 1973 | array_type: ArrayType, |
| 1973 | 1974 | vector_type: VectorType, |
| 1974 | 1975 | opt_type: Index, |
| ... | ... | @@ -2094,6 +2095,14 @@ pub const Key = union(enum) { |
| 2094 | 2095 | pub const AddressSpace = std.builtin.AddressSpace; |
| 2095 | 2096 | }; |
| 2096 | 2097 | |
| 2098 | /// Extern layout so it can be hashed with `std.mem.asBytes`. | |
| 2099 | pub const RestrictedPtrType = extern struct { | |
| 2100 | /// A `reify_restricted` instruction. | |
| 2101 | zir_index: TrackedInst.Index, | |
| 2102 | /// The underlying pointer type. | |
| 2103 | unrestricted_ptr_type: Index, | |
| 2104 | }; | |
| 2105 | ||
| 2097 | 2106 | /// Extern so that hashing can be done via memory reinterpreting. |
| 2098 | 2107 | pub const ArrayType = extern struct { |
| 2099 | 2108 | len: u64, |
| ... | ... | @@ -2590,6 +2599,7 @@ pub const Key = union(enum) { |
| 2590 | 2599 | return switch (key) { |
| 2591 | 2600 | // TODO: assert no padding in these types |
| 2592 | 2601 | inline .ptr_type, |
| 2602 | .restricted_ptr_type, | |
| 2593 | 2603 | .array_type, |
| 2594 | 2604 | .vector_type, |
| 2595 | 2605 | .opt_type, |
| ... | ... | @@ -2606,11 +2616,11 @@ pub const Key = union(enum) { |
| 2606 | 2616 | .un, |
| 2607 | 2617 | => |x| Hash.hash(seed, asBytes(&x)), |
| 2608 | 2618 | |
| 2609 | .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)), | |
| 2619 | .int_type => |x| Hash.hash(seed | @shlExact(@as(u64, @intFromEnum(x.signedness)), 63), asBytes(&x.bits)), | |
| 2610 | 2620 | |
| 2611 | 2621 | .error_union => |x| switch (x.val) { |
| 2612 | .err_name => |y| Hash.hash(seed + 0, asBytes(&x.ty) ++ asBytes(&y)), | |
| 2613 | .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)), | |
| 2622 | .err_name => |y| Hash.hash(seed | @as(u64, 0 << 63), asBytes(&x.ty) ++ asBytes(&y)), | |
| 2623 | .payload => |y| Hash.hash(seed | @as(u64, 1 << 63), asBytes(&x.ty) ++ asBytes(&y)), | |
| 2614 | 2624 | }, |
| 2615 | 2625 | |
| 2616 | 2626 | .opaque_type, |
| ... | ... | @@ -2631,10 +2641,7 @@ pub const Key = union(enum) { |
| 2631 | 2641 | std.hash.autoHash(&hasher, cv); |
| 2632 | 2642 | } |
| 2633 | 2643 | }, |
| 2634 | .reified => |reified| { | |
| 2635 | std.hash.autoHash(&hasher, reified.zir_index); | |
| 2636 | std.hash.autoHash(&hasher, reified.type_hash); | |
| 2637 | }, | |
| 2644 | .reified => |reified| std.hash.autoHash(&hasher, reified), | |
| 2638 | 2645 | .generated_union_tag => |union_type| { |
| 2639 | 2646 | std.hash.autoHash(&hasher, union_type); |
| 2640 | 2647 | }, |
| ... | ... | @@ -2672,7 +2679,7 @@ pub const Key = union(enum) { |
| 2672 | 2679 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. |
| 2673 | 2680 | // This is sound due to pointer provenance rules. |
| 2674 | 2681 | const addr_tag: Key.Ptr.BaseAddr.Tag = ptr.base_addr; |
| 2675 | const seed2 = seed + @intFromEnum(addr_tag); | |
| 2682 | const seed2 = seed | @shlExact(@as(u64, @intFromEnum(addr_tag)), 60); | |
| 2676 | 2683 | const big_offset: i128 = ptr.byte_offset; |
| 2677 | 2684 | const common = asBytes(&ptr.ty) ++ asBytes(&big_offset); |
| 2678 | 2685 | return switch (ptr.base_addr) { |
| ... | ... | @@ -3020,6 +3027,8 @@ pub const Key = union(enum) { |
| 3020 | 3027 | } |
| 3021 | 3028 | }, |
| 3022 | 3029 | |
| 3030 | .restricted_ptr_type => |a_r| return std.meta.eql(a_r, b.restricted_ptr_type), | |
| 3031 | ||
| 3023 | 3032 | inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| { |
| 3024 | 3033 | const b_info = @field(b, @tagName(a_tag_ct)); |
| 3025 | 3034 | if (std.meta.activeTag(a_info) != b_info) return false; |
| ... | ... | @@ -3037,11 +3046,7 @@ pub const Key = union(enum) { |
| 3037 | 3046 | }; |
| 3038 | 3047 | return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures)); |
| 3039 | 3048 | }, |
| 3040 | .reified => |a_r| { | |
| 3041 | const b_r = b_info.reified; | |
| 3042 | return a_r.zir_index == b_r.zir_index and | |
| 3043 | a_r.type_hash == b_r.type_hash; | |
| 3044 | }, | |
| 3049 | .reified => |a_r| return std.meta.eql(a_r, b_info.reified), | |
| 3045 | 3050 | .generated_union_tag => |a_union_ty| return a_union_ty == b_info.generated_union_tag, |
| 3046 | 3051 | } |
| 3047 | 3052 | }, |
| ... | ... | @@ -3125,6 +3130,7 @@ pub const Key = union(enum) { |
| 3125 | 3130 | return switch (key) { |
| 3126 | 3131 | .int_type, |
| 3127 | 3132 | .ptr_type, |
| 3133 | .restricted_ptr_type, | |
| 3128 | 3134 | .array_type, |
| 3129 | 3135 | .vector_type, |
| 3130 | 3136 | .opt_type, |
| ... | ... | @@ -3172,6 +3178,8 @@ pub const Key = union(enum) { |
| 3172 | 3178 | } |
| 3173 | 3179 | }; |
| 3174 | 3180 | |
| 3181 | pub const LoadedRestrictedType = Tag.TypeRestricted; | |
| 3182 | ||
| 3175 | 3183 | pub const LoadedStructType = struct { |
| 3176 | 3184 | /// Index of the `struct_decl` or `reify` ZIR instruction. |
| 3177 | 3185 | zir_index: TrackedInst.Index, |
| ... | ... | @@ -3499,6 +3507,12 @@ pub const LoadedOpaqueType = struct { |
| 3499 | 3507 | namespace: NamespaceIndex, |
| 3500 | 3508 | }; |
| 3501 | 3509 | |
| 3510 | pub fn loadRestrictedType(ip: *const InternPool, index: Index) LoadedRestrictedType { | |
| 3511 | const unwrapped_index = index.unwrap(ip); | |
| 3512 | const item = unwrapped_index.getItem(ip); | |
| 3513 | return extraData(unwrapped_index.getExtra(ip), Tag.TypeRestricted, item.data); | |
| 3514 | } | |
| 3515 | ||
| 3502 | 3516 | pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3503 | 3517 | const unwrapped_index = index.unwrap(ip); |
| 3504 | 3518 | const extra_list = unwrapped_index.getExtra(ip); |
| ... | ... | @@ -4173,6 +4187,7 @@ pub const Index = enum(u32) { |
| 4173 | 4187 | type_array_small: struct { data: *Vector }, |
| 4174 | 4188 | type_vector: struct { data: *Vector }, |
| 4175 | 4189 | type_pointer: struct { data: *Tag.TypePointer }, |
| 4190 | type_restricted: struct { data: *Tag.TypeRestricted }, | |
| 4176 | 4191 | type_slice: DataIsIndex, |
| 4177 | 4192 | type_optional: DataIsIndex, |
| 4178 | 4193 | type_anyframe: DataIsIndex, |
| ... | ... | @@ -4771,6 +4786,9 @@ pub const Tag = enum(u8) { |
| 4771 | 4786 | /// A slice type. |
| 4772 | 4787 | /// data is Index of underlying pointer type. |
| 4773 | 4788 | type_slice, |
| 4789 | /// A restricted pointer type. | |
| 4790 | /// data is payload to `TypeRestricted`. | |
| 4791 | type_restricted, | |
| 4774 | 4792 | /// An optional type. |
| 4775 | 4793 | /// data is the child type. |
| 4776 | 4794 | type_optional, |
| ... | ... | @@ -5024,13 +5042,6 @@ pub const Tag = enum(u8) { |
| 5024 | 5042 | /// data is extra index to `MemoizedCall` |
| 5025 | 5043 | memoized_call, |
| 5026 | 5044 | |
| 5027 | const ErrorUnionType = Key.ErrorUnionType; | |
| 5028 | const TypeValue = Key.TypeValue; | |
| 5029 | const Error = Key.Error; | |
| 5030 | const EnumTag = Key.EnumTag; | |
| 5031 | const Union = Key.Union; | |
| 5032 | const TypePointer = Key.PtrType; | |
| 5033 | ||
| 5034 | 5045 | const struct_packed_encoding = .{ |
| 5035 | 5046 | .summary = .@"{.payload.name%summary#\"}", |
| 5036 | 5047 | .payload = TypeStructPacked, |
| ... | ... | @@ -5116,6 +5127,7 @@ pub const Tag = enum(u8) { |
| 5116 | 5127 | .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector }, |
| 5117 | 5128 | .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector }, |
| 5118 | 5129 | .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer }, |
| 5130 | .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted }, | |
| 5119 | 5131 | .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index }, |
| 5120 | 5132 | .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index }, |
| 5121 | 5133 | .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index }, |
| ... | ... | @@ -5363,6 +5375,25 @@ pub const Tag = enum(u8) { |
| 5363 | 5375 | return @field(encodings, @tagName(tag)).payload; |
| 5364 | 5376 | } |
| 5365 | 5377 | |
| 5378 | const ErrorUnionType = Key.ErrorUnionType; | |
| 5379 | const TypeValue = Key.TypeValue; | |
| 5380 | const Error = Key.Error; | |
| 5381 | const EnumTag = Key.EnumTag; | |
| 5382 | const Union = Key.Union; | |
| 5383 | const TypePointer = Key.PtrType; | |
| 5384 | ||
| 5385 | const TypeRestricted = struct { | |
| 5386 | /// Index of the `reify_restricted` ZIR instruction. | |
| 5387 | zir_index: TrackedInst.Index, | |
| 5388 | ||
| 5389 | // TODO: the non-fqn will be needed by the new dwarf structure | |
| 5390 | /// The name of this restricted type. | |
| 5391 | name: NullTerminatedString, | |
| 5392 | ||
| 5393 | /// The pointer type this restricted type is based on. | |
| 5394 | unrestricted_ptr_type: Index, | |
| 5395 | }; | |
| 5396 | ||
| 5366 | 5397 | pub const Extern = struct { |
| 5367 | 5398 | // name, is_const, alignment, addrspace come from `owner_nav`. |
| 5368 | 5399 | ty: Index, |
| ... | ... | @@ -6455,6 +6486,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6455 | 6486 | return .{ .ptr_type = ptr_info }; |
| 6456 | 6487 | }, |
| 6457 | 6488 | |
| 6489 | .type_restricted => { | |
| 6490 | const restricted_ptr_info = extraData(unwrapped_index.getExtra(ip), Tag.TypeRestricted, data); | |
| 6491 | return .{ .restricted_ptr_type = .{ | |
| 6492 | .zir_index = restricted_ptr_info.zir_index, | |
| 6493 | .unrestricted_ptr_type = restricted_ptr_info.unrestricted_ptr_type, | |
| 6494 | } }; | |
| 6495 | }, | |
| 6496 | ||
| 6458 | 6497 | .type_optional => .{ .opt_type = @enumFromInt(data) }, |
| 6459 | 6498 | .type_anyframe => .{ .anyframe_type = @enumFromInt(data) }, |
| 6460 | 6499 | |
| ... | ... | @@ -7237,6 +7276,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7237 | 7276 | .data = try addExtra(extra, ptr_type_adjusted), |
| 7238 | 7277 | }); |
| 7239 | 7278 | }, |
| 7279 | .restricted_ptr_type => unreachable, // instead getReifiedRestrictedType | |
| 7240 | 7280 | .array_type => |array_type| { |
| 7241 | 7281 | assert(array_type.child != .none); |
| 7242 | 7282 | assert(array_type.sentinel == .none or ip.typeOf(array_type.sentinel) == array_type.child); |
| ... | ... | @@ -7367,7 +7407,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7367 | 7407 | }, |
| 7368 | 7408 | |
| 7369 | 7409 | .ptr => |ptr| { |
| 7370 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | |
| 7410 | const ptr_type = switch (ip.indexToKey(ptr.ty)) { | |
| 7411 | .ptr_type => |ptr_type| ptr_type, | |
| 7412 | .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 7413 | else => unreachable, | |
| 7414 | }; | |
| 7371 | 7415 | assert(ptr_type.flags.size != .slice); |
| 7372 | 7416 | items.appendAssumeCapacity(switch (ptr.base_addr) { |
| 7373 | 7417 | .nav => |nav| .{ |
| ... | ... | @@ -7959,6 +8003,65 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7959 | 8003 | return gop.put(); |
| 7960 | 8004 | } |
| 7961 | 8005 | |
| 8006 | pub fn getReifiedRestrictedType( | |
| 8007 | ip: *InternPool, | |
| 8008 | gpa: Allocator, | |
| 8009 | io: Io, | |
| 8010 | tid: Zcu.PerThread.Id, | |
| 8011 | zir_index: TrackedInst.Index, | |
| 8012 | unrestricted_ptr_type: Index, | |
| 8013 | ) Allocator.Error!WipRestrictedType.Result { | |
| 8014 | var gop = try ip.getOrPutKey(gpa, io, tid, .{ .restricted_ptr_type = .{ | |
| 8015 | .zir_index = zir_index, | |
| 8016 | .unrestricted_ptr_type = unrestricted_ptr_type, | |
| 8017 | } }); | |
| 8018 | defer gop.deinit(); | |
| 8019 | if (gop == .existing) return .{ .existing = gop.existing }; | |
| 8020 | ||
| 8021 | const local = ip.getLocal(tid); | |
| 8022 | const items = local.getMutableItems(gpa, io); | |
| 8023 | const extra = local.getMutableExtra(gpa, io); | |
| 8024 | try items.ensureUnusedCapacity(1); | |
| 8025 | ||
| 8026 | try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeRestricted).@"struct".fields.len); | |
| 8027 | ||
| 8028 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{ | |
| 8029 | .zir_index = zir_index, | |
| 8030 | .name = undefined, | |
| 8031 | .unrestricted_ptr_type = unrestricted_ptr_type, | |
| 8032 | }); | |
| 8033 | items.appendAssumeCapacity(.{ | |
| 8034 | .tag = .type_restricted, | |
| 8035 | .data = extra_index, | |
| 8036 | }); | |
| 8037 | return .{ .wip = .{ | |
| 8038 | .index = gop.put(), | |
| 8039 | .tid = tid, | |
| 8040 | .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeRestricted, "name").?, | |
| 8041 | } }; | |
| 8042 | } | |
| 8043 | ||
| 8044 | pub const WipRestrictedType = struct { | |
| 8045 | index: Index, | |
| 8046 | tid: Zcu.PerThread.Id, | |
| 8047 | type_name_index: u32, | |
| 8048 | ||
| 8049 | pub fn setName(wip: WipRestrictedType, ip: *InternPool, type_name: NullTerminatedString) void { | |
| 8050 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | |
| 8051 | const extra_items = extra.view().items(.@"0"); | |
| 8052 | extra_items[wip.type_name_index] = @intFromEnum(type_name); | |
| 8053 | } | |
| 8054 | ||
| 8055 | pub fn cancel(wip: WipRestrictedType, ip: *InternPool, tid: Zcu.PerThread.Id) void { | |
| 8056 | ip.remove(tid, wip.index); | |
| 8057 | } | |
| 8058 | ||
| 8059 | pub const Result = union(enum) { | |
| 8060 | wip: WipRestrictedType, | |
| 8061 | existing: Index, | |
| 8062 | }; | |
| 8063 | }; | |
| 8064 | ||
| 7962 | 8065 | pub fn getDeclaredStructType( |
| 7963 | 8066 | ip: *InternPool, |
| 7964 | 8067 | gpa: Allocator, |
| ... | ... | @@ -9925,6 +10028,7 @@ test "basic usage" { |
| 9925 | 10028 | pub fn childType(ip: *const InternPool, i: Index) Index { |
| 9926 | 10029 | return switch (ip.indexToKey(i)) { |
| 9927 | 10030 | .ptr_type => |ptr_type| ptr_type.child, |
| 10031 | .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type.child, | |
| 9928 | 10032 | .vector_type => |vector_type| vector_type.child, |
| 9929 | 10033 | .array_type => |array_type| array_type.child, |
| 9930 | 10034 | .opt_type, .anyframe_type => |child| child, |
| ... | ... | @@ -10007,22 +10111,28 @@ pub fn getCoerced( |
| 10007 | 10111 | .val = .none, |
| 10008 | 10112 | } }); |
| 10009 | 10113 | |
| 10010 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { | |
| 10011 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10012 | .ty = new_ty, | |
| 10013 | .base_addr = .int, | |
| 10014 | .byte_offset = 0, | |
| 10015 | } }), | |
| 10016 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10017 | .ty = new_ty, | |
| 10018 | .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10019 | .ty = ip.slicePtrType(new_ty), | |
| 10114 | new_ty: switch (ip.indexToKey(new_ty)) { | |
| 10115 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | |
| 10116 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10117 | .ty = new_ty, | |
| 10020 | 10118 | .base_addr = .int, |
| 10021 | 10119 | .byte_offset = 0, |
| 10022 | 10120 | } }), |
| 10023 | .len = .undef_usize, | |
| 10024 | } }), | |
| 10025 | }; | |
| 10121 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10122 | .ty = new_ty, | |
| 10123 | .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10124 | .ty = ip.slicePtrType(new_ty), | |
| 10125 | .base_addr = .int, | |
| 10126 | .byte_offset = 0, | |
| 10127 | } }), | |
| 10128 | .len = .undef_usize, | |
| 10129 | } }), | |
| 10130 | }, | |
| 10131 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ | |
| 10132 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 10133 | }, | |
| 10134 | else => {}, | |
| 10135 | } | |
| 10026 | 10136 | }, |
| 10027 | 10137 | else => { |
| 10028 | 10138 | const unwrapped_val = val.unwrap(ip); |
| ... | ... | @@ -10101,28 +10211,40 @@ pub fn getCoerced( |
| 10101 | 10211 | }, |
| 10102 | 10212 | else => {}, |
| 10103 | 10213 | }, |
| 10104 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .slice) | |
| 10105 | return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10106 | .ty = new_ty, | |
| 10107 | .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)), | |
| 10108 | .len = slice.len, | |
| 10109 | } }) | |
| 10110 | else if (ip.isIntegerType(new_ty)) | |
| 10111 | return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty), | |
| 10112 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .slice) | |
| 10113 | return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10114 | .ty = new_ty, | |
| 10115 | .base_addr = ptr.base_addr, | |
| 10116 | .byte_offset = ptr.byte_offset, | |
| 10117 | } }) | |
| 10118 | else if (ip.isIntegerType(new_ty)) | |
| 10119 | switch (ptr.base_addr) { | |
| 10214 | .slice => |slice| new_ty: switch (ip.indexToKey(new_ty)) { | |
| 10215 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | |
| 10216 | .one, .many, .c => {}, | |
| 10217 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10218 | .ty = new_ty, | |
| 10219 | .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)), | |
| 10220 | .len = slice.len, | |
| 10221 | } }), | |
| 10222 | }, | |
| 10223 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ | |
| 10224 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 10225 | }, | |
| 10226 | else => if (ip.isIntegerType(new_ty)) return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty), | |
| 10227 | }, | |
| 10228 | .ptr => |ptr| new_ty: switch (ip.indexToKey(new_ty)) { | |
| 10229 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | |
| 10230 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10231 | .ty = new_ty, | |
| 10232 | .base_addr = ptr.base_addr, | |
| 10233 | .byte_offset = ptr.byte_offset, | |
| 10234 | } }), | |
| 10235 | .slice => {}, | |
| 10236 | }, | |
| 10237 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ | |
| 10238 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 10239 | }, | |
| 10240 | else => if (ip.isIntegerType(new_ty)) switch (ptr.base_addr) { | |
| 10120 | 10241 | .int => return ip.get(gpa, io, tid, .{ .int = .{ |
| 10121 | 10242 | .ty = .usize_type, |
| 10122 | 10243 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, |
| 10123 | 10244 | } }), |
| 10124 | 10245 | else => {}, |
| 10125 | 10246 | }, |
| 10247 | }, | |
| 10126 | 10248 | .opt => |opt| switch (ip.indexToKey(new_ty)) { |
| 10127 | 10249 | .ptr_type => |ptr_type| return switch (opt.val) { |
| 10128 | 10250 | .none => switch (ptr_type.flags.size) { |
| ... | ... | @@ -10397,10 +10519,6 @@ pub fn isFunctionType(ip: *const InternPool, ty: Index) bool { |
| 10397 | 10519 | return ip.indexToKey(ty) == .func_type; |
| 10398 | 10520 | } |
| 10399 | 10521 | |
| 10400 | pub fn isPointerType(ip: *const InternPool, ty: Index) bool { | |
| 10401 | return ip.indexToKey(ty) == .ptr_type; | |
| 10402 | } | |
| 10403 | ||
| 10404 | 10522 | pub fn isOptionalType(ip: *const InternPool, ty: Index) bool { |
| 10405 | 10523 | return ip.indexToKey(ty) == .opt_type; |
| 10406 | 10524 | } |
| ... | ... | @@ -10577,6 +10695,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10577 | 10695 | .type_array_big => @sizeOf(Array), |
| 10578 | 10696 | .type_vector => @sizeOf(Vector), |
| 10579 | 10697 | .type_pointer => @sizeOf(Tag.TypePointer), |
| 10698 | .type_restricted => @sizeOf(Tag.TypeRestricted), | |
| 10580 | 10699 | .type_slice => 0, |
| 10581 | 10700 | .type_optional => 0, |
| 10582 | 10701 | .type_anyframe => 0, |
| ... | ... | @@ -10838,6 +10957,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 10838 | 10957 | .type_array_big, |
| 10839 | 10958 | .type_vector, |
| 10840 | 10959 | .type_pointer, |
| 10960 | .type_restricted, | |
| 10841 | 10961 | .type_optional, |
| 10842 | 10962 | .type_anyframe, |
| 10843 | 10963 | .type_error_union, |
| ... | ... | @@ -11576,6 +11696,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11576 | 11696 | .type_array_small, |
| 11577 | 11697 | .type_vector, |
| 11578 | 11698 | .type_pointer, |
| 11699 | .type_restricted, | |
| 11579 | 11700 | .type_slice, |
| 11580 | 11701 | .type_optional, |
| 11581 | 11702 | .type_anyframe, |
| ... | ... | @@ -11921,6 +12042,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 11921 | 12042 | |
| 11922 | 12043 | .type_pointer, |
| 11923 | 12044 | .type_slice, |
| 12045 | .type_restricted, | |
| 11924 | 12046 | => .pointer, |
| 11925 | 12047 | |
| 11926 | 12048 | .type_optional => .optional, |
src/Sema.zig+197-34| ... | ... | @@ -398,7 +398,7 @@ pub const Block = struct { |
| 398 | 398 | /// The name of the current "context" for naming namespace types. |
| 399 | 399 | /// The interpretation of this depends on the name strategy in ZIR, but the name |
| 400 | 400 | /// is always incorporated into the type name somehow. |
| 401 | /// See `Sema.setTypeName`. | |
| 401 | /// See `Sema.computeTypeName`. | |
| 402 | 402 | type_name_ctx: InternPool.NullTerminatedString, |
| 403 | 403 | |
| 404 | 404 | /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block. |
| ... | ... | @@ -1435,6 +1435,7 @@ fn analyzeBodyInner( |
| 1435 | 1435 | .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended), |
| 1436 | 1436 | .reify_tuple => try sema.zirReifyTuple( block, extended), |
| 1437 | 1437 | .reify_pointer => try sema.zirReifyPointer( block, extended), |
| 1438 | .reify_restricted => try sema.zirReifyRestricted( block, extended, inst), | |
| 1438 | 1439 | .reify_fn => try sema.zirReifyFn( block, extended), |
| 1439 | 1440 | .reify_struct => try sema.zirReifyStruct( block, extended, inst), |
| 1440 | 1441 | .reify_union => try sema.zirReifyUnion( block, extended, inst), |
| ... | ... | @@ -18956,7 +18957,8 @@ fn structInitAnon( |
| 18956 | 18957 | .existing => |ty| .fromInterned(ty), |
| 18957 | 18958 | .wip => |wip| ty: { |
| 18958 | 18959 | errdefer wip.cancel(ip, pt.tid); |
| 18959 | try sema.setTypeName(block, &wip, .anon, "struct", inst); | |
| 18960 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, .anon, "struct", inst); | |
| 18961 | wip.setName(ip, type_name, name_nav); | |
| 18960 | 18962 | |
| 18961 | 18963 | // Reified structs have field information populated immediately. |
| 18962 | 18964 | @memcpy(wip.field_names.get(ip), names); |
| ... | ... | @@ -19879,6 +19881,62 @@ fn zirReifyPointer( |
| 19879 | 19881 | })); |
| 19880 | 19882 | } |
| 19881 | 19883 | |
| 19884 | fn zirReifyRestricted( | |
| 19885 | sema: *Sema, | |
| 19886 | block: *Block, | |
| 19887 | extended: Zir.Inst.Extended.InstData, | |
| 19888 | inst: Zir.Inst.Index, | |
| 19889 | ) CompileError!Air.Inst.Ref { | |
| 19890 | const pt = sema.pt; | |
| 19891 | const zcu = pt.zcu; | |
| 19892 | const comp = zcu.comp; | |
| 19893 | const gpa = comp.gpa; | |
| 19894 | const io = comp.io; | |
| 19895 | const ip = &zcu.intern_pool; | |
| 19896 | ||
| 19897 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | |
| 19898 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | |
| 19899 | const tracked_inst = try block.trackZir(inst); | |
| 19900 | ||
| 19901 | const src: LazySrcLoc = .{ | |
| 19902 | .base_node_inst = tracked_inst, | |
| 19903 | .offset = .nodeOffset(.zero), | |
| 19904 | }; | |
| 19905 | const ptr_type_src: LazySrcLoc = .{ | |
| 19906 | .base_node_inst = tracked_inst, | |
| 19907 | .offset = .{ .node_offset_builtin_call_arg = .{ | |
| 19908 | .builtin_call_node = extra.node, | |
| 19909 | .arg_index = 0, | |
| 19910 | } }, | |
| 19911 | }; | |
| 19912 | ||
| 19913 | const operand = try sema.resolveType(block, src, extra.operand); | |
| 19914 | const unrestricted_ptr_type: Type = switch (ip.indexToKey(operand.toIntern())) { | |
| 19915 | else => return sema.fail(block, ptr_type_src, "expected pointer type, found '{f}'", .{operand.fmt(pt)}), | |
| 19916 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | |
| 19917 | .one, .many, .c => operand, | |
| 19918 | .slice => return sema.fail(block, ptr_type_src, "slice types cannot be restricted", .{}), | |
| 19919 | }, | |
| 19920 | .restricted_ptr_type => |restricted_ptr_type| .fromInterned(restricted_ptr_type.unrestricted_ptr_type), | |
| 19921 | }; | |
| 19922 | ||
| 19923 | switch (try ip.getReifiedRestrictedType(gpa, io, pt.tid, tracked_inst, unrestricted_ptr_type.toIntern())) { | |
| 19924 | .existing => |ty| { | |
| 19925 | try sema.addTypeReferenceEntry(src, .fromInterned(ty)); | |
| 19926 | // No need for `ensureNamespaceUpToDate` because this type doesn't have a namespace. | |
| 19927 | return .fromIntern(ty); | |
| 19928 | }, | |
| 19929 | .wip => |wip| { | |
| 19930 | errdefer wip.cancel(ip, pt.tid); | |
| 19931 | const type_name, _ = try sema.computeTypeName(block, wip.index, name_strategy, "restricted", inst); | |
| 19932 | wip.setName(ip, type_name); | |
| 19933 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); | |
| 19934 | try sema.addTypeReferenceEntry(src, .fromInterned(wip.index)); | |
| 19935 | return .fromIntern(wip.index); | |
| 19936 | }, | |
| 19937 | } | |
| 19938 | } | |
| 19939 | ||
| 19882 | 19940 | fn zirReifyFn( |
| 19883 | 19941 | sema: *Sema, |
| 19884 | 19942 | block: *Block, |
| ... | ... | @@ -20194,7 +20252,8 @@ fn zirReifyStruct( |
| 20194 | 20252 | }, |
| 20195 | 20253 | .wip => |wip| { |
| 20196 | 20254 | errdefer wip.cancel(ip, pt.tid); |
| 20197 | try sema.setTypeName(block, &wip, name_strategy, "struct", inst); | |
| 20255 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "struct", inst); | |
| 20256 | wip.setName(ip, type_name, name_nav); | |
| 20198 | 20257 | for (0..fields_len) |field_idx| { |
| 20199 | 20258 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); |
| 20200 | 20259 | const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx); |
| ... | ... | @@ -20438,7 +20497,8 @@ fn zirReifyUnion( |
| 20438 | 20497 | }, |
| 20439 | 20498 | .wip => |wip| { |
| 20440 | 20499 | errdefer wip.cancel(ip, pt.tid); |
| 20441 | try sema.setTypeName(block, &wip, name_strategy, "union", inst); | |
| 20500 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "union", inst); | |
| 20501 | wip.setName(ip, type_name, name_nav); | |
| 20442 | 20502 | |
| 20443 | 20503 | for (0..fields_len) |field_idx| { |
| 20444 | 20504 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); |
| ... | ... | @@ -20603,8 +20663,8 @@ fn zirReifyEnum( |
| 20603 | 20663 | }, |
| 20604 | 20664 | .wip => |wip| { |
| 20605 | 20665 | errdefer wip.cancel(ip, pt.tid); |
| 20606 | ||
| 20607 | try sema.setTypeName(block, &wip, name_strategy, "enum", inst); | |
| 20666 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "enum", inst); | |
| 20667 | wip.setName(ip, type_name, name_nav); | |
| 20608 | 20668 | |
| 20609 | 20669 | // Populate field names and values. Duplicate checking will be handled by type resolution. |
| 20610 | 20670 | for (0..fields_len) |field_index| { |
| ... | ... | @@ -27736,6 +27796,22 @@ fn coerceExtra( |
| 27736 | 27796 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); |
| 27737 | 27797 | }, |
| 27738 | 27798 | } |
| 27799 | ||
| 27800 | // Restricted coercions | |
| 27801 | if (maybe_inst_val != null) { | |
| 27802 | if (dest_ty.unrestrictedType(zcu)) |dest_unrestricted_ty| { | |
| 27803 | if (sema.resolveValue(try sema.coerceExtra(block, dest_unrestricted_ty, inst, inst_src, opts))) |inst_val| { | |
| 27804 | return .fromIntern(try ip.getCoerced(gpa, io, pt.tid, inst_val.toIntern(), dest_ty.toIntern())); | |
| 27805 | } | |
| 27806 | } | |
| 27807 | } | |
| 27808 | if (inst_ty.unrestrictedType(zcu)) |inst_unrestricted_ty| { | |
| 27809 | const inst_unrestricted: Air.Inst.Ref = if (maybe_inst_val) |inst_val| | |
| 27810 | .fromIntern(try ip.getCoerced(gpa, io, pt.tid, inst_val.toIntern(), inst_unrestricted_ty.toIntern())) | |
| 27811 | else | |
| 27812 | try sema.unwrapRestrictedPtr(block, inst_unrestricted_ty, inst, inst_src); | |
| 27813 | return sema.coerceExtra(block, dest_ty, inst_unrestricted, inst_src, opts); | |
| 27814 | } | |
| 27739 | 27815 | }, |
| 27740 | 27816 | .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) { |
| 27741 | 27817 | .float, .comptime_float => float: { |
| ... | ... | @@ -28084,6 +28160,7 @@ const InMemoryCoercionResult = union(enum) { |
| 28084 | 28160 | ptr_alignment: AlignPair, |
| 28085 | 28161 | double_ptr_to_anyopaque: Pair, |
| 28086 | 28162 | slice_to_anyopaque: Pair, |
| 28163 | ptr_restricted: Pair, | |
| 28087 | 28164 | |
| 28088 | 28165 | const Pair = struct { |
| 28089 | 28166 | actual: Type, |
| ... | ... | @@ -28415,6 +28492,15 @@ const InMemoryCoercionResult = union(enum) { |
| 28415 | 28492 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); |
| 28416 | 28493 | break; |
| 28417 | 28494 | }, |
| 28495 | .ptr_restricted => |pair| { | |
| 28496 | for ([_]Type{ pair.actual, pair.wanted }) |restricted_ptr_type| { | |
| 28497 | const unrestricted_ptr_type = restricted_ptr_type.unrestrictedType(pt.zcu) orelse continue; | |
| 28498 | try sema.errNote(src, msg, "restricted type '{f}' is not guaranteed to have the same representation as its unrestricted type '{f}'", .{ | |
| 28499 | restricted_ptr_type.fmt(pt), unrestricted_ptr_type.fmt(pt), | |
| 28500 | }); | |
| 28501 | } | |
| 28502 | break; | |
| 28503 | }, | |
| 28418 | 28504 | }; |
| 28419 | 28505 | } |
| 28420 | 28506 | }; |
| ... | ... | @@ -28479,7 +28565,7 @@ pub fn coerceInMemoryAllowed( |
| 28479 | 28565 | (dest_info.signedness == .signed and src_info.signedness == .unsigned and dest_info.bits <= src_info.bits) or |
| 28480 | 28566 | (dest_info.signedness == .unsigned and src_info.signedness == .signed)) |
| 28481 | 28567 | { |
| 28482 | return InMemoryCoercionResult{ .int_not_coercible = .{ | |
| 28568 | return .{ .int_not_coercible = .{ | |
| 28483 | 28569 | .actual_signedness = src_info.signedness, |
| 28484 | 28570 | .wanted_signedness = dest_info.signedness, |
| 28485 | 28571 | .actual_bits = src_info.bits, |
| ... | ... | @@ -28913,7 +28999,7 @@ fn coerceInMemoryAllowedPtrs( |
| 28913 | 28999 | const ok_ptr_size = src_info.flags.size == dest_info.flags.size or |
| 28914 | 29000 | src_info.flags.size == .c or dest_info.flags.size == .c; |
| 28915 | 29001 | if (!ok_ptr_size) { |
| 28916 | return InMemoryCoercionResult{ .ptr_size = .{ | |
| 29002 | return .{ .ptr_size = .{ | |
| 28917 | 29003 | .actual = src_info.flags.size, |
| 28918 | 29004 | .wanted = dest_info.flags.size, |
| 28919 | 29005 | } }; |
| ... | ... | @@ -29049,13 +29135,19 @@ fn coerceInMemoryAllowedPtrs( |
| 29049 | 29135 | break :a dest_child.abiAlignment(zcu); |
| 29050 | 29136 | } else dest_info.flags.alignment; |
| 29051 | 29137 | if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) { |
| 29052 | return InMemoryCoercionResult{ .ptr_alignment = .{ | |
| 29138 | return .{ .ptr_alignment = .{ | |
| 29053 | 29139 | .actual = src_align, |
| 29054 | 29140 | .wanted = dest_align, |
| 29055 | 29141 | } }; |
| 29056 | 29142 | } |
| 29057 | 29143 | } |
| 29058 | 29144 | |
| 29145 | // Restricted pointers have a different in-memory representation depending on the safety mode of the module that created it. | |
| 29146 | if (dest_ty.unrestrictedType(zcu) != null or src_ty.unrestrictedType(zcu) != null) return .{ .ptr_restricted = .{ | |
| 29147 | .actual = src_ty, | |
| 29148 | .wanted = dest_ty, | |
| 29149 | } }; | |
| 29150 | ||
| 29059 | 29151 | return .ok; |
| 29060 | 29152 | } |
| 29061 | 29153 | |
| ... | ... | @@ -29202,10 +29294,15 @@ fn storePtr2( |
| 29202 | 29294 | |
| 29203 | 29295 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 29204 | 29296 | |
| 29297 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| | |
| 29298 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 29299 | else | |
| 29300 | ptr; | |
| 29301 | ||
| 29205 | 29302 | const store_inst = if (is_ret) |
| 29206 | try block.addBinOp(.store, ptr, operand) | |
| 29303 | try block.addBinOp(.store, unrestricted_ptr, operand) | |
| 29207 | 29304 | else |
| 29208 | try block.addBinOp(air_tag, ptr, operand); | |
| 29305 | try block.addBinOp(air_tag, unrestricted_ptr, operand); | |
| 29209 | 29306 | |
| 29210 | 29307 | try sema.checkComptimeKnownStore(block, store_inst, operand_src); |
| 29211 | 29308 | |
| ... | ... | @@ -30282,7 +30379,12 @@ fn analyzeLoad( |
| 30282 | 30379 | break :msg msg; |
| 30283 | 30380 | }); |
| 30284 | 30381 | |
| 30285 | return block.addTyOp(.load, elem_ty, ptr); | |
| 30382 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| | |
| 30383 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 30384 | else | |
| 30385 | ptr; | |
| 30386 | ||
| 30387 | return block.addTyOp(.load, elem_ty, unrestricted_ptr); | |
| 30286 | 30388 | } |
| 30287 | 30389 | |
| 30288 | 30390 | fn analyzeSlicePtr( |
| ... | ... | @@ -31494,6 +31596,19 @@ fn wrapErrorUnionSet( |
| 31494 | 31596 | } |
| 31495 | 31597 | } |
| 31496 | 31598 | |
| 31599 | fn unwrapRestrictedPtr( | |
| 31600 | sema: *Sema, | |
| 31601 | block: *Block, | |
| 31602 | unrestricted_ptr_ty: Type, | |
| 31603 | ptr: Air.Inst.Ref, | |
| 31604 | ptr_src: LazySrcLoc, | |
| 31605 | ) !Air.Inst.Ref { | |
| 31606 | return block.addTyOp(if (block.wantSafety()) tag: { | |
| 31607 | try sema.preparePanicId(ptr_src, .corrupt_restricted_pointer); | |
| 31608 | break :tag .unwrap_restricted_safe; | |
| 31609 | } else .unwrap_restricted, unrestricted_ptr_ty, ptr); | |
| 31610 | } | |
| 31611 | ||
| 31497 | 31612 | /// Returns the enum tag value for the active tag of a tagged union value. |
| 31498 | 31613 | /// |
| 31499 | 31614 | /// Asserts that the type of `un` is a tagged union type. |
| ... | ... | @@ -34211,13 +34326,59 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C |
| 34211 | 34326 | fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Type { |
| 34212 | 34327 | const pt = sema.pt; |
| 34213 | 34328 | return switch (decl) { |
| 34329 | .Signedness, | |
| 34330 | .AddressSpace, | |
| 34331 | .CallingConvention, | |
| 34332 | => unreachable, | |
| 34214 | 34333 | // `noinline fn () void` |
| 34215 | 34334 | .returnError => try pt.funcType(.{ |
| 34216 | 34335 | .param_types = &.{}, |
| 34217 | 34336 | .return_type = .void_type, |
| 34218 | 34337 | .is_noinline = true, |
| 34219 | 34338 | }), |
| 34339 | .StackTrace, | |
| 34340 | .SourceLocation, | |
| 34341 | .CallModifier, | |
| 34342 | .AtomicOrder, | |
| 34343 | .AtomicRmwOp, | |
| 34344 | .ReduceOp, | |
| 34345 | .FloatMode, | |
| 34346 | .PrefetchOptions, | |
| 34347 | .ExportOptions, | |
| 34348 | .ExternOptions, | |
| 34349 | .BranchHint, | |
| 34350 | => unreachable, | |
| 34351 | ||
| 34352 | .Type, | |
| 34353 | .@"Type.Fn", | |
| 34354 | .@"Type.Fn.Param", | |
| 34355 | .@"Type.Fn.Param.Attributes", | |
| 34356 | .@"Type.Fn.Attributes", | |
| 34357 | .@"Type.Int", | |
| 34358 | .@"Type.Float", | |
| 34359 | .@"Type.Pointer", | |
| 34360 | .@"Type.Pointer.Size", | |
| 34361 | .@"Type.Pointer.Attributes", | |
| 34362 | .@"Type.Array", | |
| 34363 | .@"Type.Vector", | |
| 34364 | .@"Type.Optional", | |
| 34365 | .@"Type.Error", | |
| 34366 | .@"Type.ErrorUnion", | |
| 34367 | .@"Type.EnumField", | |
| 34368 | .@"Type.Enum", | |
| 34369 | .@"Type.Enum.Mode", | |
| 34370 | .@"Type.Union", | |
| 34371 | .@"Type.UnionField", | |
| 34372 | .@"Type.UnionField.Attributes", | |
| 34373 | .@"Type.Struct", | |
| 34374 | .@"Type.StructField", | |
| 34375 | .@"Type.StructField.Attributes", | |
| 34376 | .@"Type.ContainerLayout", | |
| 34377 | .@"Type.Opaque", | |
| 34378 | .@"Type.Declaration", | |
| 34379 | => unreachable, | |
| 34220 | 34380 | |
| 34381 | .panic => unreachable, | |
| 34221 | 34382 | // `fn ([]const u8, ?usize) noreturn` |
| 34222 | 34383 | .@"panic.call" => try pt.funcType(.{ |
| 34223 | 34384 | .param_types = &.{ |
| ... | ... | @@ -34226,7 +34387,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34226 | 34387 | }, |
| 34227 | 34388 | .return_type = .noreturn_type, |
| 34228 | 34389 | }), |
| 34229 | ||
| 34230 | 34390 | // `fn (anytype, anytype) noreturn` |
| 34231 | 34391 | .@"panic.sentinelMismatch", |
| 34232 | 34392 | .@"panic.inactiveUnionField", |
| ... | ... | @@ -34234,19 +34394,16 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34234 | 34394 | .param_types = &.{ .generic_poison_type, .generic_poison_type }, |
| 34235 | 34395 | .return_type = .noreturn_type, |
| 34236 | 34396 | }), |
| 34237 | ||
| 34238 | 34397 | // `fn (anyerror) noreturn` |
| 34239 | 34398 | .@"panic.unwrapError" => try pt.funcType(.{ |
| 34240 | 34399 | .param_types = &.{.anyerror_type}, |
| 34241 | 34400 | .return_type = .noreturn_type, |
| 34242 | 34401 | }), |
| 34243 | ||
| 34244 | 34402 | // `fn (usize) noreturn` |
| 34245 | 34403 | .@"panic.sliceCastLenRemainder" => try pt.funcType(.{ |
| 34246 | 34404 | .param_types = &.{.usize_type}, |
| 34247 | 34405 | .return_type = .noreturn_type, |
| 34248 | 34406 | }), |
| 34249 | ||
| 34250 | 34407 | // `fn (usize, usize) noreturn` |
| 34251 | 34408 | .@"panic.outOfBounds", |
| 34252 | 34409 | .@"panic.startGreaterThanEnd", |
| ... | ... | @@ -34254,7 +34411,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34254 | 34411 | .param_types = &.{ .usize_type, .usize_type }, |
| 34255 | 34412 | .return_type = .noreturn_type, |
| 34256 | 34413 | }), |
| 34257 | ||
| 34258 | 34414 | // `fn () noreturn` |
| 34259 | 34415 | .@"panic.reachedUnreachable", |
| 34260 | 34416 | .@"panic.unwrapNull", |
| ... | ... | @@ -34275,23 +34431,28 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34275 | 34431 | .@"panic.copyLenMismatch", |
| 34276 | 34432 | .@"panic.memcpyAlias", |
| 34277 | 34433 | .@"panic.noreturnReturned", |
| 34434 | .@"panic.corruptRestrictedPointer", | |
| 34278 | 34435 | => try pt.funcType(.{ |
| 34279 | 34436 | .param_types = &.{}, |
| 34280 | 34437 | .return_type = .noreturn_type, |
| 34281 | 34438 | }), |
| 34282 | 34439 | |
| 34283 | else => unreachable, | |
| 34440 | .VaList => unreachable, | |
| 34441 | ||
| 34442 | .assembly, | |
| 34443 | .@"assembly.Clobbers", | |
| 34444 | => unreachable, | |
| 34284 | 34445 | }; |
| 34285 | 34446 | } |
| 34286 | 34447 | |
| 34287 | pub fn setTypeName( | |
| 34448 | pub fn computeTypeName( | |
| 34288 | 34449 | sema: *Sema, |
| 34289 | 34450 | block: *Block, |
| 34290 | wip: *const InternPool.WipContainerType, | |
| 34451 | index: InternPool.Index, | |
| 34291 | 34452 | name_strategy: Zir.Inst.NameStrategy, |
| 34292 | 34453 | anon_prefix: []const u8, |
| 34293 | 34454 | inst: Zir.Inst.Index, |
| 34294 | ) CompileError!void { | |
| 34455 | ) CompileError!struct { InternPool.NullTerminatedString, InternPool.Nav.Index.Optional } { | |
| 34295 | 34456 | const pt = sema.pt; |
| 34296 | 34457 | const zcu = pt.zcu; |
| 34297 | 34458 | const comp = zcu.comp; |
| ... | ... | @@ -34308,16 +34469,16 @@ pub fn setTypeName( |
| 34308 | 34469 | // TODO: that would be possible, by detecting line number changes and renaming |
| 34309 | 34470 | // types appropriately. However, `@typeName` becomes a problem then. If we remove |
| 34310 | 34471 | // that builtin from the language, we can consider this. |
| 34311 | wip.setName(ip, try ip.getOrPutStringFmt( | |
| 34472 | return .{ try ip.getOrPutStringFmt( | |
| 34312 | 34473 | gpa, |
| 34313 | 34474 | io, |
| 34314 | 34475 | pt.tid, |
| 34315 | 34476 | "{f}__{s}_{d}", |
| 34316 | .{ block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(wip.index) }, | |
| 34477 | .{ block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(index) }, | |
| 34317 | 34478 | .no_embedded_nulls, |
| 34318 | ), .none); | |
| 34479 | ), .none }; | |
| 34319 | 34480 | }, |
| 34320 | .parent => wip.setName(ip, block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional()), | |
| 34481 | .parent => return .{ block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional() }, | |
| 34321 | 34482 | .func => { |
| 34322 | 34483 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail); |
| 34323 | 34484 | const zir_tags = sema.code.instructions.items(.tag); |
| ... | ... | @@ -34360,8 +34521,7 @@ pub fn setTypeName( |
| 34360 | 34521 | }; |
| 34361 | 34522 | |
| 34362 | 34523 | w.writeByte(')') catch return error.OutOfMemory; |
| 34363 | const name = try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls); | |
| 34364 | wip.setName(ip, name, .none); | |
| 34524 | return .{ try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls), .none }; | |
| 34365 | 34525 | }, |
| 34366 | 34526 | .dbg_var => { |
| 34367 | 34527 | // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions. |
| ... | ... | @@ -34376,10 +34536,9 @@ pub fn setTypeName( |
| 34376 | 34536 | } else { |
| 34377 | 34537 | continue :strat .anon; |
| 34378 | 34538 | }; |
| 34379 | const name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{ | |
| 34539 | return .{ try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{ | |
| 34380 | 34540 | block.type_name_ctx.fmt(ip), var_name, |
| 34381 | }, .no_embedded_nulls); | |
| 34382 | wip.setName(ip, name, .none); | |
| 34541 | }, .no_embedded_nulls), .none }; | |
| 34383 | 34542 | }, |
| 34384 | 34543 | } |
| 34385 | 34544 | } |
| ... | ... | @@ -34420,7 +34579,8 @@ fn zirStructDecl( |
| 34420 | 34579 | .existing => |ty| .fromInterned(ty), |
| 34421 | 34580 | .wip => |wip| ty: { |
| 34422 | 34581 | errdefer wip.cancel(ip, pt.tid); |
| 34423 | try sema.setTypeName(block, &wip, struct_decl.name_strategy, "struct", inst); | |
| 34582 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, struct_decl.name_strategy, "struct", inst); | |
| 34583 | wip.setName(ip, type_name, name_nav); | |
| 34424 | 34584 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34425 | 34585 | .parent = block.namespace.toOptional(), |
| 34426 | 34586 | .owner_type = wip.index, |
| ... | ... | @@ -34493,7 +34653,8 @@ fn zirUnionDecl( |
| 34493 | 34653 | .existing => |ty| .fromInterned(ty), |
| 34494 | 34654 | .wip => |wip| ty: { |
| 34495 | 34655 | errdefer wip.cancel(ip, pt.tid); |
| 34496 | try sema.setTypeName(block, &wip, union_decl.name_strategy, "union", inst); | |
| 34656 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, union_decl.name_strategy, "union", inst); | |
| 34657 | wip.setName(ip, type_name, name_nav); | |
| 34497 | 34658 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34498 | 34659 | .parent = block.namespace.toOptional(), |
| 34499 | 34660 | .owner_type = wip.index, |
| ... | ... | @@ -34545,7 +34706,8 @@ fn zirEnumDecl( |
| 34545 | 34706 | .existing => |ty| .fromInterned(ty), |
| 34546 | 34707 | .wip => |wip| ty: { |
| 34547 | 34708 | errdefer wip.cancel(ip, pt.tid); |
| 34548 | try sema.setTypeName(block, &wip, enum_decl.name_strategy, "enum", inst); | |
| 34709 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, enum_decl.name_strategy, "enum", inst); | |
| 34710 | wip.setName(ip, type_name, name_nav); | |
| 34549 | 34711 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34550 | 34712 | .parent = block.namespace.toOptional(), |
| 34551 | 34713 | .owner_type = wip.index, |
| ... | ... | @@ -34594,7 +34756,8 @@ fn zirOpaqueDecl( |
| 34594 | 34756 | .existing => |ty| .fromInterned(ty), |
| 34595 | 34757 | .wip => |wip| ty: { |
| 34596 | 34758 | errdefer wip.cancel(ip, pt.tid); |
| 34597 | try sema.setTypeName(block, &wip, opaque_decl.name_strategy, "opaque", inst); | |
| 34759 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, opaque_decl.name_strategy, "opaque", inst); | |
| 34760 | wip.setName(ip, type_name, name_nav); | |
| 34598 | 34761 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34599 | 34762 | .parent = block.namespace.toOptional(), |
| 34600 | 34763 | .owner_type = wip.index, |
src/Sema/LowerZon.zig+2-1| ... | ... | @@ -150,7 +150,8 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter |
| 150 | 150 | errdefer wip.cancel(ip, pt.tid); |
| 151 | 151 | const block = self.block; |
| 152 | 152 | const zcu = pt.zcu; |
| 153 | try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?); | |
| 153 | const type_name, const name_nav = try self.sema.computeTypeName(block, wip.index, .anon, "struct", self.base_node_inst.resolve(ip).?); | |
| 154 | wip.setName(ip, type_name, name_nav); | |
| 154 | 155 | |
| 155 | 156 | // Reified structs have field information populated immediately. |
| 156 | 157 | @memcpy(wip.field_values.get(ip), elems); |
src/Sema/bitcast.zig+1| ... | ... | @@ -239,6 +239,7 @@ const UnpackValueBits = struct { |
| 239 | 239 | switch (ip.indexToKey(val.toIntern())) { |
| 240 | 240 | .int_type, |
| 241 | 241 | .ptr_type, |
| 242 | .restricted_ptr_type, | |
| 242 | 243 | .array_type, |
| 243 | 244 | .vector_type, |
| 244 | 245 | .opt_type, |
src/Sema/type_resolution.zig+1| ... | ... | @@ -84,6 +84,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 84 | 84 | switch (ip.indexToKey(ty.toIntern())) { |
| 85 | 85 | .int_type, |
| 86 | 86 | .ptr_type, |
| 87 | .restricted_ptr_type, | |
| 87 | 88 | .anyframe_type, |
| 88 | 89 | .simple_type, |
| 89 | 90 | .opaque_type, |
src/Type.zig+138-70| ... | ... | @@ -165,6 +165,7 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { |
| 165 | 165 | .error_set_type, |
| 166 | 166 | .inferred_error_set_type, |
| 167 | 167 | .ptr_type, |
| 168 | .restricted_ptr_type, | |
| 168 | 169 | .anyframe_type, |
| 169 | 170 | => .runtime, |
| 170 | 171 | |
| ... | ... | @@ -373,13 +374,28 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo { |
| 373 | 374 | } |
| 374 | 375 | |
| 375 | 376 | pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType { |
| 376 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 377 | return ty.ptrInfoOrNull(&zcu.intern_pool, .{}).?; | |
| 378 | } | |
| 379 | ||
| 380 | pub fn ptrInfoOrNull(ty: Type, ip: *const InternPool, comptime opts: struct { | |
| 381 | allow_optional: bool = true, | |
| 382 | allow_restricted: bool = true, | |
| 383 | }) ?InternPool.Key.PtrType { | |
| 384 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 377 | 385 | .ptr_type => |p| p, |
| 378 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 386 | .restricted_ptr_type => |rp| if (opts.allow_restricted) | |
| 387 | ip.indexToKey(rp.unrestricted_ptr_type).ptr_type | |
| 388 | else | |
| 389 | null, | |
| 390 | .opt_type => |child| if (opts.allow_optional) switch (ip.indexToKey(child)) { | |
| 379 | 391 | .ptr_type => |p| p, |
| 380 | else => unreachable, | |
| 381 | }, | |
| 382 | else => unreachable, | |
| 392 | .restricted_ptr_type => |rp| if (opts.allow_restricted) | |
| 393 | ip.indexToKey(rp.unrestricted_ptr_type).ptr_type | |
| 394 | else | |
| 395 | null, | |
| 396 | else => null, // not a pointer type | |
| 397 | } else null, | |
| 398 | else => null, // not a pointer type | |
| 383 | 399 | }; |
| 384 | 400 | } |
| 385 | 401 | |
| ... | ... | @@ -488,6 +504,10 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 488 | 504 | try print(Type.fromInterned(info.child), writer, pt, ctx); |
| 489 | 505 | return; |
| 490 | 506 | }, |
| 507 | .restricted_ptr_type => { | |
| 508 | const name = ip.loadRestrictedType(ty.toIntern()).name; | |
| 509 | try writer.print("{f}", .{name.fmt(ip)}); | |
| 510 | }, | |
| 491 | 511 | .array_type => |array_type| { |
| 492 | 512 | if (array_type.sentinel == .none) { |
| 493 | 513 | try writer.print("[{d}]", .{array_type.len}); |
| ... | ... | @@ -747,6 +767,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { |
| 747 | 767 | .vector_type, |
| 748 | 768 | => true, |
| 749 | 769 | |
| 770 | .restricted_ptr_type, | |
| 750 | 771 | .error_union_type, |
| 751 | 772 | .error_set_type, |
| 752 | 773 | .inferred_error_set_type, |
| ... | ... | @@ -893,22 +914,13 @@ pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool { |
| 893 | 914 | |
| 894 | 915 | /// Never returns `none`. Asserts that all necessary type resolution is already done. |
| 895 | 916 | pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment { |
| 896 | const ip = &zcu.intern_pool; | |
| 897 | const ptr_key: InternPool.Key.PtrType = switch (ip.indexToKey(ptr_ty.toIntern())) { | |
| 898 | .ptr_type => |key| key, | |
| 899 | .opt_type => |child| ip.indexToKey(child).ptr_type, | |
| 900 | else => unreachable, | |
| 901 | }; | |
| 917 | const ptr_key = ptr_ty.ptrInfo(zcu); | |
| 902 | 918 | if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment; |
| 903 | 919 | return Type.fromInterned(ptr_key.child).abiAlignment(zcu); |
| 904 | 920 | } |
| 905 | 921 | |
| 906 | 922 | pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace { |
| 907 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 908 | .ptr_type => |ptr_type| ptr_type.flags.address_space, | |
| 909 | .opt_type => |child| zcu.intern_pool.indexToKey(child).ptr_type.flags.address_space, | |
| 910 | else => unreachable, | |
| 911 | }; | |
| 923 | return ty.ptrInfo(zcu).flags.address_space; | |
| 912 | 924 | } |
| 913 | 925 | |
| 914 | 926 | /// Never returns `.none`. Asserts that the layout of `ty` is resolved. |
| ... | ... | @@ -924,7 +936,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 924 | 936 | if (int_type.bits == 0) return .@"1"; |
| 925 | 937 | return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)); |
| 926 | 938 | }, |
| 927 | .ptr_type, .anyframe_type => ptrAbiAlignment(target), | |
| 939 | .ptr_type, .restricted_ptr_type, .anyframe_type => ptrAbiAlignment(target), | |
| 928 | 940 | .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu), |
| 929 | 941 | .vector_type => |vector_type| { |
| 930 | 942 | if (vector_type.len == 0) return .@"1"; |
| ... | ... | @@ -1078,7 +1090,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1078 | 1090 | .slice => ptrAbiSize(target) * 2, |
| 1079 | 1091 | .one, .many, .c => ptrAbiSize(target), |
| 1080 | 1092 | }, |
| 1081 | .anyframe_type => ptrAbiSize(target), | |
| 1093 | .restricted_ptr_type, .anyframe_type => ptrAbiSize(target), | |
| 1082 | 1094 | .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu), |
| 1083 | 1095 | .vector_type => |vec| { |
| 1084 | 1096 | const elem_ty: Type = .fromInterned(vec.child); |
| ... | ... | @@ -1231,7 +1243,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1231 | 1243 | .slice => target.ptrBitWidth() * 2, |
| 1232 | 1244 | else => target.ptrBitWidth(), |
| 1233 | 1245 | }, |
| 1234 | .anyframe_type => target.ptrBitWidth(), | |
| 1246 | .restricted_ptr_type, .anyframe_type => target.ptrBitWidth(), | |
| 1235 | 1247 | .array_type => |array_type| { |
| 1236 | 1248 | const elem_ty: Type = .fromInterned(array_type.child); |
| 1237 | 1249 | const len = array_type.lenIncludingSentinel(); |
| ... | ... | @@ -1329,13 +1341,31 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1329 | 1341 | }; |
| 1330 | 1342 | } |
| 1331 | 1343 | |
| 1332 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { | |
| 1333 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1334 | .ptr_type => |ptr_info| ptr_info.flags.size == .one, | |
| 1335 | else => false, | |
| 1344 | /// Returns `null` if `ty` is not a restricted pointer. | |
| 1345 | pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type { | |
| 1346 | const ip = &zcu.intern_pool; | |
| 1347 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1348 | .restricted_ptr_type => |restricted_ptr_type| return .fromInterned(restricted_ptr_type.unrestricted_ptr_type), | |
| 1349 | else => null, | |
| 1350 | }; | |
| 1351 | } | |
| 1352 | ||
| 1353 | const RestrictedRepr = enum { double_pointer, single_pointer }; | |
| 1354 | pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr { | |
| 1355 | return restrictedReprByZirIndex(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_ptr_type.zir_index, zcu); | |
| 1356 | } | |
| 1357 | pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr { | |
| 1358 | return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) { | |
| 1359 | .Debug, .ReleaseSafe => .double_pointer, | |
| 1360 | .ReleaseFast, .ReleaseSmall => .single_pointer, | |
| 1336 | 1361 | }; |
| 1337 | 1362 | } |
| 1338 | 1363 | |
| 1364 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { | |
| 1365 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1366 | return ptr_info.flags.size == .one; | |
| 1367 | } | |
| 1368 | ||
| 1339 | 1369 | /// Asserts `ty` is a pointer. |
| 1340 | 1370 | pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { |
| 1341 | 1371 | return ty.ptrSizeOrNull(zcu).?; |
| ... | ... | @@ -1343,24 +1373,27 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { |
| 1343 | 1373 | |
| 1344 | 1374 | /// Returns `null` if `ty` is not a pointer. |
| 1345 | 1375 | pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size { |
| 1346 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1347 | .ptr_type => |ptr_info| ptr_info.flags.size, | |
| 1348 | else => null, | |
| 1349 | }; | |
| 1376 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return null; | |
| 1377 | return ptr_info.flags.size; | |
| 1350 | 1378 | } |
| 1351 | 1379 | |
| 1352 | 1380 | pub fn isSlice(ty: Type, zcu: *const Zcu) bool { |
| 1353 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1354 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, | |
| 1355 | else => false, | |
| 1356 | }; | |
| 1381 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1382 | return ptr_info.flags.size == .slice; | |
| 1357 | 1383 | } |
| 1358 | 1384 | |
| 1359 | 1385 | pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1360 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1386 | const ip = &zcu.intern_pool; | |
| 1387 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1361 | 1388 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, |
| 1362 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1389 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1390 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1391 | }, | |
| 1392 | .opt_type => |child| opt_child: switch (zcu.intern_pool.indexToKey(child)) { | |
| 1363 | 1393 | .ptr_type => |ptr_type| !ptr_type.flags.is_allowzero and ptr_type.flags.size == .slice, |
| 1394 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1395 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1396 | }, | |
| 1364 | 1397 | else => false, |
| 1365 | 1398 | }, |
| 1366 | 1399 | else => false, |
| ... | ... | @@ -1372,10 +1405,8 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type { |
| 1372 | 1405 | } |
| 1373 | 1406 | |
| 1374 | 1407 | pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool { |
| 1375 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1376 | .ptr_type => |ptr_type| ptr_type.flags.is_const, | |
| 1377 | else => false, | |
| 1378 | }; | |
| 1408 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1409 | return ptr_info.flags.is_const; | |
| 1379 | 1410 | } |
| 1380 | 1411 | |
| 1381 | 1412 | pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| ... | ... | @@ -1383,38 +1414,45 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| 1383 | 1414 | } |
| 1384 | 1415 | |
| 1385 | 1416 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| 1386 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1387 | .ptr_type => |ptr_type| ptr_type.flags.is_volatile, | |
| 1388 | else => false, | |
| 1389 | }; | |
| 1417 | const ptr_info = ty.ptrInfoOrNull(ip, .{ .allow_optional = false }) orelse return false; | |
| 1418 | return ptr_info.flags.is_volatile; | |
| 1390 | 1419 | } |
| 1391 | 1420 | |
| 1392 | 1421 | pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool { |
| 1393 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1422 | const ip = &zcu.intern_pool; | |
| 1423 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1394 | 1424 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, |
| 1425 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1426 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1427 | }, | |
| 1395 | 1428 | .opt_type => true, |
| 1396 | 1429 | else => false, |
| 1397 | 1430 | }; |
| 1398 | 1431 | } |
| 1399 | 1432 | |
| 1400 | 1433 | pub fn isCPtr(ty: Type, zcu: *const Zcu) bool { |
| 1401 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1402 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | |
| 1403 | else => false, | |
| 1404 | }; | |
| 1434 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1435 | return ptr_info.flags.size == .c; | |
| 1405 | 1436 | } |
| 1406 | 1437 | |
| 1407 | 1438 | pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1408 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1439 | const ip = &zcu.intern_pool; | |
| 1440 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1409 | 1441 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1410 | 1442 | .slice => false, |
| 1411 | 1443 | .one, .many, .c => true, |
| 1412 | 1444 | }, |
| 1413 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1445 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1446 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1447 | }, | |
| 1448 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { | |
| 1414 | 1449 | .ptr_type => |p| switch (p.flags.size) { |
| 1415 | 1450 | .slice, .c => false, |
| 1416 | 1451 | .many, .one => !p.flags.is_allowzero, |
| 1417 | 1452 | }, |
| 1453 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1454 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1455 | }, | |
| 1418 | 1456 | else => false, |
| 1419 | 1457 | }, |
| 1420 | 1458 | else => false, |
| ... | ... | @@ -1429,13 +1467,20 @@ pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool { |
| 1429 | 1467 | |
| 1430 | 1468 | /// See also `isPtrLikeOptional`. |
| 1431 | 1469 | pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { |
| 1432 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1433 | .opt_type => |child_type| child_type == .anyerror_type or switch (zcu.intern_pool.indexToKey(child_type)) { | |
| 1470 | const ip = &zcu.intern_pool; | |
| 1471 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1472 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | |
| 1473 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1474 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1475 | }, | |
| 1476 | .opt_type => |child_type| child_type == .anyerror_type or opt_child: switch (ip.indexToKey(child_type)) { | |
| 1434 | 1477 | .ptr_type => |ptr_type| ptr_type.flags.size != .c and !ptr_type.flags.is_allowzero, |
| 1478 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1479 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1480 | }, | |
| 1435 | 1481 | .error_set_type, .inferred_error_set_type => true, |
| 1436 | 1482 | else => false, |
| 1437 | 1483 | }, |
| 1438 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | |
| 1439 | 1484 | else => false, |
| 1440 | 1485 | }; |
| 1441 | 1486 | } |
| ... | ... | @@ -1443,13 +1488,20 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { |
| 1443 | 1488 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 1444 | 1489 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 1445 | 1490 | pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool { |
| 1446 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1491 | const ip = &zcu.intern_pool; | |
| 1492 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1447 | 1493 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, |
| 1448 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1494 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1495 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1496 | }, | |
| 1497 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { | |
| 1449 | 1498 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1450 | 1499 | .slice, .c => false, |
| 1451 | 1500 | .many, .one => !ptr_type.flags.is_allowzero, |
| 1452 | 1501 | }, |
| 1502 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1503 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1504 | }, | |
| 1453 | 1505 | else => false, |
| 1454 | 1506 | }, |
| 1455 | 1507 | else => false, |
| ... | ... | @@ -1486,7 +1538,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1486 | 1538 | .pointer => return ty.childType(zcu), |
| 1487 | 1539 | .optional => { |
| 1488 | 1540 | const ptr_ty = ty.childType(zcu); |
| 1489 | const ptr_info = zcu.intern_pool.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 1541 | const ptr_info = ptr_ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }).?; | |
| 1490 | 1542 | assert(ptr_info.flags.size != .c); |
| 1491 | 1543 | assert(!ptr_info.flags.is_allowzero); |
| 1492 | 1544 | return .fromInterned(ptr_info.child); |
| ... | ... | @@ -1508,7 +1560,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1508 | 1560 | /// * `[*c]T` |
| 1509 | 1561 | pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1510 | 1562 | const ip = &zcu.intern_pool; |
| 1511 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1563 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1512 | 1564 | inline .array_type, .vector_type => |arr| .fromInterned(arr.child), |
| 1513 | 1565 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1514 | 1566 | .many, .slice, .c => .fromInterned(ptr_type.child), |
| ... | ... | @@ -1517,6 +1569,9 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1517 | 1569 | else => unreachable, |
| 1518 | 1570 | }, |
| 1519 | 1571 | }, |
| 1572 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1573 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1574 | }, | |
| 1520 | 1575 | else => unreachable, |
| 1521 | 1576 | }; |
| 1522 | 1577 | } |
| ... | ... | @@ -1532,12 +1587,16 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type { |
| 1532 | 1587 | /// Asserts that the type is an optional, or a C pointer. |
| 1533 | 1588 | /// For C pointers this returns the type unmodified. |
| 1534 | 1589 | pub fn optionalChild(ty: Type, zcu: *const Zcu) Type { |
| 1535 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1590 | const ip = &zcu.intern_pool; | |
| 1591 | ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1536 | 1592 | .opt_type => |child| return .fromInterned(child), |
| 1537 | 1593 | .ptr_type => |ptr_type| { |
| 1538 | 1594 | assert(ptr_type.flags.size == .c); |
| 1539 | 1595 | return ty; |
| 1540 | 1596 | }, |
| 1597 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1598 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1599 | }, | |
| 1541 | 1600 | else => unreachable, |
| 1542 | 1601 | } |
| 1543 | 1602 | } |
| ... | ... | @@ -1755,7 +1814,8 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 { |
| 1755 | 1814 | |
| 1756 | 1815 | /// Asserts the type is an array, pointer or vector. |
| 1757 | 1816 | pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1758 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1817 | const ip = &zcu.intern_pool; | |
| 1818 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1759 | 1819 | .vector_type, |
| 1760 | 1820 | .struct_type, |
| 1761 | 1821 | .tuple_type, |
| ... | ... | @@ -1763,6 +1823,9 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1763 | 1823 | |
| 1764 | 1824 | .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1765 | 1825 | .ptr_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1826 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1827 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1828 | }, | |
| 1766 | 1829 | |
| 1767 | 1830 | else => unreachable, |
| 1768 | 1831 | }; |
| ... | ... | @@ -1851,6 +1914,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1851 | 1914 | .tuple_type => unreachable, |
| 1852 | 1915 | |
| 1853 | 1916 | .ptr_type => unreachable, |
| 1917 | .restricted_ptr_type => unreachable, | |
| 1854 | 1918 | .anyframe_type => unreachable, |
| 1855 | 1919 | .array_type => unreachable, |
| 1856 | 1920 | |
| ... | ... | @@ -2021,6 +2085,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2021 | 2085 | assertHasLayout(ty, zcu); |
| 2022 | 2086 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2023 | 2087 | .ptr_type, |
| 2088 | .restricted_ptr_type, // number of possible values is not known until the end of compilation, so never treated as NPV/OPV | |
| 2024 | 2089 | .error_union_type, |
| 2025 | 2090 | .func_type, |
| 2026 | 2091 | .anyframe_type, |
| ... | ... | @@ -2829,7 +2894,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) |
| 2829 | 2894 | pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2830 | 2895 | const zcu = pt.zcu; |
| 2831 | 2896 | const ip = &zcu.intern_pool; |
| 2832 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 2897 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; | |
| 2833 | 2898 | const elem_ty: Type = switch (ptr_info.flags.size) { |
| 2834 | 2899 | .slice, .many, .c => .fromInterned(ptr_info.child), |
| 2835 | 2900 | .one => switch (ip.indexToKey(ptr_info.child)) { |
| ... | ... | @@ -2883,7 +2948,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error |
| 2883 | 2948 | pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2884 | 2949 | const zcu = pt.zcu; |
| 2885 | 2950 | const ip = &zcu.intern_pool; |
| 2886 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 2951 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; | |
| 2887 | 2952 | assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c); |
| 2888 | 2953 | const aggregate_ty: Type = .fromInterned(ptr_info.child); |
| 2889 | 2954 | aggregate_ty.assertHasLayout(zcu); |
| ... | ... | @@ -3011,7 +3076,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3011 | 3076 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { |
| 3012 | 3077 | .tuple_type, .union_type => field_ty.abiAlignment(zcu), |
| 3013 | 3078 | .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu), |
| 3014 | .ptr_type => Type.usize.abiAlignment(zcu), | |
| 3079 | .ptr_type, .restricted_ptr_type => ptrAbiAlignment(zcu.getTarget()), | |
| 3015 | 3080 | else => unreachable, |
| 3016 | 3081 | }, |
| 3017 | 3082 | else => |a| a, |
| ... | ... | @@ -3040,6 +3105,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3040 | 3105 | |
| 3041 | 3106 | pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString { |
| 3042 | 3107 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3108 | .restricted_ptr_type => ip.loadRestrictedType(ty.toIntern()).name, | |
| 3043 | 3109 | .struct_type => ip.loadStructType(ty.toIntern()).name, |
| 3044 | 3110 | .union_type => ip.loadUnionType(ty.toIntern()).name, |
| 3045 | 3111 | .enum_type => ip.loadEnumType(ty.toIntern()).name, |
| ... | ... | @@ -3247,6 +3313,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3247 | 3313 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 3248 | 3314 | .int_type, |
| 3249 | 3315 | .ptr_type, |
| 3316 | .restricted_ptr_type, | |
| 3250 | 3317 | .anyframe_type, |
| 3251 | 3318 | .simple_type, |
| 3252 | 3319 | .opaque_type, |
| ... | ... | @@ -3315,34 +3382,34 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3315 | 3382 | } |
| 3316 | 3383 | |
| 3317 | 3384 | switch (ip.indexToKey(ty.toIntern())) { |
| 3318 | .ptr_type => try collectSubtypes(Type.fromInterned(ty.ptrInfo(zcu).child), pt, visited), | |
| 3319 | .array_type => |array_type| try collectSubtypes(Type.fromInterned(array_type.child), pt, visited), | |
| 3320 | .vector_type => |vector_type| try collectSubtypes(Type.fromInterned(vector_type.child), pt, visited), | |
| 3321 | .opt_type => |child| try collectSubtypes(Type.fromInterned(child), pt, visited), | |
| 3385 | .ptr_type => |ptr_type| try collectSubtypes(.fromInterned(ptr_type.child), pt, visited), | |
| 3386 | .array_type => |array_type| try collectSubtypes(.fromInterned(array_type.child), pt, visited), | |
| 3387 | .vector_type => |vector_type| try collectSubtypes(.fromInterned(vector_type.child), pt, visited), | |
| 3388 | .opt_type => |child| try collectSubtypes(.fromInterned(child), pt, visited), | |
| 3322 | 3389 | .error_union_type => |error_union_type| { |
| 3323 | try collectSubtypes(Type.fromInterned(error_union_type.error_set_type), pt, visited); | |
| 3390 | try collectSubtypes(.fromInterned(error_union_type.error_set_type), pt, visited); | |
| 3324 | 3391 | if (error_union_type.payload_type != .generic_poison_type) { |
| 3325 | try collectSubtypes(Type.fromInterned(error_union_type.payload_type), pt, visited); | |
| 3392 | try collectSubtypes(.fromInterned(error_union_type.payload_type), pt, visited); | |
| 3326 | 3393 | } |
| 3327 | 3394 | }, |
| 3328 | 3395 | .tuple_type => |tuple| { |
| 3329 | 3396 | for (tuple.types.get(ip)) |field_ty| { |
| 3330 | try collectSubtypes(Type.fromInterned(field_ty), pt, visited); | |
| 3397 | try collectSubtypes(.fromInterned(field_ty), pt, visited); | |
| 3331 | 3398 | } |
| 3332 | 3399 | }, |
| 3333 | 3400 | .func_type => |fn_info| { |
| 3334 | 3401 | const param_types = fn_info.param_types.get(&zcu.intern_pool); |
| 3335 | 3402 | for (param_types) |param_ty| { |
| 3336 | 3403 | if (param_ty != .generic_poison_type) { |
| 3337 | try collectSubtypes(Type.fromInterned(param_ty), pt, visited); | |
| 3404 | try collectSubtypes(.fromInterned(param_ty), pt, visited); | |
| 3338 | 3405 | } |
| 3339 | 3406 | } |
| 3340 | 3407 | |
| 3341 | 3408 | if (fn_info.return_type != .generic_poison_type) { |
| 3342 | try collectSubtypes(Type.fromInterned(fn_info.return_type), pt, visited); | |
| 3409 | try collectSubtypes(.fromInterned(fn_info.return_type), pt, visited); | |
| 3343 | 3410 | } |
| 3344 | 3411 | }, |
| 3345 | .anyframe_type => |child| try collectSubtypes(Type.fromInterned(child), pt, visited), | |
| 3412 | .anyframe_type => |child| try collectSubtypes(.fromInterned(child), pt, visited), | |
| 3346 | 3413 | |
| 3347 | 3414 | // leaf types |
| 3348 | 3415 | .undef, |
| ... | ... | @@ -3354,6 +3421,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3354 | 3421 | .enum_type, |
| 3355 | 3422 | .simple_type, |
| 3356 | 3423 | .int_type, |
| 3424 | .restricted_ptr_type, | |
| 3357 | 3425 | => {}, |
| 3358 | 3426 | |
| 3359 | 3427 | // values, not types |
src/Zcu.zig+5-1| ... | ... | @@ -501,6 +501,7 @@ pub const BuiltinDecl = enum { |
| 501 | 501 | @"panic.copyLenMismatch", |
| 502 | 502 | @"panic.memcpyAlias", |
| 503 | 503 | @"panic.noreturnReturned", |
| 504 | @"panic.corruptRestrictedPointer", | |
| 504 | 505 | |
| 505 | 506 | VaList, |
| 506 | 507 | |
| ... | ... | @@ -588,6 +589,7 @@ pub const BuiltinDecl = enum { |
| 588 | 589 | .@"panic.copyLenMismatch", |
| 589 | 590 | .@"panic.memcpyAlias", |
| 590 | 591 | .@"panic.noreturnReturned", |
| 592 | .@"panic.corruptRestrictedPointer", | |
| 591 | 593 | => .func, |
| 592 | 594 | }; |
| 593 | 595 | } |
| ... | ... | @@ -661,6 +663,7 @@ pub const SimplePanicId = enum { |
| 661 | 663 | copy_len_mismatch, |
| 662 | 664 | memcpy_alias, |
| 663 | 665 | noreturn_returned, |
| 666 | corrupt_restricted_pointer, | |
| 664 | 667 | |
| 665 | 668 | pub fn toBuiltin(id: SimplePanicId) BuiltinDecl { |
| 666 | 669 | return switch (id) { |
| ... | ... | @@ -684,6 +687,7 @@ pub const SimplePanicId = enum { |
| 684 | 687 | .copy_len_mismatch => .@"panic.copyLenMismatch", |
| 685 | 688 | .memcpy_alias => .@"panic.memcpyAlias", |
| 686 | 689 | .noreturn_returned => .@"panic.noreturnReturned", |
| 690 | .corrupt_restricted_pointer => .@"panic.corruptRestrictedPointer", | |
| 687 | 691 | // zig fmt: on |
| 688 | 692 | }; |
| 689 | 693 | } |
| ... | ... | @@ -4215,7 +4219,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag |
| 4215 | 4219 | |
| 4216 | 4220 | // Queue any decls within this type which would be automatically analyzed. |
| 4217 | 4221 | // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`. |
| 4218 | const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap().?; | |
| 4222 | const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap() orelse continue; | |
| 4219 | 4223 | for (zcu.namespacePtr(ns).comptime_decls.items) |cu| { |
| 4220 | 4224 | // `comptime` decls are always analyzed. |
| 4221 | 4225 | const unit: AnalUnit = .wrap(.{ .@"comptime" = cu }); |
src/codegen.zig+4| ... | ... | @@ -281,6 +281,9 @@ pub fn generateLazySymbol( |
| 281 | 281 | w.writeAll(tag_name) catch unreachable; |
| 282 | 282 | w.writeByte(0) catch unreachable; |
| 283 | 283 | } |
| 284 | } else if (Type.fromInterned(lazy_sym.ty).unrestrictedType(zcu)) |unrestricted_ptr_ty| { | |
| 285 | alignment.* = unrestricted_ptr_ty.abiAlignment(zcu); | |
| 286 | try w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)); // to be filled in later | |
| 284 | 287 | } else { |
| 285 | 288 | return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{ |
| 286 | 289 | @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), |
| ... | ... | @@ -325,6 +328,7 @@ pub fn generateSymbol( |
| 325 | 328 | switch (ip.indexToKey(val.toIntern())) { |
| 326 | 329 | .int_type, |
| 327 | 330 | .ptr_type, |
| 331 | .restricted_ptr_type, | |
| 328 | 332 | .array_type, |
| 329 | 333 | .vector_type, |
| 330 | 334 | .opt_type, |
src/codegen/aarch64/Select.zig+45| ... | ... | @@ -658,6 +658,28 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 658 | 658 | air_inst_index = air_body[air_body_index]; |
| 659 | 659 | continue :air_tag air_tags[@intFromEnum(air_inst_index)]; |
| 660 | 660 | }, |
| 661 | .unwrap_restricted, .unwrap_restricted_safe => { | |
| 662 | const ty_op = air_data[@intFromEnum(air_inst_index)].ty_op; | |
| 663 | ||
| 664 | maybe_noop: { | |
| 665 | switch (isel.air.typeOf(ty_op.operand, ip).restrictedRepr(zcu)) { | |
| 666 | .double_pointer => break :maybe_noop, | |
| 667 | .single_pointer => {}, | |
| 668 | } | |
| 669 | if (true) break :maybe_noop; | |
| 670 | if (ty_op.operand.toIndex()) |src_air_inst_index| { | |
| 671 | if (isel.hints.get(src_air_inst_index)) |hint_vpsi| { | |
| 672 | try isel.hints.putNoClobber(gpa, air_inst_index, hint_vpsi); | |
| 673 | } | |
| 674 | } | |
| 675 | } | |
| 676 | try isel.analyzeUse(ty_op.operand); | |
| 677 | try isel.def_order.putNoClobber(gpa, air_inst_index, {}); | |
| 678 | ||
| 679 | air_body_index += 1; | |
| 680 | air_inst_index = air_body[air_body_index]; | |
| 681 | continue :air_tag air_tags[@intFromEnum(air_inst_index)]; | |
| 682 | }, | |
| 661 | 683 | .struct_field_ptr, .struct_field_val => { |
| 662 | 684 | const ty_pl = air_data[@intFromEnum(air_inst_index)].ty_pl; |
| 663 | 685 | const extra = isel.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | ... | @@ -5737,6 +5759,29 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 5737 | 5759 | } |
| 5738 | 5760 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5739 | 5761 | }, |
| 5762 | .unwrap_restricted, .unwrap_restricted_safe => |air_tag| { | |
| 5763 | if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| { | |
| 5764 | defer dst_vi.value.deref(isel); | |
| 5765 | const ty_op = air.data(air.inst_index).ty_op; | |
| 5766 | const unrestricted_ty = ty_op.ty.toType(); | |
| 5767 | const restricted_ty = isel.air.typeOf(ty_op.operand, ip); | |
| 5768 | switch (restricted_ty.restrictedRepr(zcu)) { | |
| 5769 | .double_pointer => { | |
| 5770 | switch (air_tag) { | |
| 5771 | else => unreachable, | |
| 5772 | .unwrap_restricted => {}, | |
| 5773 | .unwrap_restricted_safe => {}, // TODO | |
| 5774 | } | |
| 5775 | const ptr_vi = try isel.use(ty_op.operand); | |
| 5776 | const ptr_mat = try ptr_vi.matReg(isel); | |
| 5777 | _ = try dst_vi.value.load(isel, unrestricted_ty, ptr_mat.ra, .{}); | |
| 5778 | try ptr_mat.finish(isel); | |
| 5779 | }, | |
| 5780 | .single_pointer => try dst_vi.value.move(isel, ty_op.operand), | |
| 5781 | } | |
| 5782 | } | |
| 5783 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | |
| 5784 | }, | |
| 5740 | 5785 | .struct_field_ptr => { |
| 5741 | 5786 | if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: { |
| 5742 | 5787 | defer dst_vi.value.deref(isel); |
src/codegen/c.zig+36-1| ... | ... | @@ -896,6 +896,7 @@ pub const DeclGen = struct { |
| 896 | 896 | // types, not values |
| 897 | 897 | .int_type, |
| 898 | 898 | .ptr_type, |
| 899 | .restricted_ptr_type, | |
| 899 | 900 | .array_type, |
| 900 | 901 | .vector_type, |
| 901 | 902 | .opt_type, |
| ... | ... | @@ -1334,7 +1335,7 @@ pub const DeclGen = struct { |
| 1334 | 1335 | return w.writeByte(')'); |
| 1335 | 1336 | }, |
| 1336 | 1337 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), |
| 1337 | else => switch (ip.indexToKey(ty.toIntern())) { | |
| 1338 | else => ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1338 | 1339 | .simple_type, // anyerror, c_char (etc), usize, isize |
| 1339 | 1340 | .int_type, |
| 1340 | 1341 | .enum_type, |
| ... | ... | @@ -1405,6 +1406,9 @@ pub const DeclGen = struct { |
| 1405 | 1406 | try w.writeByte('}'); |
| 1406 | 1407 | }, |
| 1407 | 1408 | }, |
| 1409 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1410 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1411 | }, | |
| 1408 | 1412 | .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) { |
| 1409 | 1413 | .npv_payload => unreachable, // opv optional |
| 1410 | 1414 | |
| ... | ... | @@ -2840,6 +2844,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2840 | 2844 | .set_err_return_trace => try airSetErrReturnTrace(f, inst), |
| 2841 | 2845 | .save_err_return_trace_index => try airSaveErrReturnTraceIndex(f, inst), |
| 2842 | 2846 | |
| 2847 | .unwrap_restricted => try airUnwrapRestricted(f, inst, false), | |
| 2848 | .unwrap_restricted_safe => try airUnwrapRestricted(f, inst, true), | |
| 2849 | ||
| 2843 | 2850 | .wasm_memory_size => try airWasmMemorySize(f, inst), |
| 2844 | 2851 | .wasm_memory_grow => try airWasmMemoryGrow(f, inst), |
| 2845 | 2852 | |
| ... | ... | @@ -5533,6 +5540,34 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5533 | 5540 | return local; |
| 5534 | 5541 | } |
| 5535 | 5542 | |
| 5543 | fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | |
| 5544 | const pt = f.dg.pt; | |
| 5545 | const zcu = pt.zcu; | |
| 5546 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | |
| 5547 | ||
| 5548 | const unrestricted_ty = ty_op.ty.toType(); | |
| 5549 | const restricted_ty = f.typeOf(ty_op.operand); | |
| 5550 | const operand = try f.resolveInst(ty_op.operand); | |
| 5551 | try reap(f, inst, &.{ty_op.operand}); | |
| 5552 | ||
| 5553 | const w = &f.code.writer; | |
| 5554 | const local = try f.allocLocal(inst, unrestricted_ty); | |
| 5555 | ||
| 5556 | try f.writeCValue(w, local, .other); | |
| 5557 | try w.writeAll(" = "); | |
| 5558 | switch (restricted_ty.restrictedRepr(zcu)) { | |
| 5559 | .double_pointer => { | |
| 5560 | _ = safety; // TODO | |
| 5561 | try f.writeCValueDeref(w, operand); | |
| 5562 | }, | |
| 5563 | .single_pointer => try f.writeCValue(w, operand, .other), | |
| 5564 | } | |
| 5565 | try w.writeByte(';'); | |
| 5566 | try f.newline(); | |
| 5567 | ||
| 5568 | return local; | |
| 5569 | } | |
| 5570 | ||
| 5536 | 5571 | fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5537 | 5572 | const pt = f.dg.pt; |
| 5538 | 5573 | const w = &f.code.writer; |
src/codegen/c/type.zig+19-1| ... | ... | @@ -284,6 +284,20 @@ pub const CType = union(enum) { |
| 284 | 284 | |
| 285 | 285 | .pointer => { |
| 286 | 286 | const ptr = cur_ty.ptrInfo(zcu); |
| 287 | if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) { | |
| 288 | .double_pointer => { | |
| 289 | const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu); | |
| 290 | const unrestricted_cty_buf = try arena.create(CType); | |
| 291 | unrestricted_cty_buf.* = unrestricted_cty; | |
| 292 | return .{ .pointer = .{ | |
| 293 | .@"const" = true, | |
| 294 | .@"volatile" = false, | |
| 295 | .elem_ty = unrestricted_cty_buf, | |
| 296 | .nonstring = false, | |
| 297 | } }; | |
| 298 | }, | |
| 299 | .single_pointer => {}, | |
| 300 | }; | |
| 287 | 301 | switch (ptr.flags.size) { |
| 288 | 302 | .slice => { |
| 289 | 303 | try deps.addType(gpa, cur_ty, allow_incomplete); |
| ... | ... | @@ -912,7 +926,10 @@ pub const CType = union(enum) { |
| 912 | 926 | .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}), |
| 913 | 927 | .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}), |
| 914 | 928 | |
| 915 | .pointer => switch (ty.ptrSize(zcu)) { | |
| 929 | .pointer => if (ty.unrestrictedType(zcu)) |_| { | |
| 930 | const name = ty.containerTypeName(ip).toSlice(ip); | |
| 931 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); | |
| 932 | } else switch (ty.ptrSize(zcu)) { | |
| 916 | 933 | .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 917 | 934 | .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 918 | 935 | }, |
| ... | ... | @@ -985,6 +1002,7 @@ pub const CType = union(enum) { |
| 985 | 1002 | return switch (ip.indexToKey(ty.toIntern())) { |
| 986 | 1003 | .int_type, |
| 987 | 1004 | .ptr_type, |
| 1005 | .restricted_ptr_type, | |
| 988 | 1006 | .anyframe_type, |
| 989 | 1007 | .simple_type, |
| 990 | 1008 | .opaque_type, |
src/codegen/llvm.zig+2| ... | ... | @@ -3061,6 +3061,7 @@ pub const Object = struct { |
| 3061 | 3061 | }), |
| 3062 | 3062 | }; |
| 3063 | 3063 | }, |
| 3064 | .restricted_ptr_type => @panic("TODO implement restricted pointers"), | |
| 3064 | 3065 | .array_type => |array_type| o.builder.arrayType( |
| 3065 | 3066 | array_type.lenIncludingSentinel(), |
| 3066 | 3067 | try o.lowerType(.fromInterned(array_type.child)), |
| ... | ... | @@ -3443,6 +3444,7 @@ pub const Object = struct { |
| 3443 | 3444 | return switch (val_key) { |
| 3444 | 3445 | .int_type, |
| 3445 | 3446 | .ptr_type, |
| 3447 | .restricted_ptr_type, | |
| 3446 | 3448 | .array_type, |
| 3447 | 3449 | .vector_type, |
| 3448 | 3450 | .opt_type, |
src/codegen/llvm/FuncGen.zig+19| ... | ... | @@ -413,6 +413,9 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air |
| 413 | 413 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(body[i..]), |
| 414 | 414 | .wrap_errunion_err => try self.airWrapErrUnionErr(body[i..]), |
| 415 | 415 | |
| 416 | .unwrap_restricted => try self.airUnwrapRestricted(inst, false), | |
| 417 | .unwrap_restricted_safe => try self.airUnwrapRestricted(inst, true), | |
| 418 | ||
| 416 | 419 | .wasm_memory_size => try self.airWasmMemorySize(inst), |
| 417 | 420 | .wasm_memory_grow => try self.airWasmMemoryGrow(inst), |
| 418 | 421 | |
| ... | ... | @@ -3250,6 +3253,22 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocat |
| 3250 | 3253 | return result_ptr; |
| 3251 | 3254 | } |
| 3252 | 3255 | |
| 3256 | fn airUnwrapRestricted(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { | |
| 3257 | const o = self.object; | |
| 3258 | const zcu = o.zcu; | |
| 3259 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | |
| 3260 | const unrestricted_ty = ty_op.ty.toType(); | |
| 3261 | const restricted_ty = self.typeOf(ty_op.operand); | |
| 3262 | const operand = try self.resolveInst(ty_op.operand); | |
| 3263 | switch (restricted_ty.restrictedRepr(zcu)) { | |
| 3264 | .double_pointer => { | |
| 3265 | _ = safety; // TODO | |
| 3266 | return self.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "restricted.unwrap"); | |
| 3267 | }, | |
| 3268 | .single_pointer => return operand, | |
| 3269 | } | |
| 3270 | } | |
| 3271 | ||
| 3253 | 3272 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3254 | 3273 | const o = self.object; |
| 3255 | 3274 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
src/codegen/riscv64/CodeGen.zig+4| ... | ... | @@ -1614,6 +1614,10 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1614 | 1614 | .wrap_errunion_payload => try func.airWrapErrUnionPayload(inst), |
| 1615 | 1615 | .wrap_errunion_err => try func.airWrapErrUnionErr(inst), |
| 1616 | 1616 | |
| 1617 | .unwrap_restricted, | |
| 1618 | .unwrap_restricted_safe, | |
| 1619 | => return func.fail("TODO implement restricted pointers", .{}), | |
| 1620 | ||
| 1617 | 1621 | .runtime_nav_ptr => try func.airRuntimeNavPtr(inst), |
| 1618 | 1622 | |
| 1619 | 1623 | .add_optimized, |
src/codegen/sparc64/CodeGen.zig+4| ... | ... | @@ -676,6 +676,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 676 | 676 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 677 | 677 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 678 | 678 | |
| 679 | .unwrap_restricted, | |
| 680 | .unwrap_restricted_safe, | |
| 681 | => return self.fail("TODO implement restricted pointers", .{}), | |
| 682 | ||
| 679 | 683 | .add_optimized, |
| 680 | 684 | .sub_optimized, |
| 681 | 685 | .mul_optimized, |
src/codegen/spirv/CodeGen.zig+4-1| ... | ... | @@ -774,6 +774,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { |
| 774 | 774 | switch (ip.indexToKey(val.toIntern())) { |
| 775 | 775 | .int_type, |
| 776 | 776 | .ptr_type, |
| 777 | .restricted_ptr_type, | |
| 777 | 778 | .array_type, |
| 778 | 779 | .vector_type, |
| 779 | 780 | .opt_type, |
| ... | ... | @@ -2774,7 +2775,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void { |
| 2774 | 2775 | .unwrap_errunion_err => try cg.airErrUnionErr(inst), |
| 2775 | 2776 | .unwrap_errunion_payload => try cg.airErrUnionPayload(inst), |
| 2776 | 2777 | .wrap_errunion_err => try cg.airWrapErrUnionErr(inst), |
| 2777 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), | |
| 2778 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), | |
| 2779 | ||
| 2780 | .unwrap_restricted => return cg.fail("TODO implement restricted pointers", .{}), | |
| 2778 | 2781 | |
| 2779 | 2782 | .is_null => try cg.airIsNull(inst, false, .is_null), |
| 2780 | 2783 | .is_non_null => try cg.airIsNull(inst, false, .is_non_null), |
src/codegen/wasm/CodeGen.zig+20| ... | ... | @@ -1815,6 +1815,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1815 | 1815 | .errunion_payload_ptr_set => cg.airErrUnionPayloadPtrSet(inst), |
| 1816 | 1816 | .error_name => cg.airErrorName(inst), |
| 1817 | 1817 | |
| 1818 | .unwrap_restricted => cg.airUnwrapRestricted(inst, false), | |
| 1819 | .unwrap_restricted_safe => cg.airUnwrapRestricted(inst, true), | |
| 1820 | ||
| 1818 | 1821 | .wasm_memory_size => cg.airWasmMemorySize(inst), |
| 1819 | 1822 | .wasm_memory_grow => cg.airWasmMemoryGrow(inst), |
| 1820 | 1823 | |
| ... | ... | @@ -4676,6 +4679,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 4676 | 4679 | switch (ip.indexToKey(val.ip_index)) { |
| 4677 | 4680 | .int_type, |
| 4678 | 4681 | .ptr_type, |
| 4682 | .restricted_ptr_type, | |
| 4679 | 4683 | .array_type, |
| 4680 | 4684 | .vector_type, |
| 4681 | 4685 | .opt_type, |
| ... | ... | @@ -6719,6 +6723,22 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 6719 | 6723 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 6720 | 6724 | } |
| 6721 | 6725 | |
| 6726 | fn airUnwrapRestricted(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { | |
| 6727 | const zcu = cg.pt.zcu; | |
| 6728 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | |
| 6729 | const operand = try cg.resolveInst(ty_op.operand); | |
| 6730 | const unrestricted_ty = ty_op.ty.toType(); | |
| 6731 | const restricted_ty = cg.typeOf(ty_op.operand); | |
| 6732 | const result = result: switch (restricted_ty.restrictedRepr(zcu)) { | |
| 6733 | .double_pointer => { | |
| 6734 | _ = safety; // TODO | |
| 6735 | break :result try cg.load(operand, unrestricted_ty, 0); | |
| 6736 | }, | |
| 6737 | .single_pointer => cg.reuseOperand(ty_op.operand, operand), | |
| 6738 | }; | |
| 6739 | return cg.finishAir(inst, result, &.{ty_op.operand}); | |
| 6740 | } | |
| 6741 | ||
| 6722 | 6742 | fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6723 | 6743 | const pt = cg.pt; |
| 6724 | 6744 | const zcu = pt.zcu; |
src/codegen/x86_64/CodeGen.zig+153-13| ... | ... | @@ -103829,6 +103829,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103829 | 103829 | try eu.write(&ops[0], .{ .disp = eu_err_off }, cg); |
| 103830 | 103830 | try eu.finish(inst, &.{ty_op.operand}, &ops, cg); |
| 103831 | 103831 | }, |
| 103832 | .unwrap_restricted, .unwrap_restricted_safe => |air_tag| { | |
| 103833 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | |
| 103834 | const unrestricted_ty = ty_op.ty.toType(); | |
| 103835 | const restricted_ty = cg.typeOf(ty_op.operand); | |
| 103836 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | |
| 103837 | const res = res: switch (restricted_ty.restrictedRepr(zcu)) { | |
| 103838 | .double_pointer => { | |
| 103839 | switch (air_tag) { | |
| 103840 | else => unreachable, | |
| 103841 | .unwrap_restricted => {}, | |
| 103842 | .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{ | |
| 103843 | .required_features = .{ .avx, null, null, null }, | |
| 103844 | .patterns = &.{ | |
| 103845 | .{ .src = .{ .mem, .none, .none } }, | |
| 103846 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103847 | }, | |
| 103848 | .call_frame = .{ .alignment = .@"32" }, | |
| 103849 | .extra_temps = .{ | |
| 103850 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103851 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | |
| 103852 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103853 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 103854 | .unused, | |
| 103855 | .unused, | |
| 103856 | .unused, | |
| 103857 | .unused, | |
| 103858 | .unused, | |
| 103859 | .unused, | |
| 103860 | .unused, | |
| 103861 | }, | |
| 103862 | .clobbers = .{ .eflags = true }, | |
| 103863 | .each = .{ .once = &.{ | |
| 103864 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103865 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103866 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103867 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 103868 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103869 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103870 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 103871 | } }, | |
| 103872 | }, .{ | |
| 103873 | .required_features = .{ .sse, null, null, null }, | |
| 103874 | .patterns = &.{ | |
| 103875 | .{ .src = .{ .mem, .none, .none } }, | |
| 103876 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103877 | }, | |
| 103878 | .call_frame = .{ .alignment = .@"16" }, | |
| 103879 | .extra_temps = .{ | |
| 103880 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103881 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | |
| 103882 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103883 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 103884 | .unused, | |
| 103885 | .unused, | |
| 103886 | .unused, | |
| 103887 | .unused, | |
| 103888 | .unused, | |
| 103889 | .unused, | |
| 103890 | .unused, | |
| 103891 | }, | |
| 103892 | .clobbers = .{ .eflags = true }, | |
| 103893 | .each = .{ .once = &.{ | |
| 103894 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103895 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103896 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103897 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 103898 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103899 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103900 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 103901 | } }, | |
| 103902 | }, .{ | |
| 103903 | .patterns = &.{ | |
| 103904 | .{ .src = .{ .mem, .none, .none } }, | |
| 103905 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103906 | }, | |
| 103907 | .call_frame = .{ .alignment = .@"8" }, | |
| 103908 | .extra_temps = .{ | |
| 103909 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103910 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | |
| 103911 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103912 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 103913 | .unused, | |
| 103914 | .unused, | |
| 103915 | .unused, | |
| 103916 | .unused, | |
| 103917 | .unused, | |
| 103918 | .unused, | |
| 103919 | .unused, | |
| 103920 | }, | |
| 103921 | .clobbers = .{ .eflags = true }, | |
| 103922 | .each = .{ .once = &.{ | |
| 103923 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103924 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103925 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103926 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 103927 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103928 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103929 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 103930 | } }, | |
| 103931 | } }) catch |err| switch (err) { | |
| 103932 | error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{ | |
| 103933 | @tagName(air_tag), | |
| 103934 | unrestricted_ty.fmt(pt), | |
| 103935 | restricted_ty.fmt(pt), | |
| 103936 | ops[0].tracking(cg), | |
| 103937 | }), | |
| 103938 | else => |e| return e, | |
| 103939 | }, | |
| 103940 | } | |
| 103941 | break :res try ops[0].load(unrestricted_ty, .{}, cg); | |
| 103942 | }, | |
| 103943 | .single_pointer => ops[0], | |
| 103944 | }; | |
| 103945 | try res.finish(inst, &.{ty_op.operand}, &ops, cg); | |
| 103946 | }, | |
| 103832 | 103947 | .struct_field_ptr => { |
| 103833 | 103948 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 103834 | 103949 | const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | ... | @@ -176216,20 +176331,22 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 176216 | 176331 | // Due to incremental compilation, how function calls are generated depends |
| 176217 | 176332 | // on linking. |
| 176218 | 176333 | switch (info) { |
| 176219 | .air => |callee| if (callee.toInterned()) |func_ip_index| { | |
| 176220 | const func_key = ip.indexToKey(func_ip_index); | |
| 176221 | switch (switch (func_key) { | |
| 176222 | else => func_key, | |
| 176223 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | |
| 176224 | .nav => |nav| ip.indexToKey(zcu.navValue(nav).toIntern()), | |
| 176225 | else => func_key, | |
| 176226 | } else func_key, | |
| 176334 | .air => |callee| if (callee.toInterned()) |func_ip_index| try self.asmImmediate( | |
| 176335 | .{ ._, .call }, | |
| 176336 | switch (switch (ip.indexToKey(func_ip_index)) { | |
| 176337 | else => |func_key| func_key, | |
| 176338 | .ptr => |ptr| switch (ptr.byte_offset) { | |
| 176339 | 0 => switch (ptr.base_addr) { | |
| 176340 | .nav => |nav| ip.indexToKey(zcu.navValue(nav).toIntern()), | |
| 176341 | else => unreachable, | |
| 176342 | }, | |
| 176343 | else => unreachable, | |
| 176344 | }, | |
| 176227 | 176345 | }) { |
| 176228 | 176346 | else => unreachable, |
| 176229 | .func => |func| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = func.owner_nav } }), | |
| 176230 | .@"extern" => |@"extern"| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = @"extern".owner_nav } }), | |
| 176231 | } | |
| 176232 | } else { | |
| 176347 | inline .func, .@"extern" => |func| .{ .nav = .{ .index = func.owner_nav } }, | |
| 176348 | }, | |
| 176349 | ) else { | |
| 176233 | 176350 | assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer); |
| 176234 | 176351 | const scratch_reg = abi.getCAbiLinkerScratchReg(fn_info.cc); |
| 176235 | 176352 | try self.genSetReg(scratch_reg, .usize, .{ .air_ref = callee }, .{}); |
| ... | ... | @@ -188525,6 +188642,7 @@ const Select = struct { |
| 188525 | 188642 | splat_float_mem: struct { ref: Select.Operand.Ref, inside: enum { zero } = .zero, outside: f16 }, |
| 188526 | 188643 | frame: FrameIndex, |
| 188527 | 188644 | lazy_sym: struct { kind: link.File.LazySymbol.Kind, ref: Select.Operand.Ref = .none }, |
| 188645 | panic_func: Zcu.SimplePanicId, | |
| 188528 | 188646 | extern_func: [*:0]const u8, |
| 188529 | 188647 | |
| 188530 | 188648 | const ConstSpec = struct { |
| ... | ... | @@ -188986,7 +189104,25 @@ const Select = struct { |
| 188986 | 189104 | }, |
| 188987 | 189105 | } }), true }; |
| 188988 | 189106 | }, |
| 188989 | .extern_func => |extern_func_spec| .{ try cg.tempInit(spec.type, .{ .lea_extern_func = try cg.addString(std.mem.span(extern_func_spec)) }), true }, | |
| 189107 | .panic_func => |panic_id| .{ try cg.tempInit( | |
| 189108 | spec.type, | |
| 189109 | switch (switch (pt.zcu.intern_pool.indexToKey(pt.zcu.builtin_decl_values.get(panic_id.toBuiltin()))) { | |
| 189110 | else => |func_key| func_key, | |
| 189111 | .ptr => |ptr| switch (ptr.byte_offset) { | |
| 189112 | 0 => switch (ptr.base_addr) { | |
| 189113 | .nav => |nav| pt.zcu.intern_pool.indexToKey(pt.zcu.navValue(nav).toIntern()), | |
| 189114 | else => unreachable, | |
| 189115 | }, | |
| 189116 | else => unreachable, | |
| 189117 | }, | |
| 189118 | }) { | |
| 189119 | else => unreachable, | |
| 189120 | inline .func, .@"extern" => |func| .{ .lea_nav = func.owner_nav }, | |
| 189121 | }, | |
| 189122 | ), true }, | |
| 189123 | .extern_func => |extern_func_spec| .{ try cg.tempInit(spec.type, .{ | |
| 189124 | .lea_extern_func = try cg.addString(std.mem.span(extern_func_spec)), | |
| 189125 | }), true }, | |
| 188990 | 189126 | }; |
| 188991 | 189127 | } |
| 188992 | 189128 | |
| ... | ... | @@ -189036,6 +189172,7 @@ const Select = struct { |
| 189036 | 189172 | lhs: enum(u6) { |
| 189037 | 189173 | none, |
| 189038 | 189174 | ptr_size, |
| 189175 | log2_ptr_size, | |
| 189039 | 189176 | ptr_bit_size, |
| 189040 | 189177 | size, |
| 189041 | 189178 | src0_size, |
| ... | ... | @@ -189072,7 +189209,9 @@ const Select = struct { |
| 189072 | 189209 | rhs: Memory.Scale, |
| 189073 | 189210 | |
| 189074 | 189211 | const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" }; |
| 189212 | const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; | |
| 189075 | 189213 | const sub_ptr_size: Adjust = .{ .sign = .neg, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; |
| 189214 | const add_log2_ptr_size: Adjust = .{ .sign = .pos, .lhs = .log2_ptr_size, .op = .mul, .rhs = .@"1" }; | |
| 189076 | 189215 | const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" }; |
| 189077 | 189216 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 189078 | 189217 | const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" }; |
| ... | ... | @@ -190013,6 +190152,7 @@ const Select = struct { |
| 190013 | 190152 | const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) { |
| 190014 | 190153 | .none => 0, |
| 190015 | 190154 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), |
| 190155 | .log2_ptr_size => std.math.log2(@divExact(s.cg.target.ptrBitWidth(), 8)), | |
| 190016 | 190156 | .ptr_bit_size => s.cg.target.ptrBitWidth(), |
| 190017 | 190157 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 190018 | 190158 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), |
src/link/Dwarf.zig+9-1| ... | ... | @@ -3060,6 +3060,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3060 | 3060 | } = switch (ip.indexToKey(nav_val.toIntern())) { |
| 3061 | 3061 | .int_type, |
| 3062 | 3062 | .ptr_type, |
| 3063 | .restricted_ptr_type, | |
| 3063 | 3064 | .array_type, |
| 3064 | 3065 | .vector_type, |
| 3065 | 3066 | .opt_type, |
| ... | ... | @@ -3566,7 +3567,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3566 | 3567 | |
| 3567 | 3568 | const diw = &wip_nav.debug_info.writer; |
| 3568 | 3569 | var big_int_space: Value.BigIntSpace = undefined; |
| 3569 | switch (value_ip_key) { | |
| 3570 | key: switch (value_ip_key) { | |
| 3570 | 3571 | .func => unreachable, // handled above |
| 3571 | 3572 | .@"extern" => unreachable, // handled above |
| 3572 | 3573 | |
| ... | ... | @@ -3629,6 +3630,13 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3629 | 3630 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 3630 | 3631 | }, |
| 3631 | 3632 | }, |
| 3633 | .restricted_ptr_type => |restricted_ptr_type| switch (Type.restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu)) { | |
| 3634 | .double_pointer => continue :key .{ .ptr_type = .{ | |
| 3635 | .child = restricted_ptr_type.unrestricted_ptr_type, | |
| 3636 | .flags = .{ .is_const = true }, | |
| 3637 | } }, | |
| 3638 | .single_pointer => continue :key .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type }, | |
| 3639 | }, | |
| 3632 | 3640 | .array_type => |array_type| { |
| 3633 | 3641 | const array_child_type: Type = .fromInterned(array_type.child); |
| 3634 | 3642 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); |
src/print_value.zig+1| ... | ... | @@ -49,6 +49,7 @@ pub fn print( |
| 49 | 49 | switch (ip.indexToKey(val.toIntern())) { |
| 50 | 50 | .int_type, |
| 51 | 51 | .ptr_type, |
| 52 | .restricted_ptr_type, | |
| 52 | 53 | .array_type, |
| 53 | 54 | .vector_type, |
| 54 | 55 | .opt_type, |
src/print_zir.zig+8| ... | ... | @@ -622,6 +622,14 @@ const Writer = struct { |
| 622 | 622 | try stream.writeAll(")) "); |
| 623 | 623 | try self.writeSrcNode(stream, extra.node); |
| 624 | 624 | }, |
| 625 | .reify_restricted => { | |
| 626 | const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; | |
| 627 | const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | |
| 628 | try stream.print("{t}, ", .{name_strat}); | |
| 629 | try self.writeInstRef(stream, extra.operand); | |
| 630 | try stream.writeAll(")) "); | |
| 631 | try self.writeSrcNode(stream, extra.node); | |
| 632 | }, | |
| 625 | 633 | .reify_fn => { |
| 626 | 634 | const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data; |
| 627 | 635 | try self.writeInstRef(stream, extra.param_types); |