| author | |
| committer | |
| log | 24bf4387088cb2bee7329642c169a09dc48a7af0 |
| tree | b2920cbb21431c92d6784a517655ea882158d455 |
| parent | da85c089b8911189a9b42505cc44821bc87b5b23 |
29 files changed, 1272 insertions(+), 812 deletions(-)
doc/langref.html.in+2-2| ... | ... | @@ -5771,9 +5771,9 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 5771 | 5771 | |
| 5772 | 5772 | {#header_open|@Restricted#} |
| 5773 | 5773 | <pre>{#syntax#}@Restricted( |
| 5774 | comptime Pointer: type, | |
| 5774 | comptime Underlying: type, | |
| 5775 | 5775 | ) type{#endsyntax#}</pre> |
| 5776 | <p>Returns a restricted pointer type based on the specified pointer type.</p> | |
| 5776 | <p>Returns a restricted type based on the specified underlying type.</p> | |
| 5777 | 5777 | {#header_close#} |
| 5778 | 5778 | |
| 5779 | 5779 | {#header_open|@Fn#} |
lib/std/debug.zig+2-2| ... | ... | @@ -201,9 +201,9 @@ 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 { | |
| 204 | pub fn corruptRestrictedValue() noreturn { | |
| 205 | 205 | @branchHint(.cold); |
| 206 | call("corrupt restricted pointer value", @returnAddress()); | |
| 206 | call("corrupt restricted value", @returnAddress()); | |
| 207 | 207 | } |
| 208 | 208 | }; |
| 209 | 209 | } |
lib/std/debug/no_panic.zig+1-1| ... | ... | @@ -135,7 +135,7 @@ pub fn noreturnReturned() noreturn { |
| 135 | 135 | @trap(); |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | pub fn corruptRestrictedPointer() noreturn { | |
| 138 | pub fn corruptRestrictedValue() noreturn { | |
| 139 | 139 | @branchHint(.cold); |
| 140 | 140 | @trap(); |
| 141 | 141 | } |
lib/std/debug/simple_panic.zig+2-2| ... | ... | @@ -127,6 +127,6 @@ pub fn noreturnReturned() noreturn { |
| 127 | 127 | call("'noreturn' function returned", null); |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | pub fn corruptRestrictedPointer() noreturn { | |
| 131 | call("corrupt restricted pointer value", null); | |
| 130 | pub fn corruptRestrictedValue() noreturn { | |
| 131 | call("corrupt restricted value", null); | |
| 132 | 132 | } |
lib/std/zig/AstGen.zig+9-9| ... | ... | @@ -9320,15 +9320,6 @@ 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 | }, | |
| 9332 | 9323 | .Fn => { |
| 9333 | 9324 | const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes); |
| 9334 | 9325 | const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types); |
| ... | ... | @@ -9349,6 +9340,15 @@ fn builtinCall( |
| 9349 | 9340 | }); |
| 9350 | 9341 | return rvalue(gz, ri, result, node); |
| 9351 | 9342 | }, |
| 9343 | .Restricted => { | |
| 9344 | const unrestricted_ty = try typeExpr(gz, scope, params[0]); | |
| 9345 | const result = try gz.addExtendedPayloadSmall( | |
| 9346 | .reify_restricted, | |
| 9347 | @intFromEnum(reify_name_strat), | |
| 9348 | Zir.Inst.ReifyRestricted{ .node = node, .unrestricted_ty = unrestricted_ty }, | |
| 9349 | ); | |
| 9350 | return rvalue(gz, ri, result, node); | |
| 9351 | }, | |
| 9352 | 9352 | .Struct => { |
| 9353 | 9353 | const container_layout_ty = try gz.addBuiltinValue(node, .container_layout); |
| 9354 | 9354 | const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .struct_layout); |
lib/std/zig/Zir.zig+11-4| ... | ... | @@ -2062,13 +2062,13 @@ 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, | |
| 2069 | 2065 | /// Implements builtin `@Fn`. |
| 2070 | 2066 | /// `operand` is payload index to `ReifyFn`. |
| 2071 | 2067 | reify_fn, |
| 2068 | /// Implements builtin `@Restricted`. | |
| 2069 | /// `operand` is payload index to `ReifyRestricted`. | |
| 2070 | /// `small` contains `NameStrategy`. | |
| 2071 | reify_restricted, | |
| 2072 | 2072 | /// Implements builtin `@Struct`. |
| 2073 | 2073 | /// `operand` is payload index to `ReifyStruct`. |
| 2074 | 2074 | /// `small` contains `NameStrategy`. |
| ... | ... | @@ -3266,6 +3266,13 @@ pub const Inst = struct { |
| 3266 | 3266 | fn_attrs: Ref, |
| 3267 | 3267 | }; |
| 3268 | 3268 | |
| 3269 | pub const ReifyRestricted = struct { | |
| 3270 | /// This node is absolute, because `reify` instructions are tracked across updates, and | |
| 3271 | /// this simplifies the logic for getting source locations for types. | |
| 3272 | node: Ast.Node.Index, | |
| 3273 | unrestricted_ty: Ref, | |
| 3274 | }; | |
| 3275 | ||
| 3269 | 3276 | pub const ReifyStruct = struct { |
| 3270 | 3277 | src_line: u32, |
| 3271 | 3278 | /// This node is absolute, because `reify` instructions are tracked across updates, and |
src/Compilation/Config.zig+1-1| ... | ... | @@ -501,7 +501,7 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 501 | 501 | }; |
| 502 | 502 | }; |
| 503 | 503 | |
| 504 | const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace); | |
| 504 | const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, options.incremental, .error_return_trace); | |
| 505 | 505 | |
| 506 | 506 | const root_error_tracing = b: { |
| 507 | 507 | if (options.root_error_tracing) |x| break :b x; |
src/InternPool.zig+191-109| ... | ... | @@ -1969,7 +1969,6 @@ 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, | |
| 1973 | 1972 | array_type: ArrayType, |
| 1974 | 1973 | vector_type: VectorType, |
| 1975 | 1974 | opt_type: Index, |
| ... | ... | @@ -1978,6 +1977,7 @@ pub const Key = union(enum) { |
| 1978 | 1977 | anyframe_type: Index, |
| 1979 | 1978 | error_union_type: ErrorUnionType, |
| 1980 | 1979 | simple_type: SimpleType, |
| 1980 | restricted_type: RestrictedType, | |
| 1981 | 1981 | /// This represents a struct that has been explicitly declared in source code, |
| 1982 | 1982 | /// or was created with `@Struct`. It is unique and based on a declaration. |
| 1983 | 1983 | struct_type: ContainerType, |
| ... | ... | @@ -2021,6 +2021,8 @@ pub const Key = union(enum) { |
| 2021 | 2021 | un: Union, |
| 2022 | 2022 | /// An instance of a `packed struct` or `packed union`. |
| 2023 | 2023 | bitpack: Bitpack, |
| 2024 | /// An instance of a restricted type. | |
| 2025 | restricted_value: RestrictedValue, | |
| 2024 | 2026 | |
| 2025 | 2027 | /// A comptime function call with a memoized result. |
| 2026 | 2028 | memoized_call: Key.MemoizedCall, |
| ... | ... | @@ -2095,14 +2097,6 @@ pub const Key = union(enum) { |
| 2095 | 2097 | pub const AddressSpace = std.builtin.AddressSpace; |
| 2096 | 2098 | }; |
| 2097 | 2099 | |
| 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 | ||
| 2106 | 2100 | /// Extern so that hashing can be done via memory reinterpreting. |
| 2107 | 2101 | pub const ArrayType = extern struct { |
| 2108 | 2102 | len: u64, |
| ... | ... | @@ -2206,6 +2200,13 @@ pub const Key = union(enum) { |
| 2206 | 2200 | } |
| 2207 | 2201 | }; |
| 2208 | 2202 | |
| 2203 | pub const RestrictedType = extern struct { | |
| 2204 | /// A `reify_restricted` instruction. | |
| 2205 | zir_index: TrackedInst.Index, | |
| 2206 | /// The underlying unrestricted type. | |
| 2207 | unrestricted_type: Index, | |
| 2208 | }; | |
| 2209 | ||
| 2209 | 2210 | pub const Extern = struct { |
| 2210 | 2211 | /// The name of the extern symbol. |
| 2211 | 2212 | name: NullTerminatedString, |
| ... | ... | @@ -2581,6 +2582,12 @@ pub const Key = union(enum) { |
| 2581 | 2582 | backing_int_val: Index, |
| 2582 | 2583 | }; |
| 2583 | 2584 | |
| 2585 | pub const RestrictedValue = extern struct { | |
| 2586 | /// The restricted type. | |
| 2587 | ty: Index, | |
| 2588 | unrestricted_value: Index, | |
| 2589 | }; | |
| 2590 | ||
| 2584 | 2591 | pub const MemoizedCall = struct { |
| 2585 | 2592 | func: Index, |
| 2586 | 2593 | arg_values: []const Index, |
| ... | ... | @@ -2599,13 +2606,13 @@ pub const Key = union(enum) { |
| 2599 | 2606 | return switch (key) { |
| 2600 | 2607 | // TODO: assert no padding in these types |
| 2601 | 2608 | inline .ptr_type, |
| 2602 | .restricted_ptr_type, | |
| 2603 | 2609 | .array_type, |
| 2604 | 2610 | .vector_type, |
| 2605 | 2611 | .opt_type, |
| 2606 | 2612 | .anyframe_type, |
| 2607 | 2613 | .error_union_type, |
| 2608 | 2614 | .simple_type, |
| 2615 | .restricted_type, | |
| 2609 | 2616 | .simple_value, |
| 2610 | 2617 | .opt, |
| 2611 | 2618 | .undef, |
| ... | ... | @@ -2614,6 +2621,7 @@ pub const Key = union(enum) { |
| 2614 | 2621 | .enum_tag, |
| 2615 | 2622 | .inferred_error_set_type, |
| 2616 | 2623 | .un, |
| 2624 | .restricted_value, | |
| 2617 | 2625 | => |x| Hash.hash(seed, asBytes(&x)), |
| 2618 | 2626 | |
| 2619 | 2627 | .int_type => |x| Hash.hash(seed | @shlExact(@as(u64, @intFromEnum(x.signedness)), 63), asBytes(&x.bits)), |
| ... | ... | @@ -2893,6 +2901,10 @@ pub const Key = union(enum) { |
| 2893 | 2901 | const b_info = b.bitpack; |
| 2894 | 2902 | return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val; |
| 2895 | 2903 | }, |
| 2904 | .restricted_value => |a_info| { | |
| 2905 | const b_info = b.restricted_value; | |
| 2906 | return a_info.ty == b_info.ty and a_info.unrestricted_value == b_info.unrestricted_value; | |
| 2907 | }, | |
| 2896 | 2908 | |
| 2897 | 2909 | .@"extern" => |a_info| { |
| 2898 | 2910 | const b_info = b.@"extern"; |
| ... | ... | @@ -3027,7 +3039,7 @@ pub const Key = union(enum) { |
| 3027 | 3039 | } |
| 3028 | 3040 | }, |
| 3029 | 3041 | |
| 3030 | .restricted_ptr_type => |a_r| return std.meta.eql(a_r, b.restricted_ptr_type), | |
| 3042 | .restricted_type => |a_r| return std.meta.eql(a_r, b.restricted_type), | |
| 3031 | 3043 | |
| 3032 | 3044 | inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| { |
| 3033 | 3045 | const b_info = @field(b, @tagName(a_tag_ct)); |
| ... | ... | @@ -3130,7 +3142,6 @@ pub const Key = union(enum) { |
| 3130 | 3142 | return switch (key) { |
| 3131 | 3143 | .int_type, |
| 3132 | 3144 | .ptr_type, |
| 3133 | .restricted_ptr_type, | |
| 3134 | 3145 | .array_type, |
| 3135 | 3146 | .vector_type, |
| 3136 | 3147 | .opt_type, |
| ... | ... | @@ -3139,6 +3150,7 @@ pub const Key = union(enum) { |
| 3139 | 3150 | .error_set_type, |
| 3140 | 3151 | .inferred_error_set_type, |
| 3141 | 3152 | .simple_type, |
| 3153 | .restricted_type, | |
| 3142 | 3154 | .struct_type, |
| 3143 | 3155 | .union_type, |
| 3144 | 3156 | .opaque_type, |
| ... | ... | @@ -3160,6 +3172,7 @@ pub const Key = union(enum) { |
| 3160 | 3172 | .aggregate, |
| 3161 | 3173 | .un, |
| 3162 | 3174 | .bitpack, |
| 3175 | .restricted_value, | |
| 3163 | 3176 | => |x| x.ty, |
| 3164 | 3177 | |
| 3165 | 3178 | .enum_literal => .enum_literal_type, |
| ... | ... | @@ -4187,7 +4200,6 @@ pub const Index = enum(u32) { |
| 4187 | 4200 | type_array_small: struct { data: *Vector }, |
| 4188 | 4201 | type_vector: struct { data: *Vector }, |
| 4189 | 4202 | type_pointer: struct { data: *Tag.TypePointer }, |
| 4190 | type_restricted: struct { data: *Tag.TypeRestricted }, | |
| 4191 | 4203 | type_slice: DataIsIndex, |
| 4192 | 4204 | type_optional: DataIsIndex, |
| 4193 | 4205 | type_anyframe: DataIsIndex, |
| ... | ... | @@ -4222,6 +4234,7 @@ pub const Index = enum(u32) { |
| 4222 | 4234 | }, |
| 4223 | 4235 | }, |
| 4224 | 4236 | |
| 4237 | type_restricted: struct { data: *Tag.TypeRestricted }, | |
| 4225 | 4238 | type_struct: struct { data: *Tag.TypeStruct }, |
| 4226 | 4239 | type_struct_packed_auto: struct { data: *Tag.TypeStructPacked }, |
| 4227 | 4240 | type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked }, |
| ... | ... | @@ -4302,6 +4315,7 @@ pub const Index = enum(u32) { |
| 4302 | 4315 | }, |
| 4303 | 4316 | repeated: struct { data: *Repeated }, |
| 4304 | 4317 | bitpack: struct { data: *Key.Bitpack }, |
| 4318 | restricted_value: struct { data: *Key.RestrictedValue }, | |
| 4305 | 4319 | |
| 4306 | 4320 | memoized_call: struct { |
| 4307 | 4321 | const @"data.args_len" = opaque {}; |
| ... | ... | @@ -4786,9 +4800,6 @@ pub const Tag = enum(u8) { |
| 4786 | 4800 | /// A slice type. |
| 4787 | 4801 | /// data is Index of underlying pointer type. |
| 4788 | 4802 | type_slice, |
| 4789 | /// A restricted pointer type. | |
| 4790 | /// data is payload to `TypeRestricted`. | |
| 4791 | type_restricted, | |
| 4792 | 4803 | /// An optional type. |
| 4793 | 4804 | /// data is the child type. |
| 4794 | 4805 | type_optional, |
| ... | ... | @@ -4815,6 +4826,9 @@ pub const Tag = enum(u8) { |
| 4815 | 4826 | /// data is extra index of `TypeTuple`. |
| 4816 | 4827 | type_tuple, |
| 4817 | 4828 | |
| 4829 | /// A restricted pointer type. | |
| 4830 | /// data is payload to `TypeRestricted`. | |
| 4831 | type_restricted, | |
| 4818 | 4832 | /// A non-packed struct type. |
| 4819 | 4833 | /// data is extra index of `TypeStruct`. |
| 4820 | 4834 | type_struct, |
| ... | ... | @@ -5037,6 +5051,9 @@ pub const Tag = enum(u8) { |
| 5037 | 5051 | /// An instance of a `packed struct` or `packed union`. |
| 5038 | 5052 | /// data is extra index to `Key.Bitpack`. |
| 5039 | 5053 | bitpack, |
| 5054 | /// An instance of a restricted type. | |
| 5055 | /// data is extra index to `Key.RestrictedValue`. | |
| 5056 | restricted_value, | |
| 5040 | 5057 | |
| 5041 | 5058 | /// A memoized comptime function call result. |
| 5042 | 5059 | /// data is extra index to `MemoizedCall` |
| ... | ... | @@ -5127,7 +5144,6 @@ pub const Tag = enum(u8) { |
| 5127 | 5144 | .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector }, |
| 5128 | 5145 | .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector }, |
| 5129 | 5146 | .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer }, |
| 5130 | .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted }, | |
| 5131 | 5147 | .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index }, |
| 5132 | 5148 | .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index }, |
| 5133 | 5149 | .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index }, |
| ... | ... | @@ -5171,6 +5187,7 @@ pub const Tag = enum(u8) { |
| 5171 | 5187 | }, |
| 5172 | 5188 | }, |
| 5173 | 5189 | |
| 5190 | .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted }, | |
| 5174 | 5191 | .type_struct = .{ |
| 5175 | 5192 | .summary = .@"{.payload.name%summary#\"}", |
| 5176 | 5193 | .payload = TypeStruct, |
| ... | ... | @@ -5363,6 +5380,7 @@ pub const Tag = enum(u8) { |
| 5363 | 5380 | }, |
| 5364 | 5381 | .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated }, |
| 5365 | 5382 | .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack }, |
| 5383 | .restricted_value = .{ .summary = .@"@as({.payload.unrestricted_value%summary}, {})", .payload = Key.RestrictedValue }, | |
| 5366 | 5384 | |
| 5367 | 5385 | .memoized_call = .{ |
| 5368 | 5386 | .summary = .@"@memoize({.payload.func%summary})", |
| ... | ... | @@ -5390,8 +5408,8 @@ pub const Tag = enum(u8) { |
| 5390 | 5408 | /// The name of this restricted type. |
| 5391 | 5409 | name: NullTerminatedString, |
| 5392 | 5410 | |
| 5393 | /// The pointer type this restricted type is based on. | |
| 5394 | unrestricted_ptr_type: Index, | |
| 5411 | /// The underlying unrestricted type. | |
| 5412 | unrestricted_type: Index, | |
| 5395 | 5413 | }; |
| 5396 | 5414 | |
| 5397 | 5415 | pub const Extern = struct { |
| ... | ... | @@ -6486,14 +6504,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6486 | 6504 | return .{ .ptr_type = ptr_info }; |
| 6487 | 6505 | }, |
| 6488 | 6506 | |
| 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 | ||
| 6497 | 6507 | .type_optional => .{ .opt_type = @enumFromInt(data) }, |
| 6498 | 6508 | .type_anyframe => .{ .anyframe_type = @enumFromInt(data) }, |
| 6499 | 6509 | |
| ... | ... | @@ -6509,6 +6519,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6509 | 6519 | .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, |
| 6510 | 6520 | .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, |
| 6511 | 6521 | |
| 6522 | .type_restricted => { | |
| 6523 | const restricted_info = extraData(unwrapped_index.getExtra(ip), Tag.TypeRestricted, data); | |
| 6524 | return .{ .restricted_type = .{ | |
| 6525 | .zir_index = restricted_info.zir_index, | |
| 6526 | .unrestricted_type = restricted_info.unrestricted_type, | |
| 6527 | } }; | |
| 6528 | }, | |
| 6512 | 6529 | .type_struct => .{ .struct_type = ns: { |
| 6513 | 6530 | const extra_list = unwrapped_index.getExtra(ip); |
| 6514 | 6531 | const extra = extraDataTrail(extra_list, Tag.TypeStruct, data); |
| ... | ... | @@ -6903,6 +6920,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6903 | 6920 | .enum_literal => .{ .enum_literal = @enumFromInt(data) }, |
| 6904 | 6921 | .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) }, |
| 6905 | 6922 | .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) }, |
| 6923 | .restricted_value => .{ .restricted_value = extraData(unwrapped_index.getExtra(ip), Key.RestrictedValue, data) }, | |
| 6906 | 6924 | |
| 6907 | 6925 | .memoized_call => { |
| 6908 | 6926 | const extra_list = unwrapped_index.getExtra(ip); |
| ... | ... | @@ -7276,7 +7294,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7276 | 7294 | .data = try addExtra(extra, ptr_type_adjusted), |
| 7277 | 7295 | }); |
| 7278 | 7296 | }, |
| 7279 | .restricted_ptr_type => unreachable, // instead getReifiedRestrictedType | |
| 7280 | 7297 | .array_type => |array_type| { |
| 7281 | 7298 | assert(array_type.child != .none); |
| 7282 | 7299 | assert(array_type.sentinel == .none or ip.typeOf(array_type.sentinel) == array_type.child); |
| ... | ... | @@ -7382,6 +7399,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7382 | 7399 | }); |
| 7383 | 7400 | }, |
| 7384 | 7401 | |
| 7402 | .restricted_type => unreachable, // instead use: getReifiedRestrictedType | |
| 7385 | 7403 | .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType |
| 7386 | 7404 | .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType |
| 7387 | 7405 | .enum_type => unreachable, // instead use: getDeclaredEnumType, getReifiedEnumType, getGeneratedEnumTagType |
| ... | ... | @@ -7407,11 +7425,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7407 | 7425 | }, |
| 7408 | 7426 | |
| 7409 | 7427 | .ptr => |ptr| { |
| 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 | }; | |
| 7428 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | |
| 7415 | 7429 | assert(ptr_type.flags.size != .slice); |
| 7416 | 7430 | items.appendAssumeCapacity(switch (ptr.base_addr) { |
| 7417 | 7431 | .nav => |nav| .{ |
| ... | ... | @@ -7983,6 +7997,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7983 | 7997 | .data = try addExtra(extra, bitpack), |
| 7984 | 7998 | }); |
| 7985 | 7999 | }, |
| 8000 | .restricted_value => |restricted_value| { | |
| 8001 | assert(restricted_value.ty.unwrap(ip).getTag(ip) == .type_restricted); | |
| 8002 | assert(!ip.isUndef(restricted_value.unrestricted_value)); | |
| 8003 | items.appendAssumeCapacity(.{ | |
| 8004 | .tag = .restricted_value, | |
| 8005 | .data = try addExtra(extra, restricted_value), | |
| 8006 | }); | |
| 8007 | }, | |
| 7986 | 8008 | |
| 7987 | 8009 | .memoized_call => |memoized_call| { |
| 7988 | 8010 | for (memoized_call.arg_values) |arg| assert(arg != .none); |
| ... | ... | @@ -8009,11 +8031,11 @@ pub fn getReifiedRestrictedType( |
| 8009 | 8031 | io: Io, |
| 8010 | 8032 | tid: Zcu.PerThread.Id, |
| 8011 | 8033 | zir_index: TrackedInst.Index, |
| 8012 | unrestricted_ptr_type: Index, | |
| 8034 | unrestricted_type: Index, | |
| 8013 | 8035 | ) Allocator.Error!WipRestrictedType.Result { |
| 8014 | var gop = try ip.getOrPutKey(gpa, io, tid, .{ .restricted_ptr_type = .{ | |
| 8036 | var gop = try ip.getOrPutKey(gpa, io, tid, .{ .restricted_type = .{ | |
| 8015 | 8037 | .zir_index = zir_index, |
| 8016 | .unrestricted_ptr_type = unrestricted_ptr_type, | |
| 8038 | .unrestricted_type = unrestricted_type, | |
| 8017 | 8039 | } }); |
| 8018 | 8040 | defer gop.deinit(); |
| 8019 | 8041 | if (gop == .existing) return .{ .existing = gop.existing }; |
| ... | ... | @@ -8028,7 +8050,7 @@ pub fn getReifiedRestrictedType( |
| 8028 | 8050 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{ |
| 8029 | 8051 | .zir_index = zir_index, |
| 8030 | 8052 | .name = undefined, |
| 8031 | .unrestricted_ptr_type = unrestricted_ptr_type, | |
| 8053 | .unrestricted_type = unrestricted_type, | |
| 8032 | 8054 | }); |
| 8033 | 8055 | items.appendAssumeCapacity(.{ |
| 8034 | 8056 | .tag = .type_restricted, |
| ... | ... | @@ -10028,7 +10050,6 @@ test "basic usage" { |
| 10028 | 10050 | pub fn childType(ip: *const InternPool, i: Index) Index { |
| 10029 | 10051 | return switch (ip.indexToKey(i)) { |
| 10030 | 10052 | .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, | |
| 10032 | 10053 | .vector_type => |vector_type| vector_type.child, |
| 10033 | 10054 | .array_type => |array_type| array_type.child, |
| 10034 | 10055 | .opt_type, .anyframe_type => |child| child, |
| ... | ... | @@ -10111,28 +10132,22 @@ pub fn getCoerced( |
| 10111 | 10132 | .val = .none, |
| 10112 | 10133 | } }); |
| 10113 | 10134 | |
| 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, | |
| 10135 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { | |
| 10136 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10137 | .ty = new_ty, | |
| 10138 | .base_addr = .int, | |
| 10139 | .byte_offset = 0, | |
| 10140 | } }), | |
| 10141 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10142 | .ty = new_ty, | |
| 10143 | .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10144 | .ty = ip.slicePtrType(new_ty), | |
| 10118 | 10145 | .base_addr = .int, |
| 10119 | 10146 | .byte_offset = 0, |
| 10120 | 10147 | } }), |
| 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 | } | |
| 10148 | .len = .undef_usize, | |
| 10149 | } }), | |
| 10150 | }; | |
| 10136 | 10151 | }, |
| 10137 | 10152 | else => { |
| 10138 | 10153 | const unwrapped_val = val.unwrap(ip); |
| ... | ... | @@ -10211,40 +10226,28 @@ pub fn getCoerced( |
| 10211 | 10226 | }, |
| 10212 | 10227 | else => {}, |
| 10213 | 10228 | }, |
| 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) { | |
| 10229 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .slice) | |
| 10230 | return ip.get(gpa, io, tid, .{ .slice = .{ | |
| 10231 | .ty = new_ty, | |
| 10232 | .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)), | |
| 10233 | .len = slice.len, | |
| 10234 | } }) | |
| 10235 | else if (ip.isIntegerType(new_ty)) | |
| 10236 | return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty), | |
| 10237 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .slice) | |
| 10238 | return ip.get(gpa, io, tid, .{ .ptr = .{ | |
| 10239 | .ty = new_ty, | |
| 10240 | .base_addr = ptr.base_addr, | |
| 10241 | .byte_offset = ptr.byte_offset, | |
| 10242 | } }) | |
| 10243 | else if (ip.isIntegerType(new_ty)) | |
| 10244 | switch (ptr.base_addr) { | |
| 10241 | 10245 | .int => return ip.get(gpa, io, tid, .{ .int = .{ |
| 10242 | 10246 | .ty = .usize_type, |
| 10243 | 10247 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, |
| 10244 | 10248 | } }), |
| 10245 | 10249 | else => {}, |
| 10246 | 10250 | }, |
| 10247 | }, | |
| 10248 | 10251 | .opt => |opt| switch (ip.indexToKey(new_ty)) { |
| 10249 | 10252 | .ptr_type => |ptr_type| return switch (opt.val) { |
| 10250 | 10253 | .none => switch (ptr_type.flags.size) { |
| ... | ... | @@ -10484,6 +10487,22 @@ pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType { |
| 10484 | 10487 | /// includes .comptime_int_type |
| 10485 | 10488 | pub fn isIntegerType(ip: *const InternPool, ty: Index) bool { |
| 10486 | 10489 | return switch (ty) { |
| 10490 | .u0_type, | |
| 10491 | .i0_type, | |
| 10492 | .u1_type, | |
| 10493 | .u8_type, | |
| 10494 | .i8_type, | |
| 10495 | .u16_type, | |
| 10496 | .i16_type, | |
| 10497 | .u29_type, | |
| 10498 | .u32_type, | |
| 10499 | .i32_type, | |
| 10500 | .u64_type, | |
| 10501 | .i64_type, | |
| 10502 | .u80_type, | |
| 10503 | .u128_type, | |
| 10504 | .i128_type, | |
| 10505 | .u256_type, | |
| 10487 | 10506 | .usize_type, |
| 10488 | 10507 | .isize_type, |
| 10489 | 10508 | .c_char_type, |
| ... | ... | @@ -10497,7 +10516,8 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool { |
| 10497 | 10516 | .c_ulonglong_type, |
| 10498 | 10517 | .comptime_int_type, |
| 10499 | 10518 | => true, |
| 10500 | else => switch (ty.unwrap(ip).getTag(ip)) { | |
| 10519 | else => false, | |
| 10520 | _ => switch (ty.unwrap(ip).getTag(ip)) { | |
| 10501 | 10521 | .type_int_signed, |
| 10502 | 10522 | .type_int_unsigned, |
| 10503 | 10523 | => true, |
| ... | ... | @@ -10508,53 +10528,114 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool { |
| 10508 | 10528 | |
| 10509 | 10529 | /// does not include .enum_literal_type |
| 10510 | 10530 | pub fn isEnumType(ip: *const InternPool, ty: Index) bool { |
| 10511 | return ip.indexToKey(ty) == .enum_type; | |
| 10531 | return switch (ty.unwrap(ip).getTag(ip)) { | |
| 10532 | .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => true, | |
| 10533 | else => false, | |
| 10534 | }; | |
| 10535 | } | |
| 10536 | ||
| 10537 | pub fn isVectorType(ip: *const InternPool, ty: Index) bool { | |
| 10538 | return switch (ty.unwrap(ip).getTag(ip)) { | |
| 10539 | .type_vector => true, | |
| 10540 | else => false, | |
| 10541 | }; | |
| 10512 | 10542 | } |
| 10513 | 10543 | |
| 10514 | 10544 | pub fn isUnion(ip: *const InternPool, ty: Index) bool { |
| 10515 | return ip.indexToKey(ty) == .union_type; | |
| 10545 | return switch (ty.unwrap(ip).getTag(ip)) { | |
| 10546 | .type_union, .type_union_packed_auto, .type_union_packed_explicit => true, | |
| 10547 | else => false, | |
| 10548 | }; | |
| 10516 | 10549 | } |
| 10517 | 10550 | |
| 10518 | 10551 | pub fn isFunctionType(ip: *const InternPool, ty: Index) bool { |
| 10519 | return ip.indexToKey(ty) == .func_type; | |
| 10552 | return ty.unwrap(ip).getTag(ip) == .type_function; | |
| 10553 | } | |
| 10554 | ||
| 10555 | pub fn isPointerType(ip: *const InternPool, ty: Index) bool { | |
| 10556 | return switch (ty.unwrap(ip).getTag(ip)) { | |
| 10557 | .type_pointer, .type_slice => true, | |
| 10558 | else => false, | |
| 10559 | }; | |
| 10520 | 10560 | } |
| 10521 | 10561 | |
| 10522 | 10562 | pub fn isOptionalType(ip: *const InternPool, ty: Index) bool { |
| 10523 | return ip.indexToKey(ty) == .opt_type; | |
| 10563 | return ty.unwrap(ip).getTag(ip) == .type_optional; | |
| 10524 | 10564 | } |
| 10525 | 10565 | |
| 10526 | 10566 | /// includes .inferred_error_set_type |
| 10527 | 10567 | pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool { |
| 10528 | 10568 | return switch (ty) { |
| 10529 | 10569 | .anyerror_type, .adhoc_inferred_error_set_type => true, |
| 10530 | else => switch (ip.indexToKey(ty)) { | |
| 10531 | .error_set_type, .inferred_error_set_type => true, | |
| 10570 | else => false, | |
| 10571 | _ => switch (ty.unwrap(ip).getTag(ip)) { | |
| 10572 | .type_error_set, .type_inferred_error_set => true, | |
| 10532 | 10573 | else => false, |
| 10533 | 10574 | }, |
| 10534 | 10575 | }; |
| 10535 | 10576 | } |
| 10536 | 10577 | |
| 10537 | 10578 | pub fn isInferredErrorSetType(ip: *const InternPool, ty: Index) bool { |
| 10538 | return ty == .adhoc_inferred_error_set_type or ip.indexToKey(ty) == .inferred_error_set_type; | |
| 10579 | return ty == .adhoc_inferred_error_set_type or ty.unwrap(ip).getTag(ip) == .type_inferred_error_set; | |
| 10539 | 10580 | } |
| 10540 | 10581 | |
| 10541 | 10582 | pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool { |
| 10542 | return ip.indexToKey(ty) == .error_union_type; | |
| 10583 | return switch (ty) { | |
| 10584 | .anyerror_void_error_union_type => true, | |
| 10585 | else => false, | |
| 10586 | _ => switch (ty.unwrap(ip).getTag(ip)) { | |
| 10587 | .type_error_union, .type_anyerror_union => true, | |
| 10588 | else => false, | |
| 10589 | }, | |
| 10590 | }; | |
| 10543 | 10591 | } |
| 10544 | 10592 | |
| 10545 | 10593 | pub fn isAggregateType(ip: *const InternPool, ty: Index) bool { |
| 10546 | return switch (ip.indexToKey(ty)) { | |
| 10547 | .array_type, .vector_type, .tuple_type, .struct_type => true, | |
| 10594 | return switch (ty.unwrap(ip).getTag(ip)) { | |
| 10595 | .type_array_big, | |
| 10596 | .type_array_small, | |
| 10597 | .type_vector, | |
| 10598 | .type_tuple, | |
| 10599 | .type_struct, | |
| 10600 | .type_struct_packed_auto, | |
| 10601 | .type_struct_packed_explicit, | |
| 10602 | .type_struct_packed_auto_defaults, | |
| 10603 | .type_struct_packed_explicit_defaults, | |
| 10604 | => true, | |
| 10548 | 10605 | else => false, |
| 10549 | 10606 | }; |
| 10550 | 10607 | } |
| 10551 | 10608 | |
| 10609 | pub fn isOpaqueType(ip: *const InternPool, ty: Index) bool { | |
| 10610 | return ty == .anyopaque_type or ty.unwrap(ip).getTag(ip) == .type_opaque; | |
| 10611 | } | |
| 10612 | ||
| 10613 | pub fn isRestrictedType(ip: *const InternPool, ty: Index) bool { | |
| 10614 | return ty.unwrap(ip).getTag(ip) == .type_restricted; | |
| 10615 | } | |
| 10616 | ||
| 10552 | 10617 | pub fn errorUnionSet(ip: *const InternPool, ty: Index) Index { |
| 10553 | return ip.indexToKey(ty).error_union_type.error_set_type; | |
| 10618 | const unwrapped_ty = ty.unwrap(ip); | |
| 10619 | const item = unwrapped_ty.getItem(ip); | |
| 10620 | return switch (item.tag) { | |
| 10621 | .type_error_union => @enumFromInt(unwrapped_ty.getExtra(ip).view().items(.@"0")[ | |
| 10622 | item.data + std.meta.fieldIndex(Key.ErrorUnionType, "error_set_type").? | |
| 10623 | ]), | |
| 10624 | .type_anyerror_union => .anyerror_type, | |
| 10625 | else => unreachable, | |
| 10626 | }; | |
| 10554 | 10627 | } |
| 10555 | 10628 | |
| 10556 | 10629 | pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index { |
| 10557 | return ip.indexToKey(ty).error_union_type.payload_type; | |
| 10630 | const unwrapped_ty = ty.unwrap(ip); | |
| 10631 | const item = unwrapped_ty.getItem(ip); | |
| 10632 | return @enumFromInt(switch (item.tag) { | |
| 10633 | .type_error_union => unwrapped_ty.getExtra(ip).view().items(.@"0")[ | |
| 10634 | item.data + std.meta.fieldIndex(Key.ErrorUnionType, "payload_type").? | |
| 10635 | ], | |
| 10636 | .type_anyerror_union => item.data, | |
| 10637 | else => unreachable, | |
| 10638 | }); | |
| 10558 | 10639 | } |
| 10559 | 10640 | |
| 10560 | 10641 | pub fn dump(ip: *const InternPool) void { |
| ... | ... | @@ -10695,7 +10776,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10695 | 10776 | .type_array_big => @sizeOf(Array), |
| 10696 | 10777 | .type_vector => @sizeOf(Vector), |
| 10697 | 10778 | .type_pointer => @sizeOf(Tag.TypePointer), |
| 10698 | .type_restricted => @sizeOf(Tag.TypeRestricted), | |
| 10699 | 10779 | .type_slice => 0, |
| 10700 | 10780 | .type_optional => 0, |
| 10701 | 10781 | .type_anyframe => 0, |
| ... | ... | @@ -10718,6 +10798,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10718 | 10798 | (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits)); |
| 10719 | 10799 | }, |
| 10720 | 10800 | |
| 10801 | .type_restricted => @sizeOf(Tag.TypeRestricted), | |
| 10721 | 10802 | .type_struct => b: { |
| 10722 | 10803 | var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len; |
| 10723 | 10804 | const extra = extraDataTrail(extra_list, Tag.TypeStruct, data); |
| ... | ... | @@ -10908,7 +10989,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10908 | 10989 | .func_coerced => @sizeOf(Tag.FuncCoerced), |
| 10909 | 10990 | .only_possible_value => 0, |
| 10910 | 10991 | .union_value => @sizeOf(Key.Union), |
| 10911 | .bitpack => 2 * @sizeOf(u32), | |
| 10992 | .bitpack => @sizeOf(Key.Bitpack), | |
| 10993 | .restricted_value => @sizeOf(Key.RestrictedValue), | |
| 10912 | 10994 | |
| 10913 | 10995 | .memoized_call => b: { |
| 10914 | 10996 | const info = extraData(extra_list, MemoizedCall, data); |
| ... | ... | @@ -10957,7 +11039,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 10957 | 11039 | .type_array_big, |
| 10958 | 11040 | .type_vector, |
| 10959 | 11041 | .type_pointer, |
| 10960 | .type_restricted, | |
| 10961 | 11042 | .type_optional, |
| 10962 | 11043 | .type_anyframe, |
| 10963 | 11044 | .type_error_union, |
| ... | ... | @@ -10966,6 +11047,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 10966 | 11047 | .type_inferred_error_set, |
| 10967 | 11048 | .type_tuple, |
| 10968 | 11049 | .type_function, |
| 11050 | .type_restricted, | |
| 10969 | 11051 | .type_struct, |
| 10970 | 11052 | .type_struct_packed_auto, |
| 10971 | 11053 | .type_struct_packed_explicit, |
| ... | ... | @@ -11023,6 +11105,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 11023 | 11105 | .func_coerced, |
| 11024 | 11106 | .union_value, |
| 11025 | 11107 | .bitpack, |
| 11108 | .restricted_value, | |
| 11026 | 11109 | .memoized_call, |
| 11027 | 11110 | => try w.print("{d}", .{data}), |
| 11028 | 11111 | |
| ... | ... | @@ -11696,7 +11779,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11696 | 11779 | .type_array_small, |
| 11697 | 11780 | .type_vector, |
| 11698 | 11781 | .type_pointer, |
| 11699 | .type_restricted, | |
| 11700 | 11782 | .type_slice, |
| 11701 | 11783 | .type_optional, |
| 11702 | 11784 | .type_anyframe, |
| ... | ... | @@ -11706,6 +11788,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11706 | 11788 | .type_inferred_error_set, |
| 11707 | 11789 | .type_tuple, |
| 11708 | 11790 | .type_function, |
| 11791 | .type_restricted, | |
| 11709 | 11792 | .type_struct, |
| 11710 | 11793 | .type_struct_packed_auto, |
| 11711 | 11794 | .type_struct_packed_explicit, |
| ... | ... | @@ -11753,6 +11836,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11753 | 11836 | .aggregate, |
| 11754 | 11837 | .repeated, |
| 11755 | 11838 | .bitpack, |
| 11839 | .restricted_value, | |
| 11756 | 11840 | => |t| { |
| 11757 | 11841 | const extra_list = unwrapped_index.getExtra(ip); |
| 11758 | 11842 | return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]); |
| ... | ... | @@ -12027,7 +12111,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12027 | 12111 | .bool_false => unreachable, |
| 12028 | 12112 | .empty_tuple => unreachable, |
| 12029 | 12113 | |
| 12030 | _ => switch (index.unwrap(ip).getTag(ip)) { | |
| 12114 | _ => return switch (index.unwrap(ip).getTag(ip)) { | |
| 12031 | 12115 | .removed => unreachable, |
| 12032 | 12116 | |
| 12033 | 12117 | .type_int_signed, |
| ... | ... | @@ -12042,7 +12126,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12042 | 12126 | |
| 12043 | 12127 | .type_pointer, |
| 12044 | 12128 | .type_slice, |
| 12045 | .type_restricted, | |
| 12046 | 12129 | => .pointer, |
| 12047 | 12130 | |
| 12048 | 12131 | .type_optional => .optional, |
| ... | ... | @@ -12079,6 +12162,8 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12079 | 12162 | |
| 12080 | 12163 | .type_function => .@"fn", |
| 12081 | 12164 | |
| 12165 | .type_restricted => unreachable, | |
| 12166 | ||
| 12082 | 12167 | // values, not types |
| 12083 | 12168 | .undef, |
| 12084 | 12169 | .simple_value, |
| ... | ... | @@ -12128,6 +12213,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12128 | 12213 | .aggregate, |
| 12129 | 12214 | .repeated, |
| 12130 | 12215 | .bitpack, |
| 12216 | .restricted_value, | |
| 12131 | 12217 | // memoization, not types |
| 12132 | 12218 | .memoized_call, |
| 12133 | 12219 | => unreachable, |
| ... | ... | @@ -12358,11 +12444,7 @@ pub fn addFieldTagValue( |
| 12358 | 12444 | /// encoding instead of `Tag.ptr_uav_aligned` when possible. |
| 12359 | 12445 | fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool { |
| 12360 | 12446 | if (a_ty == b_ty) return true; |
| 12361 | const b_info = switch (ip.indexToKey(b_ty)) { | |
| 12362 | else => unreachable, | |
| 12363 | .ptr_type => |ptr_type| ptr_type, | |
| 12364 | .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 12365 | }; | |
| 12447 | const b_info = ip.indexToKey(b_ty).ptr_type; | |
| 12366 | 12448 | return a_info.flags.alignment == b_info.flags.alignment and |
| 12367 | 12449 | (a_info.child == b_info.child or a_info.flags.alignment != .none); |
| 12368 | 12450 | } |
src/Sema.zig+191-177| ... | ... | @@ -1435,8 +1435,8 @@ 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), | |
| 1439 | 1438 | .reify_fn => try sema.zirReifyFn( block, extended), |
| 1439 | .reify_restricted => try sema.zirReifyRestricted( block, extended, inst), | |
| 1440 | 1440 | .reify_struct => try sema.zirReifyStruct( block, extended, inst), |
| 1441 | 1441 | .reify_union => try sema.zirReifyUnion( block, extended, inst), |
| 1442 | 1442 | .reify_enum => try sema.zirReifyEnum( block, extended, inst), |
| ... | ... | @@ -4641,10 +4641,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4641 | 4641 | const src = block.nodeOffset(inst_data.src_node); |
| 4642 | 4642 | const operand = sema.resolveInst(inst_data.operand); |
| 4643 | 4643 | const operand_ty = sema.typeOf(operand); |
| 4644 | const operand_unrestricted_ty = operand_ty.unrestrictedType(zcu) orelse operand_ty; | |
| 4644 | 4645 | |
| 4645 | if (operand_ty.zigTypeTag(zcu) != .pointer) { | |
| 4646 | if (operand_unrestricted_ty.zigTypeTag(zcu) != .pointer) { | |
| 4646 | 4647 | return sema.fail(block, src, "cannot dereference non-pointer type '{f}'", .{operand_ty.fmt(pt)}); |
| 4647 | } else switch (operand_ty.ptrSize(zcu)) { | |
| 4648 | } else switch (operand_unrestricted_ty.ptrSize(zcu)) { | |
| 4648 | 4649 | .one, .c => {}, |
| 4649 | 4650 | .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{operand_ty.fmt(pt)}), |
| 4650 | 4651 | .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}), |
| ... | ... | @@ -4652,7 +4653,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4652 | 4653 | |
| 4653 | 4654 | if (sema.resolveValue(operand)) |val| { |
| 4654 | 4655 | // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal. |
| 4655 | if (val.isUndef(zcu) and operand_ty.childType(zcu).classify(zcu) != .one_possible_value) { | |
| 4656 | if (val.isUndef(zcu) and operand_unrestricted_ty.childType(zcu).classify(zcu) != .one_possible_value) { | |
| 4656 | 4657 | return sema.fail(block, src, "cannot dereference undefined value", .{}); |
| 4657 | 4658 | } |
| 4658 | 4659 | } |
| ... | ... | @@ -7815,23 +7816,22 @@ fn analyzeDeclLiteral( |
| 7815 | 7816 | block: *Block, |
| 7816 | 7817 | src: LazySrcLoc, |
| 7817 | 7818 | name: InternPool.NullTerminatedString, |
| 7818 | orig_ty: Type, | |
| 7819 | ty: Type, | |
| 7819 | 7820 | do_coerce: bool, |
| 7820 | 7821 | ) CompileError!Air.Inst.Ref { |
| 7821 | 7822 | const pt = sema.pt; |
| 7822 | 7823 | const zcu = pt.zcu; |
| 7823 | 7824 | |
| 7824 | 7825 | const uncoerced_result = res: { |
| 7825 | if (orig_ty.toIntern() == .generic_poison_type) { | |
| 7826 | var unrestricted_ty = ty.unrestrictedType(zcu) orelse ty; | |
| 7827 | if (unrestricted_ty.toIntern() == .generic_poison_type) { | |
| 7826 | 7828 | // Treat this as a normal enum literal. |
| 7827 | 7829 | break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name })); |
| 7828 | 7830 | } |
| 7829 | ||
| 7830 | var ty = orig_ty; | |
| 7831 | while (true) switch (ty.zigTypeTag(zcu)) { | |
| 7832 | .error_union => ty = ty.errorUnionPayload(zcu), | |
| 7833 | .optional => ty = ty.optionalChild(zcu), | |
| 7834 | .pointer => ty = if (ty.isSinglePointer(zcu)) ty.childType(zcu) else break, | |
| 7831 | while (true) switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 7832 | .error_union => unrestricted_ty = unrestricted_ty.errorUnionPayload(zcu), | |
| 7833 | .optional => unrestricted_ty = unrestricted_ty.optionalChild(zcu), | |
| 7834 | .pointer => unrestricted_ty = if (unrestricted_ty.isSinglePointer(zcu)) unrestricted_ty.childType(zcu) else break, | |
| 7835 | 7835 | .enum_literal, .error_set => { |
| 7836 | 7836 | // Treat this as a normal enum literal. |
| 7837 | 7837 | break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name })); |
| ... | ... | @@ -7839,7 +7839,7 @@ fn analyzeDeclLiteral( |
| 7839 | 7839 | else => break, |
| 7840 | 7840 | }; |
| 7841 | 7841 | |
| 7842 | break :res try sema.fieldVal(block, src, Air.internedToRef(ty.toIntern()), name, src); | |
| 7842 | break :res try sema.fieldVal(block, src, Air.internedToRef(unrestricted_ty.toIntern()), name, src); | |
| 7843 | 7843 | }; |
| 7844 | 7844 | |
| 7845 | 7845 | // Decl literals cannot lookup runtime `var`s. |
| ... | ... | @@ -7848,7 +7848,7 @@ fn analyzeDeclLiteral( |
| 7848 | 7848 | } |
| 7849 | 7849 | |
| 7850 | 7850 | if (do_coerce) { |
| 7851 | return sema.coerce(block, orig_ty, uncoerced_result, src); | |
| 7851 | return sema.coerce(block, ty, uncoerced_result, src); | |
| 7852 | 7852 | } else { |
| 7853 | 7853 | return uncoerced_result; |
| 7854 | 7854 | } |
| ... | ... | @@ -16170,16 +16170,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16170 | 16170 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 16171 | 16171 | const src = block.nodeOffset(inst_data.src_node); |
| 16172 | 16172 | const ty = try sema.resolveType(block, src, inst_data.operand); |
| 16173 | const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty; | |
| 16173 | 16174 | const type_info_ty = try sema.getBuiltinType(src, .Type); |
| 16174 | 16175 | const type_info_tag_ty = type_info_ty.unionTagType(zcu).?; |
| 16175 | 16176 | |
| 16176 | try sema.ensureLayoutResolved(ty, src, .type_info); | |
| 16177 | try sema.ensureLayoutResolved(unrestricted_ty, src, .type_info); | |
| 16177 | 16178 | |
| 16178 | if (ty.typeDeclInst(zcu)) |type_decl_inst| { | |
| 16179 | if (unrestricted_ty.typeDeclInst(zcu)) |type_decl_inst| { | |
| 16179 | 16180 | try sema.declareDependency(.{ .namespace = type_decl_inst }); |
| 16180 | 16181 | } |
| 16181 | 16182 | |
| 16182 | switch (ty.zigTypeTag(zcu)) { | |
| 16183 | switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 16183 | 16184 | .type, |
| 16184 | 16185 | .void, |
| 16185 | 16186 | .bool, |
| ... | ... | @@ -16202,7 +16203,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16202 | 16203 | const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn"); |
| 16203 | 16204 | const param_info_ty = try sema.getBuiltinType(src, .@"Type.Fn.Param"); |
| 16204 | 16205 | |
| 16205 | const func_ty_info = zcu.typeToFunc(ty).?; | |
| 16206 | const func_ty_info = zcu.typeToFunc(unrestricted_ty).?; | |
| 16206 | 16207 | const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 16207 | 16208 | var func_is_generic = false; |
| 16208 | 16209 | |
| ... | ... | @@ -16308,7 +16309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16308 | 16309 | .int => { |
| 16309 | 16310 | const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int"); |
| 16310 | 16311 | const signedness_ty = try sema.getBuiltinType(src, .Signedness); |
| 16311 | const info = ty.intInfo(zcu); | |
| 16312 | const info = unrestricted_ty.intInfo(zcu); | |
| 16312 | 16313 | const field_values = .{ |
| 16313 | 16314 | // signedness: Signedness, |
| 16314 | 16315 | (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), |
| ... | ... | @@ -16326,7 +16327,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16326 | 16327 | |
| 16327 | 16328 | const field_vals = .{ |
| 16328 | 16329 | // bits: u16, |
| 16329 | (try pt.intValue(.u16, ty.floatBits(zcu.getTarget()))).toIntern(), | |
| 16330 | (try pt.intValue(.u16, unrestricted_ty.floatBits(zcu.getTarget()))).toIntern(), | |
| 16330 | 16331 | }; |
| 16331 | 16332 | return Air.internedToRef((try pt.internUnion(.{ |
| 16332 | 16333 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -16335,7 +16336,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16335 | 16336 | }))); |
| 16336 | 16337 | }, |
| 16337 | 16338 | .pointer => { |
| 16338 | const info = ty.ptrInfo(zcu); | |
| 16339 | const info = unrestricted_ty.ptrInfo(zcu); | |
| 16339 | 16340 | const alignment_ty = try pt.optionalType(.usize_type); |
| 16340 | 16341 | const alignment_val: Value = val: { |
| 16341 | 16342 | const bytes = info.flags.alignment.toByteUnits() orelse { |
| ... | ... | @@ -16382,7 +16383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16382 | 16383 | .array => { |
| 16383 | 16384 | const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array"); |
| 16384 | 16385 | |
| 16385 | const info = ty.arrayInfo(zcu); | |
| 16386 | const info = unrestricted_ty.arrayInfo(zcu); | |
| 16386 | 16387 | const field_values = .{ |
| 16387 | 16388 | // len: comptime_int, |
| 16388 | 16389 | (try pt.intValue(.comptime_int, info.len)).toIntern(), |
| ... | ... | @@ -16400,7 +16401,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16400 | 16401 | .vector => { |
| 16401 | 16402 | const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector"); |
| 16402 | 16403 | |
| 16403 | const info = ty.arrayInfo(zcu); | |
| 16404 | const info = unrestricted_ty.arrayInfo(zcu); | |
| 16404 | 16405 | const field_values = .{ |
| 16405 | 16406 | // len: comptime_int, |
| 16406 | 16407 | (try pt.intValue(.comptime_int, info.len)).toIntern(), |
| ... | ... | @@ -16418,7 +16419,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16418 | 16419 | |
| 16419 | 16420 | const field_values = .{ |
| 16420 | 16421 | // child: type, |
| 16421 | ty.optionalChild(zcu).toIntern(), | |
| 16422 | unrestricted_ty.optionalChild(zcu).toIntern(), | |
| 16422 | 16423 | }; |
| 16423 | 16424 | return Air.internedToRef((try pt.internUnion(.{ |
| 16424 | 16425 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -16433,7 +16434,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16433 | 16434 | // Build our list of Error values |
| 16434 | 16435 | // Optional value is only null if anyerror |
| 16435 | 16436 | // Value can be zero-length slice otherwise |
| 16436 | const error_field_vals = switch (try sema.resolveInferredErrorSetTy(block, src, ty.toIntern())) { | |
| 16437 | const error_field_vals = switch (try sema.resolveInferredErrorSetTy(block, src, unrestricted_ty.toIntern())) { | |
| 16437 | 16438 | .anyerror_type => null, |
| 16438 | 16439 | else => |err_set_ty_index| blk: { |
| 16439 | 16440 | const names = ip.indexToKey(err_set_ty_index).error_set_type.names; |
| ... | ... | @@ -16522,9 +16523,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16522 | 16523 | |
| 16523 | 16524 | const field_values = .{ |
| 16524 | 16525 | // error_set: type, |
| 16525 | ty.errorUnionSet(zcu).toIntern(), | |
| 16526 | unrestricted_ty.errorUnionSet(zcu).toIntern(), | |
| 16526 | 16527 | // payload: type, |
| 16527 | ty.errorUnionPayload(zcu).toIntern(), | |
| 16528 | unrestricted_ty.errorUnionPayload(zcu).toIntern(), | |
| 16528 | 16529 | }; |
| 16529 | 16530 | return Air.internedToRef((try pt.internUnion(.{ |
| 16530 | 16531 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -16533,7 +16534,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16533 | 16534 | }))); |
| 16534 | 16535 | }, |
| 16535 | 16536 | .@"enum" => { |
| 16536 | const enum_obj = ip.loadEnumType(ty.toIntern()); | |
| 16537 | const enum_obj = ip.loadEnumType(unrestricted_ty.toIntern()); | |
| 16537 | 16538 | const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive); |
| 16538 | 16539 | |
| 16539 | 16540 | const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField"); |
| ... | ... | @@ -16615,13 +16616,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16615 | 16616 | } }); |
| 16616 | 16617 | }; |
| 16617 | 16618 | |
| 16618 | const decls_val = try sema.typeInfoDecls(src, ip.loadEnumType(ty.toIntern()).namespace.toOptional()); | |
| 16619 | const decls_val = try sema.typeInfoDecls(src, ip.loadEnumType(unrestricted_ty.toIntern()).namespace.toOptional()); | |
| 16619 | 16620 | |
| 16620 | 16621 | const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum"); |
| 16621 | 16622 | |
| 16622 | 16623 | const field_values = .{ |
| 16623 | 16624 | // tag_type: type, |
| 16624 | ip.loadEnumType(ty.toIntern()).int_tag_type, | |
| 16625 | ip.loadEnumType(unrestricted_ty.toIntern()).int_tag_type, | |
| 16625 | 16626 | // fields: []const EnumField, |
| 16626 | 16627 | fields_val, |
| 16627 | 16628 | // decls: []const Declaration, |
| ... | ... | @@ -16639,7 +16640,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16639 | 16640 | const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union"); |
| 16640 | 16641 | const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField"); |
| 16641 | 16642 | |
| 16642 | const union_obj = ip.loadUnionType(ty.toIntern()); | |
| 16643 | const union_obj = ip.loadUnionType(unrestricted_ty.toIntern()); | |
| 16643 | 16644 | const enum_obj = ip.loadEnumType(union_obj.enum_tag_type); |
| 16644 | 16645 | const layout = union_obj.layout; |
| 16645 | 16646 | |
| ... | ... | @@ -16678,7 +16679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16678 | 16679 | const alignment_ty = try pt.optionalType(.usize_type); |
| 16679 | 16680 | const alignment_val: Value = val: { |
| 16680 | 16681 | const a: Alignment = switch (layout) { |
| 16681 | .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu), | |
| 16682 | .auto, .@"extern" => unrestricted_ty.explicitFieldAlignment(field_index, zcu), | |
| 16682 | 16683 | .@"packed" => .none, |
| 16683 | 16684 | }; |
| 16684 | 16685 | const bytes = a.toByteUnits() orelse { |
| ... | ... | @@ -16730,11 +16731,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16730 | 16731 | } }); |
| 16731 | 16732 | }; |
| 16732 | 16733 | |
| 16733 | const decls_val = try sema.typeInfoDecls(src, ty.getNamespaceIndex(zcu).toOptional()); | |
| 16734 | const decls_val = try sema.typeInfoDecls(src, unrestricted_ty.getNamespaceIndex(zcu).toOptional()); | |
| 16734 | 16735 | |
| 16735 | 16736 | const enum_tag_ty_val = try pt.intern(.{ .opt = .{ |
| 16736 | 16737 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 16737 | .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none, | |
| 16738 | .val = if (unrestricted_ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none, | |
| 16738 | 16739 | } }); |
| 16739 | 16740 | |
| 16740 | 16741 | const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout"); |
| ... | ... | @@ -16763,7 +16764,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16763 | 16764 | var struct_field_vals: []InternPool.Index = &.{}; |
| 16764 | 16765 | defer gpa.free(struct_field_vals); |
| 16765 | 16766 | fv: { |
| 16766 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { | |
| 16767 | const struct_type = switch (ip.indexToKey(unrestricted_ty.toIntern())) { | |
| 16767 | 16768 | .tuple_type => |tuple_type| { |
| 16768 | 16769 | struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len); |
| 16769 | 16770 | for (struct_field_vals, 0..) |*struct_field_val, field_index| { |
| ... | ... | @@ -16815,10 +16816,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16815 | 16816 | } |
| 16816 | 16817 | break :fv; |
| 16817 | 16818 | }, |
| 16818 | .struct_type => ip.loadStructType(ty.toIntern()), | |
| 16819 | .struct_type => ip.loadStructType(unrestricted_ty.toIntern()), | |
| 16819 | 16820 | else => unreachable, |
| 16820 | 16821 | }; |
| 16821 | try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples | |
| 16822 | try sema.ensureStructDefaultsResolved(unrestricted_ty, src); // can't do this sooner, since it's not allowed on tuples | |
| 16822 | 16823 | struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); |
| 16823 | 16824 | |
| 16824 | 16825 | for (struct_field_vals, 0..) |*field_val, field_index| { |
| ... | ... | @@ -16859,7 +16860,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16859 | 16860 | const alignment_ty = try pt.optionalType(.usize_type); |
| 16860 | 16861 | const alignment_val: Value = val: { |
| 16861 | 16862 | const a: Alignment = switch (struct_type.layout) { |
| 16862 | .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu), | |
| 16863 | .auto, .@"extern" => unrestricted_ty.explicitFieldAlignment(field_index, zcu), | |
| 16863 | 16864 | .@"packed" => .none, |
| 16864 | 16865 | }; |
| 16865 | 16866 | const bytes = a.toByteUnits() orelse { |
| ... | ... | @@ -16916,11 +16917,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16916 | 16917 | } }); |
| 16917 | 16918 | }; |
| 16918 | 16919 | |
| 16919 | const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu)); | |
| 16920 | const decls_val = try sema.typeInfoDecls(src, unrestricted_ty.getNamespace(zcu)); | |
| 16920 | 16921 | |
| 16921 | 16922 | const backing_integer_val = try pt.intern(.{ .opt = .{ |
| 16922 | 16923 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 16923 | .val = if (zcu.typeToPackedStruct(ty)) |struct_obj| val: { | |
| 16924 | .val = if (zcu.typeToPackedStruct(unrestricted_ty)) |struct_obj| val: { | |
| 16924 | 16925 | assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu)); |
| 16925 | 16926 | break :val struct_obj.packed_backing_int_type; |
| 16926 | 16927 | } else .none, |
| ... | ... | @@ -16928,7 +16929,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16928 | 16929 | |
| 16929 | 16930 | const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout"); |
| 16930 | 16931 | |
| 16931 | const layout = ty.containerLayout(zcu); | |
| 16932 | const layout = unrestricted_ty.containerLayout(zcu); | |
| 16932 | 16933 | |
| 16933 | 16934 | const field_values = [_]InternPool.Index{ |
| 16934 | 16935 | // layout: ContainerLayout, |
| ... | ... | @@ -16940,7 +16941,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16940 | 16941 | // decls: []const Declaration, |
| 16941 | 16942 | decls_val, |
| 16942 | 16943 | // is_tuple: bool, |
| 16943 | Value.makeBool(ty.isTuple(zcu)).toIntern(), | |
| 16944 | Value.makeBool(unrestricted_ty.isTuple(zcu)).toIntern(), | |
| 16944 | 16945 | }; |
| 16945 | 16946 | return Air.internedToRef((try pt.internUnion(.{ |
| 16946 | 16947 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -16951,7 +16952,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16951 | 16952 | .@"opaque" => { |
| 16952 | 16953 | const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque"); |
| 16953 | 16954 | |
| 16954 | const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu)); | |
| 16955 | const decls_val = try sema.typeInfoDecls(src, unrestricted_ty.getNamespace(zcu)); | |
| 16955 | 16956 | |
| 16956 | 16957 | const field_values = .{ |
| 16957 | 16958 | // decls: []const Declaration, |
| ... | ... | @@ -19212,7 +19213,7 @@ fn arrayInitAnon( |
| 19212 | 19213 | } }); |
| 19213 | 19214 | const elem = sema.resolveInst(operand); |
| 19214 | 19215 | types[i] = sema.typeOf(elem).toIntern(); |
| 19215 | if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") { | |
| 19216 | if (ip.isOpaqueType(types[i])) { | |
| 19216 | 19217 | const msg = msg: { |
| 19217 | 19218 | const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 19218 | 19219 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -19599,22 +19600,24 @@ fn zirUnaryMath( |
| 19599 | 19600 | } |
| 19600 | 19601 | |
| 19601 | 19602 | fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 19603 | const pt = sema.pt; | |
| 19604 | const zcu = pt.zcu; | |
| 19605 | const ip = &zcu.intern_pool; | |
| 19606 | ||
| 19602 | 19607 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19603 | 19608 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 19604 | 19609 | const src = block.nodeOffset(inst_data.src_node); |
| 19605 | 19610 | const operand = sema.resolveInst(inst_data.operand); |
| 19606 | 19611 | const operand_ty = sema.typeOf(operand); |
| 19607 | const pt = sema.pt; | |
| 19608 | const zcu = pt.zcu; | |
| 19609 | const ip = &zcu.intern_pool; | |
| 19610 | const enum_ty = switch (operand_ty.zigTypeTag(zcu)) { | |
| 19612 | const unrestricted_operand_ty = operand_ty.unrestrictedType(zcu) orelse operand_ty; | |
| 19613 | const enum_ty = switch (unrestricted_operand_ty.zigTypeTag(zcu)) { | |
| 19611 | 19614 | .enum_literal => { |
| 19612 | 19615 | const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?; |
| 19613 | 19616 | const tag_name = ip.indexToKey(val.toIntern()).enum_literal; |
| 19614 | 19617 | return sema.addNullTerminatedStrLit(tag_name); |
| 19615 | 19618 | }, |
| 19616 | .@"enum" => operand_ty, | |
| 19617 | .@"union" => operand_ty.unionTagType(zcu) orelse | |
| 19619 | .@"enum" => unrestricted_operand_ty, | |
| 19620 | .@"union" => unrestricted_operand_ty.unionTagType(zcu) orelse | |
| 19618 | 19621 | return sema.fail(block, src, "union '{f}' is untagged", .{operand_ty.fmt(pt)}), |
| 19619 | 19622 | else => return sema.fail(block, operand_src, "expected enum or union; found '{f}'", .{ |
| 19620 | 19623 | operand_ty.fmt(pt), |
| ... | ... | @@ -19881,62 +19884,6 @@ fn zirReifyPointer( |
| 19881 | 19884 | })); |
| 19882 | 19885 | } |
| 19883 | 19886 | |
| 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 | ||
| 19940 | 19887 | fn zirReifyFn( |
| 19941 | 19888 | sema: *Sema, |
| 19942 | 19889 | block: *Block, |
| ... | ... | @@ -20035,6 +19982,58 @@ fn zirReifyFn( |
| 20035 | 19982 | })); |
| 20036 | 19983 | } |
| 20037 | 19984 | |
| 19985 | fn zirReifyRestricted( | |
| 19986 | sema: *Sema, | |
| 19987 | block: *Block, | |
| 19988 | extended: Zir.Inst.Extended.InstData, | |
| 19989 | inst: Zir.Inst.Index, | |
| 19990 | ) CompileError!Air.Inst.Ref { | |
| 19991 | const pt = sema.pt; | |
| 19992 | const zcu = pt.zcu; | |
| 19993 | const comp = zcu.comp; | |
| 19994 | const gpa = comp.gpa; | |
| 19995 | const io = comp.io; | |
| 19996 | const ip = &zcu.intern_pool; | |
| 19997 | ||
| 19998 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | |
| 19999 | const extra = sema.code.extraData(Zir.Inst.ReifyRestricted, extended.operand).data; | |
| 20000 | const tracked_inst = try block.trackZir(inst); | |
| 20001 | ||
| 20002 | const src: LazySrcLoc = .{ | |
| 20003 | .base_node_inst = tracked_inst, | |
| 20004 | .offset = .nodeOffset(.zero), | |
| 20005 | }; | |
| 20006 | const operand_src: LazySrcLoc = .{ | |
| 20007 | .base_node_inst = tracked_inst, | |
| 20008 | .offset = .{ .node_offset_builtin_call_arg = .{ | |
| 20009 | .builtin_call_node = .zero, | |
| 20010 | .arg_index = 0, | |
| 20011 | } }, | |
| 20012 | }; | |
| 20013 | ||
| 20014 | const operand = try sema.resolveType(block, src, extra.unrestricted_ty); | |
| 20015 | const unrestricted_type = switch (ip.indexToKey(operand.toIntern())) { | |
| 20016 | else => operand.toIntern(), | |
| 20017 | .restricted_type => return sema.fail(block, operand_src, "cannot restrict restricted type '{f}'", .{operand.fmt(pt)}), | |
| 20018 | }; | |
| 20019 | ||
| 20020 | switch (try ip.getReifiedRestrictedType(gpa, io, pt.tid, tracked_inst, unrestricted_type)) { | |
| 20021 | .existing => |ty| { | |
| 20022 | try sema.addTypeReferenceEntry(src, .fromInterned(ty)); | |
| 20023 | // No need for `ensureNamespaceUpToDate` because this type doesn't have a namespace. | |
| 20024 | return .fromIntern(ty); | |
| 20025 | }, | |
| 20026 | .wip => |wip| { | |
| 20027 | errdefer wip.cancel(ip, pt.tid); | |
| 20028 | const type_name, _ = try sema.computeTypeName(block, wip.index, name_strategy, "restricted", inst); | |
| 20029 | wip.setName(ip, type_name); | |
| 20030 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); | |
| 20031 | try sema.addTypeReferenceEntry(src, .fromInterned(wip.index)); | |
| 20032 | return .fromIntern(wip.index); | |
| 20033 | }, | |
| 20034 | } | |
| 20035 | } | |
| 20036 | ||
| 20038 | 20037 | fn zirReifyStruct( |
| 20039 | 20038 | sema: *Sema, |
| 20040 | 20039 | block: *Block, |
| ... | ... | @@ -25149,7 +25148,7 @@ pub fn validateVarType( |
| 25149 | 25148 | return sema.failWithOwnedErrorMsg(block, msg); |
| 25150 | 25149 | } |
| 25151 | 25150 | } else { |
| 25152 | if (var_ty.zigTypeTag(zcu) == .@"opaque") { | |
| 25151 | if (zcu.intern_pool.isOpaqueType(var_ty.toIntern())) { | |
| 25153 | 25152 | return sema.fail( |
| 25154 | 25153 | block, |
| 25155 | 25154 | src, |
| ... | ... | @@ -25166,8 +25165,11 @@ pub fn validateVarType( |
| 25166 | 25165 | errdefer msg.destroy(sema.gpa); |
| 25167 | 25166 | |
| 25168 | 25167 | try sema.explainWhyTypeIsComptime(msg, src, var_ty); |
| 25169 | if (var_ty.zigTypeTag(zcu) == .comptime_int or var_ty.zigTypeTag(zcu) == .comptime_float) { | |
| 25170 | try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{}); | |
| 25168 | switch (var_ty.toIntern()) { | |
| 25169 | else => {}, | |
| 25170 | .comptime_int_type, | |
| 25171 | .comptime_float_type, | |
| 25172 | => try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{}), | |
| 25171 | 25173 | } |
| 25172 | 25174 | |
| 25173 | 25175 | break :msg msg; |
| ... | ... | @@ -25756,23 +25758,24 @@ fn fieldVal( |
| 25756 | 25758 | const ip = &zcu.intern_pool; |
| 25757 | 25759 | const object_src = src; // TODO better source location |
| 25758 | 25760 | const object_ty = sema.typeOf(object); |
| 25761 | const unrestricted_object_ty = object_ty.unrestrictedType(zcu) orelse object_ty; | |
| 25759 | 25762 | |
| 25760 | 25763 | // Zig allows dereferencing a single pointer during field lookup. Note that |
| 25761 | 25764 | // we don't actually need to generate the dereference some field lookups, like the |
| 25762 | 25765 | // length of arrays and other comptime operations. |
| 25763 | const is_pointer_to = object_ty.isSinglePointer(zcu); | |
| 25766 | const is_pointer_to = unrestricted_object_ty.isSinglePointer(zcu); | |
| 25764 | 25767 | |
| 25765 | 25768 | const inner_ty = if (is_pointer_to) |
| 25766 | object_ty.childType(zcu) | |
| 25769 | unrestricted_object_ty.childType(zcu) | |
| 25767 | 25770 | else |
| 25768 | object_ty; | |
| 25771 | unrestricted_object_ty; | |
| 25769 | 25772 | |
| 25770 | 25773 | switch (inner_ty.zigTypeTag(zcu)) { |
| 25771 | 25774 | .array => { |
| 25772 | 25775 | if (field_name.eqlSlice("len", ip)) { |
| 25773 | 25776 | return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern()); |
| 25774 | 25777 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 25775 | const ptr_info = object_ty.ptrInfo(zcu); | |
| 25778 | const ptr_info = unrestricted_object_ty.ptrInfo(zcu); | |
| 25776 | 25779 | const result_ty = try pt.ptrType(.{ |
| 25777 | 25780 | .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(), |
| 25778 | 25781 | .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none, |
| ... | ... | @@ -25829,11 +25832,12 @@ fn fieldVal( |
| 25829 | 25832 | object; |
| 25830 | 25833 | |
| 25831 | 25834 | const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?; |
| 25832 | const child_type = val.toType(); | |
| 25835 | const child_ty = val.toType(); | |
| 25836 | const unrestricted_child_ty = child_ty.unrestrictedType(zcu) orelse child_ty; | |
| 25833 | 25837 | |
| 25834 | switch (child_type.zigTypeTag(zcu)) { | |
| 25838 | switch (unrestricted_child_ty.zigTypeTag(zcu)) { | |
| 25835 | 25839 | .error_set => { |
| 25836 | const err_set_ty: Type = err_set: switch (ip.indexToKey(child_type.toIntern())) { | |
| 25840 | const err_set_ty: Type = err_set: switch (ip.indexToKey(unrestricted_child_ty.toIntern())) { | |
| 25837 | 25841 | .inferred_error_set_type => |func_index| { |
| 25838 | 25842 | try sema.ensureFuncIesResolved(block, src, func_index); |
| 25839 | 25843 | const resolved_ies = ip.funcIesResolvedUnordered(func_index); |
| ... | ... | @@ -25841,9 +25845,9 @@ fn fieldVal( |
| 25841 | 25845 | }, |
| 25842 | 25846 | .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) { |
| 25843 | 25847 | return sema.fail(block, src, "no error named '{f}' in '{f}'", .{ |
| 25844 | field_name.fmt(ip), child_type.fmt(pt), | |
| 25848 | field_name.fmt(ip), child_ty.fmt(pt), | |
| 25845 | 25849 | }); |
| 25846 | } else child_type, | |
| 25850 | } else unrestricted_child_ty, | |
| 25847 | 25851 | .simple_type => |t| { |
| 25848 | 25852 | assert(t == .anyerror); |
| 25849 | 25853 | _ = try pt.getErrorValue(field_name); |
| ... | ... | @@ -25857,42 +25861,42 @@ fn fieldVal( |
| 25857 | 25861 | } })); |
| 25858 | 25862 | }, |
| 25859 | 25863 | .@"union" => { |
| 25860 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25864 | if (try sema.namespaceLookupVal(block, src, unrestricted_child_ty.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25861 | 25865 | return inst; |
| 25862 | 25866 | } |
| 25863 | try sema.ensureLayoutResolved(child_type, src, .field_used); | |
| 25864 | if (child_type.unionTagType(zcu)) |enum_ty| { | |
| 25867 | try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used); | |
| 25868 | if (unrestricted_child_ty.unionTagType(zcu)) |enum_ty| { | |
| 25865 | 25869 | if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| { |
| 25866 | 25870 | const field_index: u32 = @intCast(field_index_usize); |
| 25867 | 25871 | return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern()); |
| 25868 | 25872 | } |
| 25869 | 25873 | } |
| 25870 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | |
| 25874 | return sema.failWithBadMemberAccess(block, child_ty, field_name_src, field_name); | |
| 25871 | 25875 | }, |
| 25872 | 25876 | .@"enum" => { |
| 25873 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25877 | if (try sema.namespaceLookupVal(block, src, unrestricted_child_ty.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25874 | 25878 | return inst; |
| 25875 | 25879 | } |
| 25876 | try sema.ensureLayoutResolved(child_type, src, .field_used); | |
| 25877 | const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse | |
| 25878 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | |
| 25880 | try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used); | |
| 25881 | const field_index_usize = unrestricted_child_ty.enumFieldIndex(field_name, zcu) orelse | |
| 25882 | return sema.failWithBadMemberAccess(block, child_ty, field_name_src, field_name); | |
| 25879 | 25883 | const field_index: u32 = @intCast(field_index_usize); |
| 25880 | const enum_val = try pt.enumValueFieldIndex(child_type, field_index); | |
| 25884 | const enum_val = try pt.enumValueFieldIndex(unrestricted_child_ty, field_index); | |
| 25881 | 25885 | return Air.internedToRef(enum_val.toIntern()); |
| 25882 | 25886 | }, |
| 25883 | 25887 | .@"struct", .@"opaque" => { |
| 25884 | if (!child_type.isTuple(zcu) and child_type.toIntern() != .anyopaque_type) { | |
| 25885 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25888 | if (!unrestricted_child_ty.isTuple(zcu) and unrestricted_child_ty.toIntern() != .anyopaque_type) { | |
| 25889 | if (try sema.namespaceLookupVal(block, src, unrestricted_child_ty.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 25886 | 25890 | return inst; |
| 25887 | 25891 | } |
| 25888 | 25892 | } |
| 25889 | return sema.failWithBadMemberAccess(block, child_type, src, field_name); | |
| 25893 | return sema.failWithBadMemberAccess(block, child_ty, src, field_name); | |
| 25890 | 25894 | }, |
| 25891 | 25895 | else => return sema.failWithOwnedErrorMsg(block, msg: { |
| 25892 | const msg = try sema.errMsg(src, "type '{f}' has no members", .{child_type.fmt(pt)}); | |
| 25896 | const msg = try sema.errMsg(src, "type '{f}' has no members", .{child_ty.fmt(pt)}); | |
| 25893 | 25897 | errdefer msg.destroy(sema.gpa); |
| 25894 | if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | |
| 25895 | if (child_type.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | |
| 25898 | if (unrestricted_child_ty.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | |
| 25899 | if (unrestricted_child_ty.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | |
| 25896 | 25900 | break :msg msg; |
| 25897 | 25901 | }), |
| 25898 | 25902 | } |
| ... | ... | @@ -27471,6 +27475,29 @@ fn coerceExtra( |
| 27471 | 27475 | |
| 27472 | 27476 | const maybe_inst_val = sema.resolveValue(inst); |
| 27473 | 27477 | |
| 27478 | // Restricted coercions | |
| 27479 | if (maybe_inst_val != null) { | |
| 27480 | if (dest_ty.unrestrictedType(zcu)) |dest_unrestricted_ty| { | |
| 27481 | if (sema.resolveValue(try sema.coerceExtra(block, dest_unrestricted_ty, inst, inst_src, opts))) |dest_unrestricted_val| { | |
| 27482 | return .fromIntern(try pt.intern(if (dest_unrestricted_val.isUndef(zcu)) .{ | |
| 27483 | .undef = dest_ty.toIntern(), | |
| 27484 | } else .{ .restricted_value = .{ | |
| 27485 | .ty = dest_ty.toIntern(), | |
| 27486 | .unrestricted_value = dest_unrestricted_val.toIntern(), | |
| 27487 | } })); | |
| 27488 | } | |
| 27489 | } | |
| 27490 | } | |
| 27491 | if (inst_ty.unrestrictedType(zcu)) |inst_unrestricted_ty| { | |
| 27492 | const unrestricted_inst: Air.Inst.Ref = if (maybe_inst_val) |inst_val| | |
| 27493 | .fromIntern(ip.indexToKey(inst_val.toIntern()).restricted_value.unrestricted_value) | |
| 27494 | else unrestricted_inst: { | |
| 27495 | try sema.requireRuntimeBlock(block, inst_src, null); | |
| 27496 | break :unrestricted_inst try sema.unwrapRestricted(block, inst_unrestricted_ty, inst, inst_src); | |
| 27497 | }; | |
| 27498 | return sema.coerceExtra(block, dest_ty, unrestricted_inst, inst_src, opts); | |
| 27499 | } | |
| 27500 | ||
| 27474 | 27501 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val); |
| 27475 | 27502 | if (in_memory_result == .ok) { |
| 27476 | 27503 | if (maybe_inst_val) |val| { |
| ... | ... | @@ -27796,22 +27823,6 @@ fn coerceExtra( |
| 27796 | 27823 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); |
| 27797 | 27824 | }, |
| 27798 | 27825 | } |
| 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 | } | |
| 27815 | 27826 | }, |
| 27816 | 27827 | .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) { |
| 27817 | 27828 | .float, .comptime_float => float: { |
| ... | ... | @@ -28126,6 +28137,7 @@ fn coerceInMemory( |
| 28126 | 28137 | |
| 28127 | 28138 | const InMemoryCoercionResult = union(enum) { |
| 28128 | 28139 | ok, |
| 28140 | restricted: Pair, | |
| 28129 | 28141 | no_match: Pair, |
| 28130 | 28142 | int_not_coercible: Int, |
| 28131 | 28143 | comptime_int_not_coercible: TypeValuePair, |
| ... | ... | @@ -28160,7 +28172,6 @@ const InMemoryCoercionResult = union(enum) { |
| 28160 | 28172 | ptr_alignment: AlignPair, |
| 28161 | 28173 | double_ptr_to_anyopaque: Pair, |
| 28162 | 28174 | slice_to_anyopaque: Pair, |
| 28163 | ptr_restricted: Pair, | |
| 28164 | 28175 | |
| 28165 | 28176 | const Pair = struct { |
| 28166 | 28177 | actual: Type, |
| ... | ... | @@ -28247,6 +28258,16 @@ const InMemoryCoercionResult = union(enum) { |
| 28247 | 28258 | var cur = res; |
| 28248 | 28259 | while (true) switch (cur.*) { |
| 28249 | 28260 | .ok => unreachable, |
| 28261 | .restricted => |pair| { | |
| 28262 | for ([_]Type{ pair.actual, pair.wanted }) |restricted_type| { | |
| 28263 | try sema.addDeclaredHereNote(msg, restricted_type); | |
| 28264 | const unrestricted_type = restricted_type.unrestrictedType(pt.zcu) orelse continue; | |
| 28265 | try sema.errNote(src, msg, "restricted type '{f}' is not guaranteed to have the same representation as its unrestricted type '{f}'", .{ | |
| 28266 | restricted_type.fmt(pt), unrestricted_type.fmt(pt), | |
| 28267 | }); | |
| 28268 | } | |
| 28269 | break; | |
| 28270 | }, | |
| 28250 | 28271 | .no_match => |types| { |
| 28251 | 28272 | try sema.addDeclaredHereNote(msg, types.wanted); |
| 28252 | 28273 | try sema.addDeclaredHereNote(msg, types.actual); |
| ... | ... | @@ -28492,15 +28513,6 @@ const InMemoryCoercionResult = union(enum) { |
| 28492 | 28513 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); |
| 28493 | 28514 | break; |
| 28494 | 28515 | }, |
| 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 | }, | |
| 28504 | 28516 | }; |
| 28505 | 28517 | } |
| 28506 | 28518 | }; |
| ... | ... | @@ -28538,6 +28550,7 @@ pub fn coerceInMemoryAllowed( |
| 28538 | 28550 | ) CompileError!InMemoryCoercionResult { |
| 28539 | 28551 | const pt = sema.pt; |
| 28540 | 28552 | const zcu = pt.zcu; |
| 28553 | const ip = &zcu.intern_pool; | |
| 28541 | 28554 | |
| 28542 | 28555 | if (src_val) |val| { |
| 28543 | 28556 | assert(val.typeOf(zcu).toIntern() == src_ty.toIntern()); |
| ... | ... | @@ -28546,6 +28559,12 @@ pub fn coerceInMemoryAllowed( |
| 28546 | 28559 | if (dest_ty.eql(src_ty, zcu)) |
| 28547 | 28560 | return .ok; |
| 28548 | 28561 | |
| 28562 | // Restricted types have a different in-memory representation depending on the safety mode of the module that created them. | |
| 28563 | if (ip.isRestrictedType(dest_ty.toIntern()) or ip.isRestrictedType(src_ty.toIntern())) return .{ .restricted = .{ | |
| 28564 | .actual = src_ty, | |
| 28565 | .wanted = dest_ty, | |
| 28566 | } }; | |
| 28567 | ||
| 28549 | 28568 | const dest_tag = dest_ty.zigTypeTag(zcu); |
| 28550 | 28569 | const src_tag = src_ty.zigTypeTag(zcu); |
| 28551 | 28570 | |
| ... | ... | @@ -29142,12 +29161,6 @@ fn coerceInMemoryAllowedPtrs( |
| 29142 | 29161 | } |
| 29143 | 29162 | } |
| 29144 | 29163 | |
| 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 | ||
| 29151 | 29164 | return .ok; |
| 29152 | 29165 | } |
| 29153 | 29166 | |
| ... | ... | @@ -29295,7 +29308,7 @@ fn storePtr2( |
| 29295 | 29308 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 29296 | 29309 | |
| 29297 | 29310 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| |
| 29298 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 29311 | try sema.unwrapRestricted(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 29299 | 29312 | else |
| 29300 | 29313 | ptr; |
| 29301 | 29314 | |
| ... | ... | @@ -30185,7 +30198,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde |
| 30185 | 30198 | |
| 30186 | 30199 | const nav_index = nav: { |
| 30187 | 30200 | const orig_nav = ip.getNav(orig_nav_index); |
| 30188 | if (orig_nav.resolved.?.is_extern_decl or ip.zigTypeTag(orig_nav.resolved.?.type) == .@"fn") { | |
| 30201 | if (orig_nav.resolved.?.is_extern_decl or ip.isFunctionType(orig_nav.resolved.?.type)) { | |
| 30189 | 30202 | // A pointer to this `Nav` might actually be encoded as a pointer to a different `Nav` |
| 30190 | 30203 | // because this is either an `extern` definition or an `extern` alias. (The latter case |
| 30191 | 30204 | // is unsolved language weirdness; see https://github.com/ziglang/zig/issues/21027.) To |
| ... | ... | @@ -30266,7 +30279,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i |
| 30266 | 30279 | |
| 30267 | 30280 | try sema.ensureNavResolved(block, src, nav_index, .type); |
| 30268 | 30281 | const nav_ty: Type = .fromInterned(ip.getNav(nav_index).resolved.?.type); |
| 30269 | if (nav_ty.zigTypeTag(zcu) != .@"fn") return; | |
| 30282 | if (!ip.isFunctionType(nav_ty.toIntern())) return; | |
| 30270 | 30283 | if (!nav_ty.fnHasRuntimeBits(zcu)) return; |
| 30271 | 30284 | |
| 30272 | 30285 | try sema.ensureNavResolved(block, src, nav_index, .fully); |
| ... | ... | @@ -30349,8 +30362,9 @@ fn analyzeLoad( |
| 30349 | 30362 | const pt = sema.pt; |
| 30350 | 30363 | const zcu = pt.zcu; |
| 30351 | 30364 | const ptr_ty = sema.typeOf(ptr); |
| 30352 | const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) { | |
| 30353 | .pointer => ptr_ty.childType(zcu), | |
| 30365 | const unrestricted_ptr_ty = ptr_ty.unrestrictedType(zcu) orelse ptr_ty; | |
| 30366 | const elem_ty = switch (unrestricted_ptr_ty.zigTypeTag(zcu)) { | |
| 30367 | .pointer => unrestricted_ptr_ty.childType(zcu), | |
| 30354 | 30368 | else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}), |
| 30355 | 30369 | }; |
| 30356 | 30370 | |
| ... | ... | @@ -30379,8 +30393,8 @@ fn analyzeLoad( |
| 30379 | 30393 | break :msg msg; |
| 30380 | 30394 | }); |
| 30381 | 30395 | |
| 30382 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| | |
| 30383 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 30396 | const unrestricted_ptr = if (unrestricted_ptr_ty.toIntern() != ptr_ty.toIntern()) | |
| 30397 | try sema.unwrapRestricted(block, unrestricted_ptr_ty, ptr, ptr_src) | |
| 30384 | 30398 | else |
| 30385 | 30399 | ptr; |
| 30386 | 30400 | |
| ... | ... | @@ -31596,17 +31610,17 @@ fn wrapErrorUnionSet( |
| 31596 | 31610 | } |
| 31597 | 31611 | } |
| 31598 | 31612 | |
| 31599 | fn unwrapRestrictedPtr( | |
| 31613 | fn unwrapRestricted( | |
| 31600 | 31614 | sema: *Sema, |
| 31601 | 31615 | block: *Block, |
| 31602 | unrestricted_ptr_ty: Type, | |
| 31616 | unrestricted_ty: Type, | |
| 31603 | 31617 | ptr: Air.Inst.Ref, |
| 31604 | 31618 | ptr_src: LazySrcLoc, |
| 31605 | 31619 | ) !Air.Inst.Ref { |
| 31606 | 31620 | return block.addTyOp(if (block.wantSafety()) tag: { |
| 31607 | try sema.preparePanicId(ptr_src, .corrupt_restricted_pointer); | |
| 31621 | try sema.preparePanicId(ptr_src, .corrupt_restricted_value); | |
| 31608 | 31622 | break :tag .unwrap_restricted_safe; |
| 31609 | } else .unwrap_restricted, unrestricted_ptr_ty, ptr); | |
| 31623 | } else .unwrap_restricted, unrestricted_ty, ptr); | |
| 31610 | 31624 | } |
| 31611 | 31625 | |
| 31612 | 31626 | /// Returns the enum tag value for the active tag of a tagged union value. |
| ... | ... | @@ -34431,7 +34445,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34431 | 34445 | .@"panic.copyLenMismatch", |
| 34432 | 34446 | .@"panic.memcpyAlias", |
| 34433 | 34447 | .@"panic.noreturnReturned", |
| 34434 | .@"panic.corruptRestrictedPointer", | |
| 34448 | .@"panic.corruptRestrictedValue", | |
| 34435 | 34449 | => try pt.funcType(.{ |
| 34436 | 34450 | .param_types = &.{}, |
| 34437 | 34451 | .return_type = .noreturn_type, |
src/Sema/bitcast.zig+3-1| ... | ... | @@ -239,13 +239,13 @@ const UnpackValueBits = struct { |
| 239 | 239 | switch (ip.indexToKey(val.toIntern())) { |
| 240 | 240 | .int_type, |
| 241 | 241 | .ptr_type, |
| 242 | .restricted_ptr_type, | |
| 243 | 242 | .array_type, |
| 244 | 243 | .vector_type, |
| 245 | 244 | .opt_type, |
| 246 | 245 | .anyframe_type, |
| 247 | 246 | .error_union_type, |
| 248 | 247 | .simple_type, |
| 248 | .restricted_type, | |
| 249 | 249 | .struct_type, |
| 250 | 250 | .tuple_type, |
| 251 | 251 | .union_type, |
| ... | ... | @@ -274,6 +274,8 @@ const UnpackValueBits = struct { |
| 274 | 274 | |
| 275 | 275 | .bitpack => |bitpack| try unpack.primitive(.fromInterned(bitpack.backing_int_val)), |
| 276 | 276 | |
| 277 | .restricted_value => |restricted_value| try unpack.add(.fromInterned(restricted_value.unrestricted_value)), | |
| 278 | ||
| 277 | 279 | .aggregate => switch (ty.zigTypeTag(zcu)) { |
| 278 | 280 | .vector => { |
| 279 | 281 | const len: usize = @intCast(ty.arrayLen(zcu)); |
src/Sema/type_resolution.zig+2-1| ... | ... | @@ -84,7 +84,6 @@ 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, | |
| 88 | 87 | .anyframe_type, |
| 89 | 88 | .simple_type, |
| 90 | 89 | .opaque_type, |
| ... | ... | @@ -106,6 +105,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 106 | 105 | .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| { |
| 107 | 106 | try ensureLayoutResolvedInner(sema, .fromInterned(field_ty), orig_ty, reason); |
| 108 | 107 | }, |
| 108 | .restricted_type => |restricted_type| return ensureLayoutResolvedInner(sema, .fromInterned(restricted_type.unrestricted_type), orig_ty, reason), | |
| 109 | 109 | .struct_type, .union_type, .enum_type => { |
| 110 | 110 | try sema.declareDependency(.{ .type_layout = ty.toIntern() }); |
| 111 | 111 | try sema.addReferenceEntry(null, reason.src, .wrap(.{ .type_layout = ty.toIntern() })); |
| ... | ... | @@ -132,6 +132,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 132 | 132 | .aggregate, |
| 133 | 133 | .un, |
| 134 | 134 | .bitpack, |
| 135 | .restricted_value, | |
| 135 | 136 | // memoization, not types |
| 136 | 137 | .memoized_call, |
| 137 | 138 | => unreachable, |
src/Type.zig+167-122| ... | ... | @@ -165,7 +165,6 @@ 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, | |
| 169 | 168 | .anyframe_type, |
| 170 | 169 | => .runtime, |
| 171 | 170 | |
| ... | ... | @@ -201,6 +200,10 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { |
| 201 | 200 | cur_ty = .fromInterned(child_ty_ip); |
| 202 | 201 | continue; |
| 203 | 202 | }, |
| 203 | .restricted_type => |restricted_type| { | |
| 204 | cur_ty = .fromInterned(restricted_type.unrestricted_type); | |
| 205 | continue; | |
| 206 | }, | |
| 204 | 207 | .tuple_type => |tuple| { |
| 205 | 208 | @branchHint(.unlikely); |
| 206 | 209 | break classifyTuple(tuple.types.get(ip), tuple.values.get(ip), zcu); |
| ... | ... | @@ -254,6 +257,7 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { |
| 254 | 257 | .aggregate, |
| 255 | 258 | .un, |
| 256 | 259 | .bitpack, |
| 260 | .restricted_value, | |
| 257 | 261 | // memoization, not types |
| 258 | 262 | .memoized_call, |
| 259 | 263 | => unreachable, |
| ... | ... | @@ -374,28 +378,13 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo { |
| 374 | 378 | } |
| 375 | 379 | |
| 376 | 380 | pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType { |
| 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())) { | |
| 381 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 385 | 382 | .ptr_type => |p| p, |
| 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)) { | |
| 383 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 391 | 384 | .ptr_type => |p| p, |
| 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 | |
| 385 | else => unreachable, | |
| 386 | }, | |
| 387 | else => unreachable, | |
| 399 | 388 | }; |
| 400 | 389 | } |
| 401 | 390 | |
| ... | ... | @@ -504,10 +493,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 504 | 493 | try print(Type.fromInterned(info.child), writer, pt, ctx); |
| 505 | 494 | return; |
| 506 | 495 | }, |
| 507 | .restricted_ptr_type => { | |
| 508 | const name = ip.loadRestrictedType(ty.toIntern()).name; | |
| 509 | try writer.print("{f}", .{name.fmt(ip)}); | |
| 510 | }, | |
| 511 | 496 | .array_type => |array_type| { |
| 512 | 497 | if (array_type.sentinel == .none) { |
| 513 | 498 | try writer.print("[{d}]", .{array_type.len}); |
| ... | ... | @@ -607,6 +592,10 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 607 | 592 | |
| 608 | 593 | .generic_poison => unreachable, |
| 609 | 594 | }, |
| 595 | .restricted_type => { | |
| 596 | const name = ip.loadRestrictedType(ty.toIntern()).name; | |
| 597 | try writer.print("{f}", .{name.fmt(ip)}); | |
| 598 | }, | |
| 610 | 599 | .struct_type => { |
| 611 | 600 | const name = ip.loadStructType(ty.toIntern()).name; |
| 612 | 601 | try writer.print("{f}", .{name.fmt(ip)}); |
| ... | ... | @@ -708,6 +697,7 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 708 | 697 | .aggregate, |
| 709 | 698 | .un, |
| 710 | 699 | .bitpack, |
| 700 | .restricted_value, | |
| 711 | 701 | // memoization, not types |
| 712 | 702 | .memoized_call, |
| 713 | 703 | => unreachable, |
| ... | ... | @@ -767,13 +757,13 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { |
| 767 | 757 | .vector_type, |
| 768 | 758 | => true, |
| 769 | 759 | |
| 770 | .restricted_ptr_type, | |
| 771 | 760 | .error_union_type, |
| 772 | 761 | .error_set_type, |
| 773 | 762 | .inferred_error_set_type, |
| 774 | 763 | .tuple_type, |
| 775 | 764 | .opaque_type, |
| 776 | 765 | .anyframe_type, |
| 766 | .restricted_type, | |
| 777 | 767 | // These are function bodies, not function pointers. |
| 778 | 768 | .func_type, |
| 779 | 769 | => false, |
| ... | ... | @@ -847,6 +837,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { |
| 847 | 837 | .aggregate, |
| 848 | 838 | .un, |
| 849 | 839 | .bitpack, |
| 840 | .restricted_value, | |
| 850 | 841 | // memoization, not types |
| 851 | 842 | .memoized_call, |
| 852 | 843 | => unreachable, |
| ... | ... | @@ -898,10 +889,7 @@ pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool { |
| 898 | 889 | |
| 899 | 890 | /// Like `hasRuntimeBits`, but also returns `true` for runtime functions. |
| 900 | 891 | pub fn isRuntimeFnOrHasRuntimeBits(ty: Type, zcu: *const Zcu) bool { |
| 901 | switch (ty.zigTypeTag(zcu)) { | |
| 902 | .@"fn" => return ty.fnHasRuntimeBits(zcu), | |
| 903 | else => return ty.hasRuntimeBits(zcu), | |
| 904 | } | |
| 892 | return if (zcu.intern_pool.isFunctionType(ty.toIntern())) ty.fnHasRuntimeBits(zcu) else ty.hasRuntimeBits(zcu); | |
| 905 | 893 | } |
| 906 | 894 | |
| 907 | 895 | /// Returns whether `ty` is NPV, meaning it is "like `noreturn`" in a sense. See doc comments on |
| ... | ... | @@ -914,13 +902,22 @@ pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool { |
| 914 | 902 | |
| 915 | 903 | /// Never returns `none`. Asserts that all necessary type resolution is already done. |
| 916 | 904 | pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment { |
| 917 | const ptr_key = ptr_ty.ptrInfo(zcu); | |
| 905 | const ip = &zcu.intern_pool; | |
| 906 | const ptr_key: InternPool.Key.PtrType = switch (ip.indexToKey(ptr_ty.toIntern())) { | |
| 907 | .ptr_type => |key| key, | |
| 908 | .opt_type => |child| ip.indexToKey(child).ptr_type, | |
| 909 | else => unreachable, | |
| 910 | }; | |
| 918 | 911 | if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment; |
| 919 | 912 | return Type.fromInterned(ptr_key.child).abiAlignment(zcu); |
| 920 | 913 | } |
| 921 | 914 | |
| 922 | 915 | pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace { |
| 923 | return ty.ptrInfo(zcu).flags.address_space; | |
| 916 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 917 | .ptr_type => |ptr_type| ptr_type.flags.address_space, | |
| 918 | .opt_type => |child| zcu.intern_pool.indexToKey(child).ptr_type.flags.address_space, | |
| 919 | else => unreachable, | |
| 920 | }; | |
| 924 | 921 | } |
| 925 | 922 | |
| 926 | 923 | /// Never returns `.none`. Asserts that the layout of `ty` is resolved. |
| ... | ... | @@ -936,7 +933,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 936 | 933 | if (int_type.bits == 0) return .@"1"; |
| 937 | 934 | return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)); |
| 938 | 935 | }, |
| 939 | .ptr_type, .restricted_ptr_type, .anyframe_type => ptrAbiAlignment(target), | |
| 936 | .ptr_type, .anyframe_type => ptrAbiAlignment(target), | |
| 940 | 937 | .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu), |
| 941 | 938 | .vector_type => |vector_type| { |
| 942 | 939 | if (vector_type.len == 0) return .@"1"; |
| ... | ... | @@ -1020,6 +1017,10 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 1020 | 1017 | |
| 1021 | 1018 | .generic_poison => unreachable, |
| 1022 | 1019 | }, |
| 1020 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1021 | .indirect => ptrAbiAlignment(target), | |
| 1022 | .direct => return abiAlignment(.fromInterned(restricted_type.unrestricted_type), zcu), | |
| 1023 | }, | |
| 1023 | 1024 | .tuple_type => |tuple| { |
| 1024 | 1025 | var big_align: Alignment = .@"1"; |
| 1025 | 1026 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| ... | ... | @@ -1069,6 +1070,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 1069 | 1070 | .aggregate, |
| 1070 | 1071 | .un, |
| 1071 | 1072 | .bitpack, |
| 1073 | .restricted_value, | |
| 1072 | 1074 | // memoization, not types |
| 1073 | 1075 | .memoized_call, |
| 1074 | 1076 | => unreachable, |
| ... | ... | @@ -1090,7 +1092,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1090 | 1092 | .slice => ptrAbiSize(target) * 2, |
| 1091 | 1093 | .one, .many, .c => ptrAbiSize(target), |
| 1092 | 1094 | }, |
| 1093 | .restricted_ptr_type, .anyframe_type => ptrAbiSize(target), | |
| 1095 | .anyframe_type => ptrAbiSize(target), | |
| 1094 | 1096 | .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu), |
| 1095 | 1097 | .vector_type => |vec| { |
| 1096 | 1098 | const elem_ty: Type = .fromInterned(vec.child); |
| ... | ... | @@ -1169,6 +1171,10 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1169 | 1171 | .anyopaque => unreachable, |
| 1170 | 1172 | .generic_poison => unreachable, |
| 1171 | 1173 | }, |
| 1174 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1175 | .indirect => ptrAbiSize(target), | |
| 1176 | .direct => return abiSize(.fromInterned(restricted_type.unrestricted_type), zcu), | |
| 1177 | }, | |
| 1172 | 1178 | .tuple_type => |tuple| switch (ty.classify(zcu)) { |
| 1173 | 1179 | // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with |
| 1174 | 1180 | // non-zero size. |
| ... | ... | @@ -1209,6 +1215,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1209 | 1215 | .aggregate, |
| 1210 | 1216 | .un, |
| 1211 | 1217 | .bitpack, |
| 1218 | .restricted_value, | |
| 1212 | 1219 | // memoization, not types |
| 1213 | 1220 | .memoized_call, |
| 1214 | 1221 | => unreachable, |
| ... | ... | @@ -1243,7 +1250,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1243 | 1250 | .slice => target.ptrBitWidth() * 2, |
| 1244 | 1251 | else => target.ptrBitWidth(), |
| 1245 | 1252 | }, |
| 1246 | .restricted_ptr_type, .anyframe_type => target.ptrBitWidth(), | |
| 1253 | .anyframe_type => target.ptrBitWidth(), | |
| 1247 | 1254 | .array_type => |array_type| { |
| 1248 | 1255 | const elem_ty: Type = .fromInterned(array_type.child); |
| 1249 | 1256 | const len = array_type.lenIncludingSentinel(); |
| ... | ... | @@ -1294,6 +1301,10 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1294 | 1301 | .generic_poison => unreachable, |
| 1295 | 1302 | }, |
| 1296 | 1303 | |
| 1304 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1305 | .indirect => target.ptrBitWidth(), | |
| 1306 | .direct => return bitSize(.fromInterned(restricted_type.unrestricted_type), zcu), | |
| 1307 | }, | |
| 1297 | 1308 | .struct_type => { |
| 1298 | 1309 | const struct_obj = ip.loadStructType(ty.toIntern()); |
| 1299 | 1310 | switch (struct_obj.layout) { |
| ... | ... | @@ -1335,29 +1346,27 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1335 | 1346 | .aggregate, |
| 1336 | 1347 | .un, |
| 1337 | 1348 | .bitpack, |
| 1349 | .restricted_value, | |
| 1338 | 1350 | // memoization, not types |
| 1339 | 1351 | .memoized_call, |
| 1340 | 1352 | => unreachable, |
| 1341 | 1353 | }; |
| 1342 | 1354 | } |
| 1343 | 1355 | |
| 1344 | /// Returns `null` if `ty` is not a restricted pointer. | |
| 1356 | /// Returns `null` if `ty` is not a restricted type. | |
| 1345 | 1357 | pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type { |
| 1346 | 1358 | const ip = &zcu.intern_pool; |
| 1347 | 1359 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1348 | .restricted_ptr_type => |restricted_ptr_type| return .fromInterned(restricted_ptr_type.unrestricted_ptr_type), | |
| 1360 | .restricted_type => |restricted_type| return .fromInterned(restricted_type.unrestricted_type), | |
| 1349 | 1361 | else => null, |
| 1350 | 1362 | }; |
| 1351 | 1363 | } |
| 1352 | 1364 | |
| 1353 | 1365 | const RestrictedRepr = enum { indirect, direct }; |
| 1354 | 1366 | pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr { |
| 1355 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1356 | .restricted_ptr_type => |restricted_ptr_type| restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu), | |
| 1357 | else => .direct, | |
| 1358 | }; | |
| 1367 | return restrictedReprByTrackedInst(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_type.zir_index, zcu); | |
| 1359 | 1368 | } |
| 1360 | pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr { | |
| 1369 | pub fn restrictedReprByTrackedInst(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr { | |
| 1361 | 1370 | return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) { |
| 1362 | 1371 | .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct, |
| 1363 | 1372 | .ReleaseFast, .ReleaseSmall => .direct, |
| ... | ... | @@ -1365,8 +1374,10 @@ pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *c |
| 1365 | 1374 | } |
| 1366 | 1375 | |
| 1367 | 1376 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { |
| 1368 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1369 | return ptr_info.flags.size == .one; | |
| 1377 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1378 | .ptr_type => |ptr_info| ptr_info.flags.size == .one, | |
| 1379 | else => false, | |
| 1380 | }; | |
| 1370 | 1381 | } |
| 1371 | 1382 | |
| 1372 | 1383 | /// Asserts `ty` is a pointer. |
| ... | ... | @@ -1376,27 +1387,24 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { |
| 1376 | 1387 | |
| 1377 | 1388 | /// Returns `null` if `ty` is not a pointer. |
| 1378 | 1389 | pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size { |
| 1379 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return null; | |
| 1380 | return ptr_info.flags.size; | |
| 1390 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1391 | .ptr_type => |ptr_info| ptr_info.flags.size, | |
| 1392 | else => null, | |
| 1393 | }; | |
| 1381 | 1394 | } |
| 1382 | 1395 | |
| 1383 | 1396 | pub fn isSlice(ty: Type, zcu: *const Zcu) bool { |
| 1384 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1385 | return ptr_info.flags.size == .slice; | |
| 1397 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1398 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, | |
| 1399 | else => false, | |
| 1400 | }; | |
| 1386 | 1401 | } |
| 1387 | 1402 | |
| 1388 | 1403 | pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1389 | const ip = &zcu.intern_pool; | |
| 1390 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1404 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1391 | 1405 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, |
| 1392 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1393 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1394 | }, | |
| 1395 | .opt_type => |child| opt_child: switch (zcu.intern_pool.indexToKey(child)) { | |
| 1406 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1396 | 1407 | .ptr_type => |ptr_type| !ptr_type.flags.is_allowzero and ptr_type.flags.size == .slice, |
| 1397 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1398 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1399 | }, | |
| 1400 | 1408 | else => false, |
| 1401 | 1409 | }, |
| 1402 | 1410 | else => false, |
| ... | ... | @@ -1408,8 +1416,10 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type { |
| 1408 | 1416 | } |
| 1409 | 1417 | |
| 1410 | 1418 | pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool { |
| 1411 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1412 | return ptr_info.flags.is_const; | |
| 1419 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1420 | .ptr_type => |ptr_type| ptr_type.flags.is_const, | |
| 1421 | else => false, | |
| 1422 | }; | |
| 1413 | 1423 | } |
| 1414 | 1424 | |
| 1415 | 1425 | pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| ... | ... | @@ -1417,25 +1427,25 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| 1417 | 1427 | } |
| 1418 | 1428 | |
| 1419 | 1429 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| 1420 | const ptr_info = ty.ptrInfoOrNull(ip, .{ .allow_optional = false }) orelse return false; | |
| 1421 | return ptr_info.flags.is_volatile; | |
| 1430 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1431 | .ptr_type => |ptr_type| ptr_type.flags.is_volatile, | |
| 1432 | else => false, | |
| 1433 | }; | |
| 1422 | 1434 | } |
| 1423 | 1435 | |
| 1424 | 1436 | pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool { |
| 1425 | const ip = &zcu.intern_pool; | |
| 1426 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1437 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1427 | 1438 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, |
| 1428 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1429 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1430 | }, | |
| 1431 | 1439 | .opt_type => true, |
| 1432 | 1440 | else => false, |
| 1433 | 1441 | }; |
| 1434 | 1442 | } |
| 1435 | 1443 | |
| 1436 | 1444 | pub fn isCPtr(ty: Type, zcu: *const Zcu) bool { |
| 1437 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | |
| 1438 | return ptr_info.flags.size == .c; | |
| 1445 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1446 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | |
| 1447 | else => false, | |
| 1448 | }; | |
| 1439 | 1449 | } |
| 1440 | 1450 | |
| 1441 | 1451 | pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| ... | ... | @@ -1445,16 +1455,18 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1445 | 1455 | .slice => false, |
| 1446 | 1456 | .one, .many, .c => true, |
| 1447 | 1457 | }, |
| 1448 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1449 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1458 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1459 | .indirect => true, | |
| 1460 | .direct => continue :ty ip.indexToKey(restricted_type.unrestricted_type), | |
| 1450 | 1461 | }, |
| 1451 | 1462 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { |
| 1452 | 1463 | .ptr_type => |p| switch (p.flags.size) { |
| 1453 | 1464 | .slice, .c => false, |
| 1454 | 1465 | .many, .one => !p.flags.is_allowzero, |
| 1455 | 1466 | }, |
| 1456 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1457 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1467 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1468 | .indirect => true, | |
| 1469 | .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type), | |
| 1458 | 1470 | }, |
| 1459 | 1471 | else => false, |
| 1460 | 1472 | }, |
| ... | ... | @@ -1473,17 +1485,19 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { |
| 1473 | 1485 | const ip = &zcu.intern_pool; |
| 1474 | 1486 | return ty: switch (ip.indexToKey(ty.toIntern())) { |
| 1475 | 1487 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, |
| 1476 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1477 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1478 | }, | |
| 1479 | .opt_type => |child_type| child_type == .anyerror_type or opt_child: switch (ip.indexToKey(child_type)) { | |
| 1488 | .opt_type => |opt_child_type| opt_child_type == .anyerror_type or opt_child: switch (ip.indexToKey(opt_child_type)) { | |
| 1480 | 1489 | .ptr_type => |ptr_type| ptr_type.flags.size != .c and !ptr_type.flags.is_allowzero, |
| 1481 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1482 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1483 | }, | |
| 1484 | 1490 | .error_set_type, .inferred_error_set_type => true, |
| 1491 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1492 | .indirect => true, | |
| 1493 | .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type), | |
| 1494 | }, | |
| 1485 | 1495 | else => false, |
| 1486 | 1496 | }, |
| 1497 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1498 | .indirect => false, | |
| 1499 | .direct => continue :ty ip.indexToKey(restricted_type.unrestricted_type), | |
| 1500 | }, | |
| 1487 | 1501 | else => false, |
| 1488 | 1502 | }; |
| 1489 | 1503 | } |
| ... | ... | @@ -1494,19 +1508,21 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool { |
| 1494 | 1508 | const ip = &zcu.intern_pool; |
| 1495 | 1509 | return ty: switch (ip.indexToKey(ty.toIntern())) { |
| 1496 | 1510 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, |
| 1497 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1498 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1499 | }, | |
| 1500 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { | |
| 1511 | .opt_type => |opt_child_type| opt_child: switch (ip.indexToKey(opt_child_type)) { | |
| 1501 | 1512 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1502 | 1513 | .slice, .c => false, |
| 1503 | 1514 | .many, .one => !ptr_type.flags.is_allowzero, |
| 1504 | 1515 | }, |
| 1505 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | |
| 1506 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1516 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1517 | .indirect => true, | |
| 1518 | .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type), | |
| 1507 | 1519 | }, |
| 1508 | 1520 | else => false, |
| 1509 | 1521 | }, |
| 1522 | .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) { | |
| 1523 | .indirect => false, | |
| 1524 | .direct => continue :ty ip.indexToKey(restricted_type.unrestricted_type), | |
| 1525 | }, | |
| 1510 | 1526 | else => false, |
| 1511 | 1527 | }; |
| 1512 | 1528 | } |
| ... | ... | @@ -1541,7 +1557,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1541 | 1557 | .pointer => return ty.childType(zcu), |
| 1542 | 1558 | .optional => { |
| 1543 | 1559 | const ptr_ty = ty.childType(zcu); |
| 1544 | const ptr_info = ptr_ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }).?; | |
| 1560 | const ptr_info = zcu.intern_pool.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 1545 | 1561 | assert(ptr_info.flags.size != .c); |
| 1546 | 1562 | assert(!ptr_info.flags.is_allowzero); |
| 1547 | 1563 | return .fromInterned(ptr_info.child); |
| ... | ... | @@ -1563,7 +1579,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1563 | 1579 | /// * `[*c]T` |
| 1564 | 1580 | pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1565 | 1581 | const ip = &zcu.intern_pool; |
| 1566 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1582 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1567 | 1583 | inline .array_type, .vector_type => |arr| .fromInterned(arr.child), |
| 1568 | 1584 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1569 | 1585 | .many, .slice, .c => .fromInterned(ptr_type.child), |
| ... | ... | @@ -1572,9 +1588,6 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1572 | 1588 | else => unreachable, |
| 1573 | 1589 | }, |
| 1574 | 1590 | }, |
| 1575 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1576 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1577 | }, | |
| 1578 | 1591 | else => unreachable, |
| 1579 | 1592 | }; |
| 1580 | 1593 | } |
| ... | ... | @@ -1590,16 +1603,12 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type { |
| 1590 | 1603 | /// Asserts that the type is an optional, or a C pointer. |
| 1591 | 1604 | /// For C pointers this returns the type unmodified. |
| 1592 | 1605 | pub fn optionalChild(ty: Type, zcu: *const Zcu) Type { |
| 1593 | const ip = &zcu.intern_pool; | |
| 1594 | ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1606 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1595 | 1607 | .opt_type => |child| return .fromInterned(child), |
| 1596 | 1608 | .ptr_type => |ptr_type| { |
| 1597 | 1609 | assert(ptr_type.flags.size == .c); |
| 1598 | 1610 | return ty; |
| 1599 | 1611 | }, |
| 1600 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1601 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1602 | }, | |
| 1603 | 1612 | else => unreachable, |
| 1604 | 1613 | } |
| 1605 | 1614 | } |
| ... | ... | @@ -1699,6 +1708,15 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo |
| 1699 | 1708 | }; |
| 1700 | 1709 | } |
| 1701 | 1710 | |
| 1711 | pub fn isBitpack(ty: Type, zcu: *const Zcu) bool { | |
| 1712 | const ip = &zcu.intern_pool; | |
| 1713 | return switch (ip.indexToKey(ty.toIntern())) { | |
| 1714 | .struct_type => ip.loadStructType(ty.toIntern()).layout == .@"packed", | |
| 1715 | .union_type => ip.loadUnionType(ty.toIntern()).layout == .@"packed", | |
| 1716 | else => false, | |
| 1717 | }; | |
| 1718 | } | |
| 1719 | ||
| 1702 | 1720 | pub fn bitpackBackingInt(ty: Type, zcu: *const Zcu) Type { |
| 1703 | 1721 | const ip = &zcu.intern_pool; |
| 1704 | 1722 | return switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -1728,7 +1746,7 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool { |
| 1728 | 1746 | const ip = &zcu.intern_pool; |
| 1729 | 1747 | return switch (ty.toIntern()) { |
| 1730 | 1748 | .anyerror_type, .adhoc_inferred_error_set_type => false, |
| 1731 | else => switch (ip.indexToKey(ty.toIntern())) { | |
| 1749 | else => |index| switch (ip.indexToKey(index)) { | |
| 1732 | 1750 | .error_set_type => |error_set_type| error_set_type.names.len == 0, |
| 1733 | 1751 | .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) { |
| 1734 | 1752 | .none, .anyerror_type => false, |
| ... | ... | @@ -1752,7 +1770,7 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool { |
| 1752 | 1770 | return switch (ty.toIntern()) { |
| 1753 | 1771 | .anyerror_type => true, |
| 1754 | 1772 | .adhoc_inferred_error_set_type => false, |
| 1755 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1773 | else => |index| switch (zcu.intern_pool.indexToKey(index)) { | |
| 1756 | 1774 | .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type, |
| 1757 | 1775 | else => false, |
| 1758 | 1776 | }, |
| ... | ... | @@ -1760,9 +1778,13 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool { |
| 1760 | 1778 | } |
| 1761 | 1779 | |
| 1762 | 1780 | pub fn isError(ty: Type, zcu: *const Zcu) bool { |
| 1763 | return switch (ty.zigTypeTag(zcu)) { | |
| 1764 | .error_union, .error_set => true, | |
| 1781 | return switch (ty.toIntern()) { | |
| 1782 | .anyerror_type, .adhoc_inferred_error_set_type, .anyerror_void_error_union_type => true, | |
| 1765 | 1783 | else => false, |
| 1784 | _ => |index| switch (zcu.intern_pool.indexToKey(index)) { | |
| 1785 | .error_union_type, .error_set_type => true, | |
| 1786 | else => false, | |
| 1787 | }, | |
| 1766 | 1788 | }; |
| 1767 | 1789 | } |
| 1768 | 1790 | |
| ... | ... | @@ -1782,7 +1804,7 @@ pub fn errorSetHasField( |
| 1782 | 1804 | const ip = &zcu.intern_pool; |
| 1783 | 1805 | return switch (ty.toIntern()) { |
| 1784 | 1806 | .anyerror_type => true, |
| 1785 | else => switch (ip.indexToKey(ty.toIntern())) { | |
| 1807 | else => |index| switch (ip.indexToKey(index)) { | |
| 1786 | 1808 | .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null, |
| 1787 | 1809 | .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) { |
| 1788 | 1810 | .anyerror_type => true, |
| ... | ... | @@ -1817,8 +1839,7 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 { |
| 1817 | 1839 | |
| 1818 | 1840 | /// Asserts the type is an array, pointer or vector. |
| 1819 | 1841 | pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1820 | const ip = &zcu.intern_pool; | |
| 1821 | return ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1842 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1822 | 1843 | .vector_type, |
| 1823 | 1844 | .struct_type, |
| 1824 | 1845 | .tuple_type, |
| ... | ... | @@ -1826,9 +1847,6 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1826 | 1847 | |
| 1827 | 1848 | .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1828 | 1849 | .ptr_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1829 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1830 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1831 | }, | |
| 1832 | 1850 | |
| 1833 | 1851 | else => unreachable, |
| 1834 | 1852 | }; |
| ... | ... | @@ -1867,10 +1885,27 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool { |
| 1867 | 1885 | /// Returns true for integers, enums, error sets, and packed structs/unions. |
| 1868 | 1886 | /// If this function returns true, then intInfo() can be called on the type. |
| 1869 | 1887 | pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool { |
| 1870 | return switch (ty.zigTypeTag(zcu)) { | |
| 1871 | .int, .@"enum", .error_set => true, | |
| 1872 | .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed", | |
| 1873 | else => false, | |
| 1888 | const ip = &zcu.intern_pool; | |
| 1889 | return switch (ty.toIntern()) { | |
| 1890 | .usize_type, | |
| 1891 | .isize_type, | |
| 1892 | .c_char_type, | |
| 1893 | .c_short_type, | |
| 1894 | .c_ushort_type, | |
| 1895 | .c_int_type, | |
| 1896 | .c_uint_type, | |
| 1897 | .c_long_type, | |
| 1898 | .c_ulong_type, | |
| 1899 | .c_longlong_type, | |
| 1900 | .c_ulonglong_type, | |
| 1901 | .anyerror_type, | |
| 1902 | => true, | |
| 1903 | else => switch (ip.indexToKey(ty.toIntern())) { | |
| 1904 | .int_type, .enum_type, .error_set_type => true, | |
| 1905 | .struct_type => ip.loadStructType(ty.toIntern()).layout == .@"packed", | |
| 1906 | .union_type => ip.loadUnionType(ty.toIntern()).layout == .@"packed", | |
| 1907 | else => false, | |
| 1908 | }, | |
| 1874 | 1909 | }; |
| 1875 | 1910 | } |
| 1876 | 1911 | |
| ... | ... | @@ -1914,10 +1949,10 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1914 | 1949 | return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }; |
| 1915 | 1950 | }, |
| 1916 | 1951 | |
| 1952 | .restricted_type => unreachable, | |
| 1917 | 1953 | .tuple_type => unreachable, |
| 1918 | 1954 | |
| 1919 | 1955 | .ptr_type => unreachable, |
| 1920 | .restricted_ptr_type => unreachable, | |
| 1921 | 1956 | .anyframe_type => unreachable, |
| 1922 | 1957 | .array_type => unreachable, |
| 1923 | 1958 | |
| ... | ... | @@ -1945,6 +1980,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1945 | 1980 | .aggregate, |
| 1946 | 1981 | .un, |
| 1947 | 1982 | .bitpack, |
| 1983 | .restricted_value, | |
| 1948 | 1984 | // memoization, not types |
| 1949 | 1985 | .memoized_call, |
| 1950 | 1986 | => unreachable, |
| ... | ... | @@ -2070,7 +2106,6 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool { |
| 2070 | 2106 | .c_longlong_type, |
| 2071 | 2107 | .c_ulonglong_type, |
| 2072 | 2108 | => true, |
| 2073 | ||
| 2074 | 2109 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 2075 | 2110 | .int_type => true, |
| 2076 | 2111 | else => false, |
| ... | ... | @@ -2088,7 +2123,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2088 | 2123 | assertHasLayout(ty, zcu); |
| 2089 | 2124 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2090 | 2125 | .ptr_type, |
| 2091 | .restricted_ptr_type, // number of possible values is not known until the end of compilation, so never treated as NPV/OPV | |
| 2092 | 2126 | .error_union_type, |
| 2093 | 2127 | .func_type, |
| 2094 | 2128 | .anyframe_type, |
| ... | ... | @@ -2152,6 +2186,13 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2152 | 2186 | .no_possible_value => try pt.nullValue(ty), |
| 2153 | 2187 | else => null, |
| 2154 | 2188 | }, |
| 2189 | .restricted_type => |restricted_type| if (try onePossibleValue( | |
| 2190 | .fromInterned(restricted_type.unrestricted_type), | |
| 2191 | pt, | |
| 2192 | )) |unrestricted_opv| .fromInterned(try pt.intern(.{ .restricted_value = .{ | |
| 2193 | .ty = ty.toIntern(), | |
| 2194 | .unrestricted_value = unrestricted_opv.toIntern(), | |
| 2195 | } })) else null, | |
| 2155 | 2196 | .tuple_type => |tuple| { |
| 2156 | 2197 | // Check *whether* the OPV exists first, because constructing it is a little more expensive. |
| 2157 | 2198 | if (ty.classify(zcu) != .one_possible_value) return null; |
| ... | ... | @@ -2240,6 +2281,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2240 | 2281 | .aggregate, |
| 2241 | 2282 | .un, |
| 2242 | 2283 | .bitpack, |
| 2284 | .restricted_value, | |
| 2243 | 2285 | // memoization, not types |
| 2244 | 2286 | .memoized_call, |
| 2245 | 2287 | => unreachable, |
| ... | ... | @@ -2249,7 +2291,8 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2249 | 2291 | /// Asserts that `ty` has its layout resolved. `generic_poison` will return `false`. |
| 2250 | 2292 | pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool { |
| 2251 | 2293 | if (ty.toIntern() == .generic_poison_type) return false; |
| 2252 | if (ty.zigTypeTag(zcu) == .error_union and ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type) return false; | |
| 2294 | const ip = &zcu.intern_pool; | |
| 2295 | if (ip.isErrorUnionType(ty.toIntern()) and ip.errorUnionPayload(ty.toIntern()) == .generic_poison_type) return false; | |
| 2253 | 2296 | return switch (ty.classify(zcu)) { |
| 2254 | 2297 | .no_possible_value, .one_possible_value, .runtime => false, |
| 2255 | 2298 | .partially_comptime, .fully_comptime => true, |
| ... | ... | @@ -2257,7 +2300,7 @@ pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool { |
| 2257 | 2300 | } |
| 2258 | 2301 | |
| 2259 | 2302 | pub fn isVector(ty: Type, zcu: *const Zcu) bool { |
| 2260 | return ty.zigTypeTag(zcu) == .vector; | |
| 2303 | return zcu.intern_pool.isVectorType(ty.toIntern()); | |
| 2261 | 2304 | } |
| 2262 | 2305 | |
| 2263 | 2306 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. |
| ... | ... | @@ -2673,7 +2716,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc { |
| 2673 | 2716 | const ip = &zcu.intern_pool; |
| 2674 | 2717 | return .{ |
| 2675 | 2718 | .base_node_inst = switch (ip.indexToKey(ty.toIntern())) { |
| 2676 | .restricted_ptr_type => |restricted_ptr_type| restricted_ptr_type.zir_index, | |
| 2719 | .restricted_type => |restricted_type| restricted_type.zir_index, | |
| 2677 | 2720 | .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) { |
| 2678 | 2721 | .declared => |d| d.zir_index, |
| 2679 | 2722 | .reified => |r| r.zir_index, |
| ... | ... | @@ -2898,7 +2941,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) |
| 2898 | 2941 | pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2899 | 2942 | const zcu = pt.zcu; |
| 2900 | 2943 | const ip = &zcu.intern_pool; |
| 2901 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; | |
| 2944 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 2902 | 2945 | const elem_ty: Type = switch (ptr_info.flags.size) { |
| 2903 | 2946 | .slice, .many, .c => .fromInterned(ptr_info.child), |
| 2904 | 2947 | .one => switch (ip.indexToKey(ptr_info.child)) { |
| ... | ... | @@ -2952,7 +2995,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error |
| 2952 | 2995 | pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2953 | 2996 | const zcu = pt.zcu; |
| 2954 | 2997 | const ip = &zcu.intern_pool; |
| 2955 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; | |
| 2998 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | |
| 2956 | 2999 | assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c); |
| 2957 | 3000 | const aggregate_ty: Type = .fromInterned(ptr_info.child); |
| 2958 | 3001 | aggregate_ty.assertHasLayout(zcu); |
| ... | ... | @@ -3080,7 +3123,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3080 | 3123 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { |
| 3081 | 3124 | .tuple_type, .union_type => field_ty.abiAlignment(zcu), |
| 3082 | 3125 | .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu), |
| 3083 | .ptr_type, .restricted_ptr_type => ptrAbiAlignment(zcu.getTarget()), | |
| 3126 | .ptr_type => ptrAbiAlignment(zcu.getTarget()), | |
| 3084 | 3127 | else => unreachable, |
| 3085 | 3128 | }, |
| 3086 | 3129 | else => |a| a, |
| ... | ... | @@ -3109,7 +3152,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3109 | 3152 | |
| 3110 | 3153 | pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString { |
| 3111 | 3154 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3112 | .restricted_ptr_type => ip.loadRestrictedType(ty.toIntern()).name, | |
| 3155 | .restricted_type => ip.loadRestrictedType(ty.toIntern()).name, | |
| 3113 | 3156 | .struct_type => ip.loadStructType(ty.toIntern()).name, |
| 3114 | 3157 | .union_type => ip.loadUnionType(ty.toIntern()).name, |
| 3115 | 3158 | .enum_type => ip.loadEnumType(ty.toIntern()).name, |
| ... | ... | @@ -3317,7 +3360,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3317 | 3360 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 3318 | 3361 | .int_type, |
| 3319 | 3362 | .ptr_type, |
| 3320 | .restricted_ptr_type, | |
| 3321 | 3363 | .anyframe_type, |
| 3322 | 3364 | .simple_type, |
| 3323 | 3365 | .opaque_type, |
| ... | ... | @@ -3337,6 +3379,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3337 | 3379 | .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| { |
| 3338 | 3380 | assertHasLayout(.fromInterned(field_ty), zcu); |
| 3339 | 3381 | }, |
| 3382 | .restricted_type => |restricted_type| assertHasLayout(.fromInterned(restricted_type.unrestricted_type), zcu), | |
| 3340 | 3383 | .struct_type => { |
| 3341 | 3384 | assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout); |
| 3342 | 3385 | zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() })); |
| ... | ... | @@ -3351,6 +3394,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3351 | 3394 | }, |
| 3352 | 3395 | |
| 3353 | 3396 | // values, not types |
| 3397 | .undef, | |
| 3354 | 3398 | .simple_value, |
| 3355 | 3399 | .@"extern", |
| 3356 | 3400 | .func, |
| ... | ... | @@ -3366,7 +3410,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3366 | 3410 | .aggregate, |
| 3367 | 3411 | .un, |
| 3368 | 3412 | .bitpack, |
| 3369 | .undef, | |
| 3413 | .restricted_value, | |
| 3370 | 3414 | // memoization, not types |
| 3371 | 3415 | .memoized_call, |
| 3372 | 3416 | => unreachable, |
| ... | ... | @@ -3419,13 +3463,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3419 | 3463 | .undef, |
| 3420 | 3464 | .inferred_error_set_type, |
| 3421 | 3465 | .error_set_type, |
| 3466 | .restricted_type, | |
| 3422 | 3467 | .struct_type, |
| 3423 | 3468 | .union_type, |
| 3424 | 3469 | .opaque_type, |
| 3425 | 3470 | .enum_type, |
| 3426 | 3471 | .simple_type, |
| 3427 | 3472 | .int_type, |
| 3428 | .restricted_ptr_type, | |
| 3429 | 3473 | => {}, |
| 3430 | 3474 | |
| 3431 | 3475 | // values, not types |
| ... | ... | @@ -3444,6 +3488,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3444 | 3488 | .aggregate, |
| 3445 | 3489 | .un, |
| 3446 | 3490 | .bitpack, |
| 3491 | .restricted_value, | |
| 3447 | 3492 | // memoization, not types |
| 3448 | 3493 | .memoized_call, |
| 3449 | 3494 | => unreachable, |
src/Zcu.zig+8-7| ... | ... | @@ -501,7 +501,7 @@ pub const BuiltinDecl = enum { |
| 501 | 501 | @"panic.copyLenMismatch", |
| 502 | 502 | @"panic.memcpyAlias", |
| 503 | 503 | @"panic.noreturnReturned", |
| 504 | @"panic.corruptRestrictedPointer", | |
| 504 | @"panic.corruptRestrictedValue", | |
| 505 | 505 | |
| 506 | 506 | VaList, |
| 507 | 507 | |
| ... | ... | @@ -589,7 +589,7 @@ pub const BuiltinDecl = enum { |
| 589 | 589 | .@"panic.copyLenMismatch", |
| 590 | 590 | .@"panic.memcpyAlias", |
| 591 | 591 | .@"panic.noreturnReturned", |
| 592 | .@"panic.corruptRestrictedPointer", | |
| 592 | .@"panic.corruptRestrictedValue", | |
| 593 | 593 | => .func, |
| 594 | 594 | }; |
| 595 | 595 | } |
| ... | ... | @@ -663,7 +663,7 @@ pub const SimplePanicId = enum { |
| 663 | 663 | copy_len_mismatch, |
| 664 | 664 | memcpy_alias, |
| 665 | 665 | noreturn_returned, |
| 666 | corrupt_restricted_pointer, | |
| 666 | corrupt_restricted_value, | |
| 667 | 667 | |
| 668 | 668 | pub fn toBuiltin(id: SimplePanicId) BuiltinDecl { |
| 669 | 669 | return switch (id) { |
| ... | ... | @@ -687,7 +687,7 @@ pub const SimplePanicId = enum { |
| 687 | 687 | .copy_len_mismatch => .@"panic.copyLenMismatch", |
| 688 | 688 | .memcpy_alias => .@"panic.memcpyAlias", |
| 689 | 689 | .noreturn_returned => .@"panic.noreturnReturned", |
| 690 | .corrupt_restricted_pointer => .@"panic.corruptRestrictedPointer", | |
| 690 | .corrupt_restricted_value => .@"panic.corruptRestrictedValue", | |
| 691 | 691 | // zig fmt: on |
| 692 | 692 | }; |
| 693 | 693 | } |
| ... | ... | @@ -2748,12 +2748,13 @@ pub const LazySrcLoc = struct { |
| 2748 | 2748 | .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node, |
| 2749 | 2749 | .extended => switch (inst.data.extended.opcode) { |
| 2750 | 2750 | .struct_decl => zir.getStructDecl(zir_inst).src_node, |
| 2751 | .union_decl => zir.getUnionDecl(zir_inst).src_node, | |
| 2752 | 2751 | .enum_decl => zir.getEnumDecl(zir_inst).src_node, |
| 2752 | .union_decl => zir.getUnionDecl(zir_inst).src_node, | |
| 2753 | 2753 | .opaque_decl => zir.getOpaqueDecl(zir_inst).src_node, |
| 2754 | .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node, | |
| 2754 | .reify_restricted => zir.extraData(Zir.Inst.ReifyRestricted, inst.data.extended.operand).data.node, | |
| 2755 | 2755 | .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node, |
| 2756 | 2756 | .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node, |
| 2757 | .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node, | |
| 2757 | 2758 | else => unreachable, |
| 2758 | 2759 | }, |
| 2759 | 2760 | else => unreachable, |
| ... | ... | @@ -4000,7 +4001,7 @@ pub const Feature = enum { |
| 4000 | 4001 | |
| 4001 | 4002 | pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool { |
| 4002 | 4003 | const backend = target_util.zigBackend(&zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm); |
| 4003 | return target_util.backendSupportsFeature(backend, feature); | |
| 4004 | return target_util.backendSupportsFeature(backend, zcu.comp.config.incremental, feature); | |
| 4004 | 4005 | } |
| 4005 | 4006 | |
| 4006 | 4007 | pub const AtomicPtrAlignmentError = error{ |
src/codegen.zig+89-89| ... | ... | @@ -232,15 +232,26 @@ const LazySymbolStructure = struct { |
| 232 | 232 | operation: Operation, |
| 233 | 233 | |
| 234 | 234 | pub const Operation = enum { |
| 235 | ptr_inc, | |
| 235 | end_ptr_inc, | |
| 236 | 236 | |
| 237 | pub fn apply(operation: Operation, slice: []u8, endian: std.builtin.Endian) void { | |
| 237 | pub fn apply(operation: Operation, slice: []u8, target_opts: struct { | |
| 238 | ptr_bit_width: u16, | |
| 239 | endian: std.builtin.Endian, | |
| 240 | }) void { | |
| 238 | 241 | switch (operation) { |
| 239 | .ptr_inc => switch (slice.len) { | |
| 242 | .end_ptr_inc => switch (target_opts.ptr_bit_width) { | |
| 240 | 243 | else => unreachable, |
| 241 | 2 => std.mem.writeInt(u16, slice[0..2], std.mem.readInt(u16, slice[0..2], endian) + 1, endian), | |
| 242 | 4 => std.mem.writeInt(u32, slice[0..4], std.mem.readInt(u32, slice[0..4], endian) + 1, endian), | |
| 243 | 8 => std.mem.writeInt(u64, slice[0..8], std.mem.readInt(u64, slice[0..8], endian) + 1, endian), | |
| 244 | inline 16, 32, 64 => |ptr_bit_width| { | |
| 245 | const ptr_size = @divExact(ptr_bit_width, 8); | |
| 246 | const TargetPtrInt = @Int(.unsigned, ptr_bit_width); | |
| 247 | const end_slice = slice[slice.len - ptr_size ..][0..ptr_size]; | |
| 248 | std.mem.writeInt( | |
| 249 | TargetPtrInt, | |
| 250 | end_slice, | |
| 251 | std.mem.readInt(TargetPtrInt, end_slice, target_opts.endian) + 1, | |
| 252 | target_opts.endian, | |
| 253 | ); | |
| 254 | }, | |
| 244 | 255 | }, |
| 245 | 256 | } |
| 246 | 257 | } |
| ... | ... | @@ -279,14 +290,14 @@ pub fn getLazySymbolInfo( |
| 279 | 290 | .structure => .{}, |
| 280 | 291 | .attributes => .{ .required_alignment = .@"1" }, |
| 281 | 292 | }, |
| 282 | .restricted_ptr_type => |restricted_ptr_type| switch (kind) { | |
| 293 | .restricted_type => |restricted_type| switch (kind) { | |
| 283 | 294 | .structure => .{}, |
| 284 | 295 | .attributes => { |
| 285 | const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key); | |
| 286 | const unrestricted_ptr_ty: Type = | |
| 287 | .fromInterned(restricted_ptr_type.unrestricted_ptr_type); | |
| 288 | return .{ .required_alignment = restricted_ptr_ty.abiAlignment(zcu) | |
| 289 | .maxStrict(unrestricted_ptr_ty.abiAlignment(zcu)) }; | |
| 296 | const restricted_ty: Type = .fromInterned(lazy_sym.key); | |
| 297 | const unrestricted_ty: Type = | |
| 298 | .fromInterned(restricted_type.unrestricted_type); | |
| 299 | return .{ .required_alignment = restricted_ty.abiAlignment(zcu) | |
| 300 | .maxStrict(unrestricted_ty.abiAlignment(zcu)) }; | |
| 290 | 301 | }, |
| 291 | 302 | }, |
| 292 | 303 | }, |
| ... | ... | @@ -298,31 +309,32 @@ pub fn getLazySymbolInfo( |
| 298 | 309 | }, |
| 299 | 310 | _ => switch (ip.indexToKey(lazy_sym.key)) { |
| 300 | 311 | else => unreachable, |
| 301 | .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) { | |
| 302 | else => unreachable, | |
| 303 | .restricted_ptr_type => |restricted_ptr_type| switch (kind) { | |
| 304 | .structure => .{ .parent = .{ .kind = .const_data, .key = ptr.ty }, .modify = .{ | |
| 305 | .lazy_sym = .{ .kind = .deferred_const_data, .key = ptr.ty }, | |
| 306 | .operation = .ptr_inc, | |
| 307 | } }, | |
| 308 | .attributes => { | |
| 309 | const unrestricted_ptr_ty: Type = | |
| 310 | .fromInterned(restricted_ptr_type.unrestricted_ptr_type); | |
| 311 | return .{ | |
| 312 | .required_alignment = unrestricted_ptr_ty.abiAlignment(zcu), | |
| 313 | .size = unrestricted_ptr_ty.abiSize(zcu), | |
| 314 | }; | |
| 315 | }, | |
| 312 | .restricted_value => |restricted_value| switch (kind) { | |
| 313 | .structure => .{ .parent = .{ .kind = .const_data, .key = restricted_value.ty }, .modify = .{ | |
| 314 | .lazy_sym = .{ .kind = .deferred_const_data, .key = restricted_value.ty }, | |
| 315 | .operation = .end_ptr_inc, | |
| 316 | } }, | |
| 317 | .attributes => { | |
| 318 | const unrestricted_ty: Type = .fromInterned( | |
| 319 | ip.indexToKey(restricted_value.ty).restricted_type.unrestricted_type, | |
| 320 | ); | |
| 321 | return .{ | |
| 322 | .required_alignment = unrestricted_ty.abiAlignment(zcu), | |
| 323 | .size = unrestricted_ty.abiSize(zcu), | |
| 324 | }; | |
| 316 | 325 | }, |
| 317 | 326 | }, |
| 318 | .restricted_ptr_type => switch (kind) { | |
| 327 | .restricted_type => switch (kind) { | |
| 319 | 328 | .structure => .{ .parent = .{ .kind = .const_data, .key = lazy_sym.key } }, |
| 320 | 329 | .attributes => { |
| 321 | const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key); | |
| 330 | const restricted_ty: Type = .fromInterned(lazy_sym.key); | |
| 331 | const unrestricted_ty: Type = .fromInterned( | |
| 332 | ip.indexToKey(lazy_sym.key).restricted_type.unrestricted_type, | |
| 333 | ); | |
| 322 | 334 | return .{ |
| 323 | 335 | .header = true, |
| 324 | .required_alignment = restricted_ptr_ty.abiAlignment(zcu), | |
| 325 | .size = restricted_ptr_ty.abiSize(zcu), | |
| 336 | .required_alignment = restricted_ty.abiAlignment(zcu), | |
| 337 | .size = unrestricted_ty.abiAlignment(zcu).forward(restricted_ty.abiSize(zcu)), | |
| 326 | 338 | }; |
| 327 | 339 | }, |
| 328 | 340 | }, |
| ... | ... | @@ -367,7 +379,7 @@ pub fn generateLazySymbol( |
| 367 | 379 | } |
| 368 | 380 | return; |
| 369 | 381 | }, |
| 370 | .restricted_ptr_type => return, | |
| 382 | .restricted_type => return, | |
| 371 | 383 | else => {}, |
| 372 | 384 | }, |
| 373 | 385 | .deferred_const_data => switch (lazy_sym.key) { |
| ... | ... | @@ -392,25 +404,10 @@ pub fn generateLazySymbol( |
| 392 | 404 | return; |
| 393 | 405 | }, |
| 394 | 406 | _ => switch (ip.indexToKey(lazy_sym.key)) { |
| 395 | .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) { | |
| 396 | .restricted_ptr_type => |restricted_ptr_type| return lowerPtr( | |
| 397 | bin_file, | |
| 398 | pt, | |
| 399 | src_loc, | |
| 400 | try ip.getCoerced( | |
| 401 | comp.gpa, | |
| 402 | comp.io, | |
| 403 | pt.tid, | |
| 404 | lazy_sym.key, | |
| 405 | restricted_ptr_type.unrestricted_ptr_type, | |
| 406 | ), | |
| 407 | w, | |
| 408 | reloc_parent, | |
| 409 | 0, | |
| 410 | ), | |
| 411 | else => {}, | |
| 412 | }, | |
| 413 | .restricted_ptr_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)), | |
| 407 | .restricted_value => |restricted_value| return generateSymbol(bin_file, pt, src_loc, .fromInterned( | |
| 408 | restricted_value.unrestricted_value, | |
| 409 | ), w, reloc_parent), | |
| 410 | .restricted_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)), | |
| 414 | 411 | else => {}, |
| 415 | 412 | }, |
| 416 | 413 | else => {}, |
| ... | ... | @@ -463,13 +460,13 @@ pub fn generateSymbol( |
| 463 | 460 | switch (ip.indexToKey(val.toIntern())) { |
| 464 | 461 | .int_type, |
| 465 | 462 | .ptr_type, |
| 466 | .restricted_ptr_type, | |
| 467 | 463 | .array_type, |
| 468 | 464 | .vector_type, |
| 469 | 465 | .opt_type, |
| 470 | 466 | .anyframe_type, |
| 471 | 467 | .error_union_type, |
| 472 | 468 | .simple_type, |
| 469 | .restricted_type, | |
| 473 | 470 | .struct_type, |
| 474 | 471 | .tuple_type, |
| 475 | 472 | .union_type, |
| ... | ... | @@ -576,10 +573,7 @@ pub fn generateSymbol( |
| 576 | 573 | 128 => try w.writeInt(u128, @bitCast(f128_val), endian), |
| 577 | 574 | }, |
| 578 | 575 | }, |
| 579 | .ptr => switch (ty.restrictedRepr(zcu)) { | |
| 580 | .indirect => try lowerLazySymbolRef(bin_file, pt, .{ .kind = .deferred_const_data, .key = val.toIntern() }, w, reloc_parent, 0), | |
| 581 | .direct => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0), | |
| 582 | }, | |
| 576 | .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0), | |
| 583 | 577 | .slice => |slice| { |
| 584 | 578 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent); |
| 585 | 579 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent); |
| ... | ... | @@ -788,6 +782,10 @@ pub fn generateSymbol( |
| 788 | 782 | } |
| 789 | 783 | }, |
| 790 | 784 | .bitpack => |bitpack| try generateSymbol(bin_file, pt, src_loc, .fromInterned(bitpack.backing_int_val), w, reloc_parent), |
| 785 | .restricted_value => |restricted_value| switch (ty.restrictedRepr(zcu)) { | |
| 786 | .indirect => try lowerLazySymbolRef(bin_file, pt, .{ .kind = .deferred_const_data, .key = val.toIntern() }, w, reloc_parent, 0), | |
| 787 | .direct => try generateSymbol(bin_file, pt, src_loc, .fromInterned(restricted_value.unrestricted_value), w, reloc_parent), | |
| 788 | }, | |
| 791 | 789 | .memoized_call => unreachable, |
| 792 | 790 | } |
| 793 | 791 | } |
| ... | ... | @@ -1185,55 +1183,57 @@ const LowerResult = union(enum) { |
| 1185 | 1183 | lea_lazy_sym: link.File.LazySymbol, |
| 1186 | 1184 | }; |
| 1187 | 1185 | |
| 1188 | pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult { | |
| 1186 | pub fn lowerValue(pt: Zcu.PerThread, start_val: Value, target: *const std.Target) Allocator.Error!LowerResult { | |
| 1189 | 1187 | const zcu = pt.zcu; |
| 1190 | 1188 | const ip = &zcu.intern_pool; |
| 1191 | const ty = val.typeOf(zcu); | |
| 1189 | const start_ty = start_val.typeOf(zcu); | |
| 1190 | ||
| 1191 | log.debug("lowerValue(@as({f}, {f}))", .{ start_ty.fmt(pt), start_val.fmtValue(pt) }); | |
| 1192 | 1192 | |
| 1193 | log.debug("lowerValue(@as({f}, {f}))", .{ ty.fmt(pt), val.fmtValue(pt) }); | |
| 1193 | if (start_val.isUndef(zcu)) return .undef; | |
| 1194 | 1194 | |
| 1195 | if (val.isUndef(zcu)) return .undef; | |
| 1195 | const ty, const val: Value = if (start_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (start_ty.restrictedRepr(zcu)) { | |
| 1196 | .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = start_val.toIntern() } }, | |
| 1197 | .direct => .{ unrestricted_ty, .fromInterned(ip.indexToKey(start_val.toIntern()).restricted_value.unrestricted_value) }, | |
| 1198 | } else .{ start_ty, start_val }; | |
| 1196 | 1199 | |
| 1197 | 1200 | switch (ty.zigTypeTag(zcu)) { |
| 1198 | 1201 | .void => return .none, |
| 1199 | 1202 | .bool => return .{ .immediate = @intFromBool(val.toBool()) }, |
| 1200 | 1203 | .pointer => switch (ty.ptrSize(zcu)) { |
| 1201 | 1204 | .slice => {}, |
| 1202 | .one, .many, .c => switch (ty.restrictedRepr(zcu)) { | |
| 1203 | .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = val.toIntern() } }, | |
| 1204 | .direct => { | |
| 1205 | const ptr = ip.indexToKey(val.toIntern()).ptr; | |
| 1206 | if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset }; | |
| 1207 | if (ptr.byte_offset == 0) switch (ptr.base_addr) { | |
| 1208 | .int => unreachable, // handled above | |
| 1209 | ||
| 1210 | .nav => |nav_index| { | |
| 1211 | const nav = ip.getNav(nav_index); | |
| 1212 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); | |
| 1213 | if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) { | |
| 1214 | return .{ .lea_nav = nav_index }; | |
| 1215 | } else { | |
| 1216 | // Create the 0xaa bit pattern... | |
| 1217 | const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3); | |
| 1218 | // ...but align the pointer | |
| 1219 | const alignment = zcu.navAlignment(nav_index); | |
| 1220 | return .{ .immediate = alignment.forward(undef_ptr_bits) }; | |
| 1221 | } | |
| 1222 | }, | |
| 1223 | ||
| 1224 | .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) { | |
| 1225 | return .{ .lea_uav = uav }; | |
| 1205 | .one, .many, .c => { | |
| 1206 | const ptr = ip.indexToKey(val.toIntern()).ptr; | |
| 1207 | if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset }; | |
| 1208 | if (ptr.byte_offset == 0) switch (ptr.base_addr) { | |
| 1209 | .int => unreachable, // handled above | |
| 1210 | ||
| 1211 | .nav => |nav_index| { | |
| 1212 | const nav = ip.getNav(nav_index); | |
| 1213 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); | |
| 1214 | if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) { | |
| 1215 | return .{ .lea_nav = nav_index }; | |
| 1226 | 1216 | } else { |
| 1227 | 1217 | // Create the 0xaa bit pattern... |
| 1228 | 1218 | const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3); |
| 1229 | 1219 | // ...but align the pointer |
| 1230 | const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); | |
| 1220 | const alignment = zcu.navAlignment(nav_index); | |
| 1231 | 1221 | return .{ .immediate = alignment.forward(undef_ptr_bits) }; |
| 1232 | }, | |
| 1222 | } | |
| 1223 | }, | |
| 1233 | 1224 | |
| 1234 | else => {}, | |
| 1235 | }; | |
| 1236 | }, | |
| 1225 | .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) { | |
| 1226 | return .{ .lea_uav = uav }; | |
| 1227 | } else { | |
| 1228 | // Create the 0xaa bit pattern... | |
| 1229 | const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3); | |
| 1230 | // ...but align the pointer | |
| 1231 | const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); | |
| 1232 | return .{ .immediate = alignment.forward(undef_ptr_bits) }; | |
| 1233 | }, | |
| 1234 | ||
| 1235 | else => {}, | |
| 1236 | }; | |
| 1237 | 1237 | }, |
| 1238 | 1238 | }, |
| 1239 | 1239 | .int => { |
src/codegen/c.zig+99-77| ... | ... | @@ -767,7 +767,7 @@ pub const DeclGen = struct { |
| 767 | 767 | // somewhere and we should let the C compiler tell us about it. |
| 768 | 768 | const elem_ty = ptr_ty.childType(zcu); |
| 769 | 769 | const need_cast = elem_ty.toIntern() != nav_ty.toIntern() and |
| 770 | elem_ty.zigTypeTag(zcu) != .@"fn" or nav_ty.zigTypeTag(zcu) != .@"fn"; | |
| 770 | !ip.isFunctionType(elem_ty.toIntern()) or !ip.isFunctionType(nav_ty.toIntern()); | |
| 771 | 771 | if (need_cast) { |
| 772 | 772 | try w.writeAll("(("); |
| 773 | 773 | try dg.renderType(w, ptr_ty); |
| ... | ... | @@ -919,13 +919,13 @@ pub const DeclGen = struct { |
| 919 | 919 | // types, not values |
| 920 | 920 | .int_type, |
| 921 | 921 | .ptr_type, |
| 922 | .restricted_ptr_type, | |
| 923 | 922 | .array_type, |
| 924 | 923 | .vector_type, |
| 925 | 924 | .opt_type, |
| 926 | 925 | .anyframe_type, |
| 927 | 926 | .error_union_type, |
| 928 | 927 | .simple_type, |
| 928 | .restricted_type, | |
| 929 | 929 | .struct_type, |
| 930 | 930 | .tuple_type, |
| 931 | 931 | .union_type, |
| ... | ... | @@ -1078,24 +1078,11 @@ pub const DeclGen = struct { |
| 1078 | 1078 | try dg.renderValue(w, .fromInterned(slice.len), initializer_type); |
| 1079 | 1079 | try w.writeByte('}'); |
| 1080 | 1080 | }, |
| 1081 | .ptr => switch (ty.restrictedRepr(zcu)) { | |
| 1082 | .indirect => { | |
| 1083 | try dg.need_restricted.ensureUnusedCapacity(zcu.gpa, 2); | |
| 1084 | dg.need_restricted.putAssumeCapacity(ty.toIntern(), {}); | |
| 1085 | dg.need_restricted.putAssumeCapacity(val.toIntern(), {}); | |
| 1086 | ||
| 1087 | const restricted_ty_name = ty.containerTypeName(ip).toSlice(ip); | |
| 1088 | try w.print("&zig_restricted_{f}__{d}[zig_restricted_index_{f}__{d}]", .{ | |
| 1089 | fmtIdentUnsolo(restricted_ty_name), ty.toIntern(), | |
| 1090 | fmtIdentUnsolo(restricted_ty_name), val.toIntern(), | |
| 1091 | }); | |
| 1092 | }, | |
| 1093 | .direct => { | |
| 1094 | const derivation = try val.pointerDerivation(dg.arena, pt, null); | |
| 1095 | try w.writeByte('('); | |
| 1096 | try dg.renderPointer(w, derivation, location); | |
| 1097 | try w.writeByte(')'); | |
| 1098 | }, | |
| 1081 | .ptr => { | |
| 1082 | const derivation = try val.pointerDerivation(dg.arena, pt, null); | |
| 1083 | try w.writeByte('('); | |
| 1084 | try dg.renderPointer(w, derivation, location); | |
| 1085 | try w.writeByte(')'); | |
| 1099 | 1086 | }, |
| 1100 | 1087 | .opt => |opt| switch (CType.classifyOptional(ty, zcu)) { |
| 1101 | 1088 | .npv_payload => unreachable, // opv optional |
| ... | ... | @@ -1319,13 +1306,28 @@ pub const DeclGen = struct { |
| 1319 | 1306 | if (loaded_union.layout == .auto) try w.writeByte('}'); |
| 1320 | 1307 | } |
| 1321 | 1308 | }, |
| 1309 | .restricted_value => |restricted_value| switch (ty.restrictedRepr(zcu)) { | |
| 1310 | .indirect => { | |
| 1311 | const loaded_restricted = ip.loadRestrictedType(ty.toIntern()); | |
| 1312 | // Explicitly add the restricted decl dependency on the unrestricted type | |
| 1313 | _ = try CType.lower(.fromInterned(loaded_restricted.unrestricted_type), &dg.ctype_deps, dg.arena, zcu); | |
| 1314 | try dg.need_restricted.put(zcu.gpa, val.toIntern(), {}); | |
| 1315 | ||
| 1316 | const restricted_ty_name = loaded_restricted.name.toSlice(ip); | |
| 1317 | try w.print("&zig_restricted_{f}__{d}[zig_restricted_index_{f}__{d}]", .{ | |
| 1318 | fmtIdentUnsolo(restricted_ty_name), ty.toIntern(), | |
| 1319 | fmtIdentUnsolo(restricted_ty_name), val.toIntern(), | |
| 1320 | }); | |
| 1321 | }, | |
| 1322 | .direct => try dg.renderValue(w, .fromInterned(restricted_value.unrestricted_value), initializer_type), | |
| 1323 | }, | |
| 1322 | 1324 | } |
| 1323 | 1325 | } |
| 1324 | 1326 | |
| 1325 | 1327 | fn renderUndefValue( |
| 1326 | 1328 | dg: *DeclGen, |
| 1327 | 1329 | w: *Writer, |
| 1328 | ty: Type, | |
| 1330 | start_ty: Type, | |
| 1329 | 1331 | location: ValueRenderLocation, |
| 1330 | 1332 | ) Error!void { |
| 1331 | 1333 | const pt = dg.pt; |
| ... | ... | @@ -1343,7 +1345,8 @@ pub const DeclGen = struct { |
| 1343 | 1345 | .ReleaseFast, .ReleaseSmall => false, |
| 1344 | 1346 | }; |
| 1345 | 1347 | |
| 1346 | switch (ty.toIntern()) { | |
| 1348 | var ty = start_ty; | |
| 1349 | ty: switch (start_ty.toIntern()) { | |
| 1347 | 1350 | .c_longdouble_type, |
| 1348 | 1351 | .f16_type, |
| 1349 | 1352 | .f32_type, |
| ... | ... | @@ -1371,7 +1374,7 @@ pub const DeclGen = struct { |
| 1371 | 1374 | return w.writeByte(')'); |
| 1372 | 1375 | }, |
| 1373 | 1376 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), |
| 1374 | else => ty: switch (ip.indexToKey(ty.toIntern())) { | |
| 1377 | else => ty_key: switch (ip.indexToKey(ty.toIntern())) { | |
| 1375 | 1378 | .simple_type, // anyerror, c_char (etc), usize, isize |
| 1376 | 1379 | .int_type, |
| 1377 | 1380 | .enum_type, |
| ... | ... | @@ -1442,9 +1445,6 @@ pub const DeclGen = struct { |
| 1442 | 1445 | try w.writeByte('}'); |
| 1443 | 1446 | }, |
| 1444 | 1447 | }, |
| 1445 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | |
| 1446 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | |
| 1447 | }, | |
| 1448 | 1448 | .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) { |
| 1449 | 1449 | .npv_payload => unreachable, // opv optional |
| 1450 | 1450 | |
| ... | ... | @@ -1475,6 +1475,16 @@ pub const DeclGen = struct { |
| 1475 | 1475 | try w.writeAll(" }"); |
| 1476 | 1476 | }, |
| 1477 | 1477 | }, |
| 1478 | .restricted_type => |restricted_type| switch (ty.restrictedRepr(zcu)) { | |
| 1479 | .indirect => continue :ty_key .{ .ptr_type = .{ | |
| 1480 | .child = restricted_type.unrestricted_type, | |
| 1481 | .flags = .{ .is_const = true }, | |
| 1482 | } }, | |
| 1483 | .direct => { | |
| 1484 | ty = .fromInterned(restricted_type.unrestricted_type); | |
| 1485 | continue :ty restricted_type.unrestricted_type; | |
| 1486 | }, | |
| 1487 | }, | |
| 1478 | 1488 | .struct_type => { |
| 1479 | 1489 | const loaded_struct = ip.loadStructType(ty.toIntern()); |
| 1480 | 1490 | switch (loaded_struct.layout) { |
| ... | ... | @@ -1628,6 +1638,7 @@ pub const DeclGen = struct { |
| 1628 | 1638 | .aggregate, |
| 1629 | 1639 | .un, |
| 1630 | 1640 | .bitpack, |
| 1641 | .restricted_value, | |
| 1631 | 1642 | .memoized_call, |
| 1632 | 1643 | => unreachable, // values, not types |
| 1633 | 1644 | }, |
| ... | ... | @@ -2106,9 +2117,9 @@ pub fn genRestricted( |
| 2106 | 2117 | const zcu = pt.zcu; |
| 2107 | 2118 | const ip = &zcu.intern_pool; |
| 2108 | 2119 | for (need_restricted.keys(), need_restricted.values()) |restricted_ty, *restricted_vals| { |
| 2109 | const unrestricted_ptr_type = ip.indexToKey(restricted_ty).restricted_ptr_type.unrestricted_ptr_type; | |
| 2110 | const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_ptr_type), &dg.ctype_deps, dg.arena, zcu); | |
| 2111 | const restricted_ty_name = Type.fromInterned(restricted_ty).containerTypeName(ip).toSlice(ip); | |
| 2120 | const unrestricted_type = ip.indexToKey(restricted_ty).restricted_type.unrestricted_type; | |
| 2121 | const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_type), &dg.ctype_deps, dg.arena, zcu); | |
| 2122 | const restricted_ty_name = ip.loadRestrictedType(restricted_ty).name.toSlice(ip); | |
| 2112 | 2123 | try w.print( |
| 2113 | 2124 | \\#define zig_restricted_len_{f}__{d} {d}u |
| 2114 | 2125 | \\static {f}const zig_restricted_{f}__{d}[zig_restricted_len_{f}__{d}]{f} = {{ |
| ... | ... | @@ -2138,7 +2149,7 @@ pub fn genRestricted( |
| 2138 | 2149 | restricted_val, |
| 2139 | 2150 | }); |
| 2140 | 2151 | try dg.renderValue(w, .fromInterned( |
| 2141 | try ip.getCoerced(zcu.gpa, zcu.comp.io, pt.tid, restricted_val, unrestricted_ptr_type), | |
| 2152 | ip.indexToKey(restricted_val).restricted_value.unrestricted_value, | |
| 2142 | 2153 | ), .static_initializer); |
| 2143 | 2154 | try w.writeAll(",\n"); |
| 2144 | 2155 | } |
| ... | ... | @@ -3194,21 +3205,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3194 | 3205 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| 3195 | 3206 | try f.allocs.put(zcu.gpa, local.new_local, true); |
| 3196 | 3207 | |
| 3197 | switch (elem_ty.zigTypeTag(zcu)) { | |
| 3198 | .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) { | |
| 3199 | .@"packed" => { | |
| 3200 | // For packed aggregates, we zero-initialize to try and work around a design flaw | |
| 3201 | // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore` | |
| 3202 | // for details. | |
| 3203 | const w = &f.code.writer; | |
| 3204 | try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local}); | |
| 3205 | try f.renderType(w, elem_ty); | |
| 3206 | try w.writeAll("));"); | |
| 3207 | try f.newline(); | |
| 3208 | }, | |
| 3209 | .auto, .@"extern" => {}, | |
| 3210 | }, | |
| 3211 | else => {}, | |
| 3208 | if (elem_ty.isBitpack(zcu)) { | |
| 3209 | // For packed aggregates, we zero-initialize to try and work around a design flaw | |
| 3210 | // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore` | |
| 3211 | // for details. | |
| 3212 | const w = &f.code.writer; | |
| 3213 | try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local}); | |
| 3214 | try f.renderType(w, elem_ty); | |
| 3215 | try w.writeAll("));"); | |
| 3216 | try f.newline(); | |
| 3212 | 3217 | } |
| 3213 | 3218 | |
| 3214 | 3219 | return .{ .local_ref = local.new_local }; |
| ... | ... | @@ -3228,21 +3233,15 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3228 | 3233 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| 3229 | 3234 | try f.allocs.put(zcu.gpa, local.new_local, true); |
| 3230 | 3235 | |
| 3231 | switch (elem_ty.zigTypeTag(zcu)) { | |
| 3232 | .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) { | |
| 3233 | .@"packed" => { | |
| 3234 | // For packed aggregates, we zero-initialize to try and work around a design flaw | |
| 3235 | // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore` | |
| 3236 | // for details. | |
| 3237 | const w = &f.code.writer; | |
| 3238 | try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local}); | |
| 3239 | try f.renderType(w, elem_ty); | |
| 3240 | try w.writeAll("));"); | |
| 3241 | try f.newline(); | |
| 3242 | }, | |
| 3243 | .auto, .@"extern" => {}, | |
| 3244 | }, | |
| 3245 | else => {}, | |
| 3236 | if (elem_ty.isBitpack(zcu)) { | |
| 3237 | // For packed aggregates, we zero-initialize to try and work around a design flaw | |
| 3238 | // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore` | |
| 3239 | // for details. | |
| 3240 | const w = &f.code.writer; | |
| 3241 | try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local}); | |
| 3242 | try f.renderType(w, elem_ty); | |
| 3243 | try w.writeAll("));"); | |
| 3244 | try f.newline(); | |
| 3246 | 3245 | } |
| 3247 | 3246 | |
| 3248 | 3247 | return .{ .local_ref = local.new_local }; |
| ... | ... | @@ -5639,6 +5638,7 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue |
| 5639 | 5638 | try reap(f, inst, &.{ty_op.operand}); |
| 5640 | 5639 | |
| 5641 | 5640 | const w = &f.code.writer; |
| 5641 | // Implicitly adds the restricted decl dependency on the unrestricted type | |
| 5642 | 5642 | const local = try f.allocLocal(inst, unrestricted_ty); |
| 5643 | 5643 | |
| 5644 | 5644 | switch (restricted_ty.restrictedRepr(zcu)) { |
| ... | ... | @@ -5647,8 +5647,13 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue |
| 5647 | 5647 | const target = &f.dg.mod.resolved_target.result; |
| 5648 | 5648 | const ptr_bits = target.ptrBitWidth(); |
| 5649 | 5649 | |
| 5650 | const int_from_ptr = try f.allocLocal(inst, .usize); | |
| 5651 | try f.writeCValue(w, int_from_ptr, .other); | |
| 5650 | try f.dg.need_restricted.put(zcu.gpa, restricted_ty.toIntern(), {}); | |
| 5651 | const unrestricted_size = unrestricted_ty.abiSize(zcu); | |
| 5652 | assert(unrestricted_size > 0); | |
| 5653 | const restricted_ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip); | |
| 5654 | ||
| 5655 | const ptr_diff = try f.allocLocal(inst, .usize); | |
| 5656 | try f.writeCValue(w, ptr_diff, .other); | |
| 5652 | 5657 | try w.print(" = zig_subw_u{d}(({f})", .{ |
| 5653 | 5658 | ptr_bits, |
| 5654 | 5659 | CType.fmtTypeName(.{ .int = .uintptr_t }, zcu), |
| ... | ... | @@ -5656,29 +5661,46 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue |
| 5656 | 5661 | try f.writeCValue(w, operand, .other); |
| 5657 | 5662 | try w.print(", ({f})zig_restricted_{f}__{d}, {f});", .{ |
| 5658 | 5663 | CType.fmtTypeName(.{ .int = .uintptr_t }, zcu), |
| 5659 | fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)), | |
| 5664 | fmtIdentUnsolo(restricted_ty_name), | |
| 5660 | 5665 | restricted_ty.toIntern(), |
| 5661 | 5666 | fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower), |
| 5662 | 5667 | }); |
| 5663 | 5668 | try f.newline(); |
| 5664 | 5669 | |
| 5665 | const rotate_amount = std.math.log2_int(u16, @divExact(ptr_bits, 8)); | |
| 5666 | try w.print("if ((zig_shr_u{d}(", .{ptr_bits}); | |
| 5667 | try f.writeCValue(w, int_from_ptr, .other); | |
| 5668 | try w.print(", {f}) | zig_shlw_u{d}(", .{ | |
| 5669 | fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower), | |
| 5670 | ptr_bits, | |
| 5671 | }); | |
| 5672 | try f.writeCValue(w, int_from_ptr, .other); | |
| 5673 | try w.print(", {f}, {f})) >= zig_restricted_len_{f}__{d}) {{", .{ | |
| 5674 | fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower), | |
| 5675 | fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower), | |
| 5676 | fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)), | |
| 5670 | try w.writeAll("if ("); | |
| 5671 | if (unrestricted_size == 1) { | |
| 5672 | try f.writeCValue(w, ptr_diff, .other); | |
| 5673 | } else if (std.math.isPowerOfTwo(unrestricted_size)) { | |
| 5674 | const rotate_amount = std.math.log2_int(u64, unrestricted_size); | |
| 5675 | try w.print("(zig_shr_u{d}(", .{ptr_bits}); | |
| 5676 | try f.writeCValue(w, ptr_diff, .other); | |
| 5677 | try w.print(", {f}) | zig_shlw_u{d}(", .{ | |
| 5678 | fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower), | |
| 5679 | ptr_bits, | |
| 5680 | }); | |
| 5681 | try f.writeCValue(w, ptr_diff, .other); | |
| 5682 | try w.print(", {f}, {f}))", .{ | |
| 5683 | fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower), | |
| 5684 | fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower), | |
| 5685 | }); | |
| 5686 | } else { | |
| 5687 | try f.writeCValue(w, ptr_diff, .other); | |
| 5688 | try w.print(" % {f} != {f} || ", .{ | |
| 5689 | fmtUnsignedIntLiteralSmall(target, .uintptr_t, unrestricted_size, false, 10, .lower), | |
| 5690 | fmtUnsignedIntLiteralSmall(target, .uintptr_t, 0, false, 10, .lower), | |
| 5691 | }); | |
| 5692 | try f.writeCValue(w, ptr_diff, .other); | |
| 5693 | try w.print(" / {f}", .{ | |
| 5694 | fmtUnsignedIntLiteralSmall(target, .uintptr_t, unrestricted_size, false, 10, .lower), | |
| 5695 | }); | |
| 5696 | } | |
| 5697 | try w.print(" >= zig_restricted_len_{f}__{d}) {{", .{ | |
| 5698 | fmtIdentUnsolo(restricted_ty_name), | |
| 5677 | 5699 | restricted_ty.toIntern(), |
| 5678 | 5700 | }); |
| 5679 | 5701 | f.indent(); |
| 5680 | 5702 | try f.newline(); |
| 5681 | try f.writePanic(.corrupt_restricted_pointer, w); | |
| 5703 | try f.writePanic(.corrupt_restricted_value, w); | |
| 5682 | 5704 | try f.outdent(); |
| 5683 | 5705 | try w.writeByte('}'); |
| 5684 | 5706 | try f.newline(); |
| ... | ... | @@ -6484,7 +6506,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6484 | 6506 | try f.writeCValue(w, local, .other); |
| 6485 | 6507 | try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {}); |
| 6486 | 6508 | try w.print(" = zig_tagName_{f}__{d}(", .{ |
| 6487 | fmtIdentUnsolo(enum_ty.containerTypeName(ip).toSlice(ip)), | |
| 6509 | fmtIdentUnsolo(ip.loadEnumType(enum_ty.toIntern()).name.toSlice(ip)), | |
| 6488 | 6510 | @intFromEnum(enum_ty.toIntern()), |
| 6489 | 6511 | }); |
| 6490 | 6512 | try f.writeCValue(w, operand, .other); |
src/codegen/c/type.zig+30-25| ... | ... | @@ -239,7 +239,20 @@ pub const CType = union(enum) { |
| 239 | 239 | ) Allocator.Error!CType { |
| 240 | 240 | const gpa = zcu.comp.gpa; |
| 241 | 241 | const ip = &zcu.intern_pool; |
| 242 | var cur_ty = start_ty; | |
| 242 | var cur_ty: Type = if (start_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (start_ty.restrictedRepr(zcu)) { | |
| 243 | .indirect => { | |
| 244 | const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu); | |
| 245 | const unrestricted_cty_buf = try arena.create(CType); | |
| 246 | unrestricted_cty_buf.* = unrestricted_cty; | |
| 247 | return .{ .pointer = .{ | |
| 248 | .@"const" = true, | |
| 249 | .@"volatile" = false, | |
| 250 | .elem_ty = unrestricted_cty_buf, | |
| 251 | .nonstring = unrestricted_cty.isStringElem(), | |
| 252 | } }; | |
| 253 | }, | |
| 254 | .direct => unrestricted_ty, | |
| 255 | } else start_ty; | |
| 243 | 256 | while (true) { |
| 244 | 257 | switch (cur_ty.zigTypeTag(zcu)) { |
| 245 | 258 | .type, |
| ... | ... | @@ -284,20 +297,6 @@ pub const CType = union(enum) { |
| 284 | 297 | |
| 285 | 298 | .pointer => { |
| 286 | 299 | const ptr = cur_ty.ptrInfo(zcu); |
| 287 | if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) { | |
| 288 | .indirect => { | |
| 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 | .direct => {}, | |
| 300 | }; | |
| 301 | 300 | switch (ptr.flags.size) { |
| 302 | 301 | .slice => { |
| 303 | 302 | try deps.addType(gpa, cur_ty, allow_incomplete); |
| ... | ... | @@ -305,7 +304,7 @@ pub const CType = union(enum) { |
| 305 | 304 | }, |
| 306 | 305 | .one, .many, .c => { |
| 307 | 306 | const elem_ty: Type = .fromInterned(ptr.child); |
| 308 | const is_fn_ptr = elem_ty.zigTypeTag(zcu) == .@"fn"; | |
| 307 | const is_fn_ptr = ip.isFunctionType(elem_ty.toIntern()); | |
| 309 | 308 | const elem_cty: CType = elem_cty: { |
| 310 | 309 | if (ptr.packed_offset.host_size > 0 and ptr.flags.vector_index == .none) { |
| 311 | 310 | switch (classifyBitInt(.unsigned, ptr.packed_offset.host_size * 8, zcu)) { |
| ... | ... | @@ -876,6 +875,10 @@ pub const CType = union(enum) { |
| 876 | 875 | const ty = ctx.ty; |
| 877 | 876 | const zcu = ctx.zcu; |
| 878 | 877 | const ip = &zcu.intern_pool; |
| 878 | if (ip.isRestrictedType(ty.toIntern())) { | |
| 879 | const name = ip.loadRestrictedType(ty.toIntern()).name.toSlice(ip); | |
| 880 | return w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); | |
| 881 | } | |
| 879 | 882 | switch (ty.zigTypeTag(zcu)) { |
| 880 | 883 | .frame => unreachable, |
| 881 | 884 | .@"anyframe" => unreachable, |
| ... | ... | @@ -926,10 +929,7 @@ pub const CType = union(enum) { |
| 926 | 929 | .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}), |
| 927 | 930 | .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}), |
| 928 | 931 | |
| 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)) { | |
| 932 | .pointer => switch (ty.ptrSize(zcu)) { | |
| 933 | 933 | .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 934 | 934 | .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 935 | 935 | }, |
| ... | ... | @@ -971,6 +971,10 @@ pub const CType = union(enum) { |
| 971 | 971 | fmtZigType(ty.childType(zcu), zcu), |
| 972 | 972 | }), |
| 973 | 973 | |
| 974 | .@"enum" => { | |
| 975 | const name = ip.loadEnumType(ty.toIntern()).name.toSlice(ip); | |
| 976 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); | |
| 977 | }, | |
| 974 | 978 | .@"struct" => if (ty.isTuple(zcu)) { |
| 975 | 979 | const len = ty.structFieldCount(zcu); |
| 976 | 980 | try w.print("tuple_{d}", .{len}); |
| ... | ... | @@ -979,17 +983,17 @@ pub const CType = union(enum) { |
| 979 | 983 | try w.print("_{f}", .{fmtZigType(field_ty, zcu)}); |
| 980 | 984 | } |
| 981 | 985 | } else { |
| 982 | const name = ty.containerTypeName(ip).toSlice(ip); | |
| 986 | const name = ip.loadStructType(ty.toIntern()).name.toSlice(ip); | |
| 983 | 987 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); |
| 984 | 988 | }, |
| 985 | 989 | .@"opaque" => if (ty.toIntern() == .anyopaque_type) { |
| 986 | 990 | try w.writeAll("anyopaque"); |
| 987 | 991 | } else { |
| 988 | const name = ty.containerTypeName(ip).toSlice(ip); | |
| 992 | const name = ip.loadOpaqueType(ty.toIntern()).name.toSlice(ip); | |
| 989 | 993 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); |
| 990 | 994 | }, |
| 991 | .@"union", .@"enum" => { | |
| 992 | const name = ty.containerTypeName(ip).toSlice(ip); | |
| 995 | .@"union" => { | |
| 996 | const name = ip.loadUnionType(ty.toIntern()).name.toSlice(ip); | |
| 993 | 997 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); |
| 994 | 998 | }, |
| 995 | 999 | } |
| ... | ... | @@ -1002,7 +1006,6 @@ pub const CType = union(enum) { |
| 1002 | 1006 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1003 | 1007 | .int_type, |
| 1004 | 1008 | .ptr_type, |
| 1005 | .restricted_ptr_type, | |
| 1006 | 1009 | .anyframe_type, |
| 1007 | 1010 | .simple_type, |
| 1008 | 1011 | .opaque_type, |
| ... | ... | @@ -1010,6 +1013,7 @@ pub const CType = union(enum) { |
| 1010 | 1013 | .inferred_error_set_type, |
| 1011 | 1014 | => true, |
| 1012 | 1015 | |
| 1016 | .restricted_type, | |
| 1013 | 1017 | .struct_type, |
| 1014 | 1018 | .union_type, |
| 1015 | 1019 | .enum_type, |
| ... | ... | @@ -1045,6 +1049,7 @@ pub const CType = union(enum) { |
| 1045 | 1049 | .aggregate, |
| 1046 | 1050 | .un, |
| 1047 | 1051 | .bitpack, |
| 1052 | .restricted_value, | |
| 1048 | 1053 | // memoization, not types |
| 1049 | 1054 | .memoized_call, |
| 1050 | 1055 | => unreachable, |
src/codegen/llvm.zig+93-87| ... | ... | @@ -708,16 +708,17 @@ pub const Object = struct { |
| 708 | 708 | rd.* = undefined; |
| 709 | 709 | } |
| 710 | 710 | }; |
| 711 | pub fn getRestrictedDecls(o: *Object, ty: Type) Allocator.Error!*RestrictedDecls { | |
| 712 | const gop = try o.restricted_map.getOrPut(o.gpa, ty.toIntern()); | |
| 711 | pub fn getRestrictedDecls(o: *Object, restricted_ty: Type) Allocator.Error!*RestrictedDecls { | |
| 712 | const gop = try o.restricted_map.getOrPut(o.gpa, restricted_ty.toIntern()); | |
| 713 | 713 | if (gop.found_existing) return gop.value_ptr; |
| 714 | 714 | errdefer _ = o.restricted_map.pop().?; |
| 715 | 715 | |
| 716 | const target = o.zcu.getTarget(); | |
| 717 | const ip = &o.zcu.intern_pool; | |
| 718 | const ptr_align = Type.ptrAbiAlignment(target).toLlvm(); | |
| 716 | const zcu = o.zcu; | |
| 717 | const target = zcu.getTarget(); | |
| 718 | const ip = &zcu.intern_pool; | |
| 719 | const unrestricted_ty = restricted_ty.unrestrictedType(zcu).?; | |
| 719 | 720 | |
| 720 | const ty_name = ty.containerTypeName(ip).toSlice(ip); | |
| 721 | const ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip); | |
| 721 | 722 | gop.value_ptr.* = .{ |
| 722 | 723 | .len = try o.builder.addVariable( |
| 723 | 724 | try o.builder.strtabStringFmt("{s}.len", .{ty_name}), |
| ... | ... | @@ -733,11 +734,11 @@ pub const Object = struct { |
| 733 | 734 | }; |
| 734 | 735 | gop.value_ptr.len.setLinkage(.private, &o.builder); |
| 735 | 736 | gop.value_ptr.len.setMutability(.constant, &o.builder); |
| 736 | gop.value_ptr.len.setAlignment(ptr_align, &o.builder); | |
| 737 | gop.value_ptr.len.setAlignment(Type.ptrAbiAlignment(target).toLlvm(), &o.builder); | |
| 737 | 738 | gop.value_ptr.len.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 738 | 739 | gop.value_ptr.array.setLinkage(.private, &o.builder); |
| 739 | 740 | gop.value_ptr.array.setMutability(.constant, &o.builder); |
| 740 | gop.value_ptr.array.setAlignment(ptr_align, &o.builder); | |
| 741 | gop.value_ptr.array.setAlignment(unrestricted_ty.abiAlignment(zcu).toLlvm(), &o.builder); | |
| 741 | 742 | // Setting unnamed_addr here would reduce safety, and the module emitting the safety checks may not be the same module |
| 742 | 743 | // that defined the restricted type. In any case, llvm will add unnamed_addr itself if no safety checks end up being emitted. |
| 743 | 744 | gop.value_ptr.array.setUnnamedAddr(.default, &o.builder); |
| ... | ... | @@ -750,10 +751,13 @@ pub const Object = struct { |
| 750 | 751 | try o.builder.intConst(restricted_decls.len.typeOf(&o.builder), len), |
| 751 | 752 | &o.builder, |
| 752 | 753 | ); |
| 753 | try restricted_decls.array.setInitializer(try o.builder.arrayConst( | |
| 754 | try o.builder.arrayType(len, .ptr), | |
| 755 | restricted_decls.values.values(), | |
| 756 | ), &o.builder); | |
| 754 | try restricted_decls.array.setInitializer(switch (len) { | |
| 755 | 0 => try o.builder.structConst(try o.builder.structType(.normal, &.{}), &.{}), | |
| 756 | else => try o.builder.arrayConst( | |
| 757 | try o.builder.arrayType(len, restricted_decls.values.values()[0].typeOf(&o.builder)), | |
| 758 | restricted_decls.values.values(), | |
| 759 | ), | |
| 760 | }, &o.builder); | |
| 757 | 761 | } |
| 758 | 762 | } |
| 759 | 763 | |
| ... | ... | @@ -2023,7 +2027,7 @@ pub const Object = struct { |
| 2023 | 2027 | fn lowerDebugType( |
| 2024 | 2028 | o: *Object, |
| 2025 | 2029 | pt: Zcu.PerThread, |
| 2026 | ty: Type, | |
| 2030 | start_ty: Type, | |
| 2027 | 2031 | ty_fwd_ref: Builder.Metadata, |
| 2028 | 2032 | ) Allocator.Error!Builder.Metadata { |
| 2029 | 2033 | assert(!o.builder.strip); |
| ... | ... | @@ -2033,7 +2037,7 @@ pub const Object = struct { |
| 2033 | 2037 | const target = zcu.getTarget(); |
| 2034 | 2038 | const ip = &zcu.intern_pool; |
| 2035 | 2039 | |
| 2036 | const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)}); | |
| 2040 | const name = try o.builder.metadataStringFmt("{f}", .{start_ty.fmt(pt)}); | |
| 2037 | 2041 | |
| 2038 | 2042 | // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up. |
| 2039 | 2043 | // For instance, `bool` is considered to be 8 bits, and `u60` is considered to be 64 bits. |
| ... | ... | @@ -2044,6 +2048,24 @@ pub const Object = struct { |
| 2044 | 2048 | // handling for variants at all, and will never print fields in them, so I opted not to use |
| 2045 | 2049 | // them for now. |
| 2046 | 2050 | |
| 2051 | const ty = if (start_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (start_ty.restrictedRepr(zcu)) { | |
| 2052 | .indirect => { | |
| 2053 | const ptr_size = Type.ptrAbiSize(zcu.getTarget()); | |
| 2054 | const ptr_align = Type.ptrAbiAlignment(zcu.getTarget()); | |
| 2055 | return o.builder.debugPointerType( | |
| 2056 | name, | |
| 2057 | null, // file | |
| 2058 | o.debug_compile_unit.unwrap().?, // scope | |
| 2059 | 0, // line | |
| 2060 | try o.getDebugType(pt, unrestricted_ty), | |
| 2061 | ptr_size * 8, | |
| 2062 | ptr_align.toByteUnits().? * 8, | |
| 2063 | 0, // offset | |
| 2064 | ); | |
| 2065 | }, | |
| 2066 | .direct => unrestricted_ty, | |
| 2067 | } else start_ty; | |
| 2068 | ||
| 2047 | 2069 | switch (ty.zigTypeTag(zcu)) { |
| 2048 | 2070 | .void, |
| 2049 | 2071 | .noreturn, |
| ... | ... | @@ -2071,64 +2093,52 @@ pub const Object = struct { |
| 2071 | 2093 | .pointer => { |
| 2072 | 2094 | const ptr_size = Type.ptrAbiSize(zcu.getTarget()); |
| 2073 | 2095 | const ptr_align = Type.ptrAbiAlignment(zcu.getTarget()); |
| 2074 | switch (ty.restrictedRepr(zcu)) { | |
| 2075 | .indirect => return o.builder.debugPointerType( | |
| 2076 | name, | |
| 2096 | if (ty.isSlice(zcu)) { | |
| 2097 | const debug_ptr_type = try o.builder.debugMemberType( | |
| 2098 | try o.builder.metadataString("ptr"), | |
| 2077 | 2099 | null, // file |
| 2078 | o.debug_compile_unit.unwrap().?, // scope | |
| 2100 | ty_fwd_ref, | |
| 2079 | 2101 | 0, // line |
| 2080 | try o.getDebugType(pt, ty.unrestrictedType(zcu).?), | |
| 2102 | try o.getDebugType(pt, ty.slicePtrFieldType(zcu)), | |
| 2081 | 2103 | ptr_size * 8, |
| 2082 | 2104 | ptr_align.toByteUnits().? * 8, |
| 2083 | 2105 | 0, // offset |
| 2084 | ), | |
| 2085 | .direct => if (ty.isSlice(zcu)) { | |
| 2086 | const debug_ptr_type = try o.builder.debugMemberType( | |
| 2087 | try o.builder.metadataString("ptr"), | |
| 2088 | null, // file | |
| 2089 | ty_fwd_ref, | |
| 2090 | 0, // line | |
| 2091 | try o.getDebugType(pt, ty.slicePtrFieldType(zcu)), | |
| 2092 | ptr_size * 8, | |
| 2093 | ptr_align.toByteUnits().? * 8, | |
| 2094 | 0, // offset | |
| 2095 | ); | |
| 2106 | ); | |
| 2096 | 2107 | |
| 2097 | const debug_len_type = try o.builder.debugMemberType( | |
| 2098 | try o.builder.metadataString("len"), | |
| 2099 | null, // file | |
| 2100 | ty_fwd_ref, | |
| 2101 | 0, // line | |
| 2102 | try o.getDebugType(pt, .usize), | |
| 2103 | ptr_size * 8, | |
| 2104 | ptr_align.toByteUnits().? * 8, | |
| 2105 | ptr_size * 8, | |
| 2106 | ); | |
| 2108 | const debug_len_type = try o.builder.debugMemberType( | |
| 2109 | try o.builder.metadataString("len"), | |
| 2110 | null, // file | |
| 2111 | ty_fwd_ref, | |
| 2112 | 0, // line | |
| 2113 | try o.getDebugType(pt, .usize), | |
| 2114 | ptr_size * 8, | |
| 2115 | ptr_align.toByteUnits().? * 8, | |
| 2116 | ptr_size * 8, | |
| 2117 | ); | |
| 2107 | 2118 | |
| 2108 | return o.builder.debugStructType( | |
| 2109 | name, | |
| 2110 | null, // file | |
| 2111 | o.debug_compile_unit.unwrap().?, // scope | |
| 2112 | 0, // line | |
| 2113 | null, // underlying type | |
| 2114 | ptr_size * 2 * 8, | |
| 2115 | ptr_align.toByteUnits().? * 8, | |
| 2116 | try o.builder.metadataTuple(&.{ | |
| 2117 | debug_ptr_type, | |
| 2118 | debug_len_type, | |
| 2119 | }), | |
| 2120 | ); | |
| 2121 | } else return o.builder.debugPointerType( | |
| 2119 | return o.builder.debugStructType( | |
| 2122 | 2120 | name, |
| 2123 | 2121 | null, // file |
| 2124 | 2122 | o.debug_compile_unit.unwrap().?, // scope |
| 2125 | 2123 | 0, // line |
| 2126 | try o.getDebugType(pt, ty.childType(zcu)), | |
| 2127 | ptr_size * 8, | |
| 2124 | null, // underlying type | |
| 2125 | ptr_size * 2 * 8, | |
| 2128 | 2126 | ptr_align.toByteUnits().? * 8, |
| 2129 | 0, // offset | |
| 2130 | ), | |
| 2131 | } | |
| 2127 | try o.builder.metadataTuple(&.{ | |
| 2128 | debug_ptr_type, | |
| 2129 | debug_len_type, | |
| 2130 | }), | |
| 2131 | ); | |
| 2132 | } else return o.builder.debugPointerType( | |
| 2133 | name, | |
| 2134 | null, // file | |
| 2135 | o.debug_compile_unit.unwrap().?, // scope | |
| 2136 | 0, // line | |
| 2137 | try o.getDebugType(pt, ty.childType(zcu)), | |
| 2138 | ptr_size * 8, | |
| 2139 | ptr_align.toByteUnits().? * 8, | |
| 2140 | 0, // offset | |
| 2141 | ); | |
| 2132 | 2142 | }, |
| 2133 | 2143 | .array => return o.builder.debugArrayType( |
| 2134 | 2144 | name, |
| ... | ... | @@ -3121,7 +3131,7 @@ pub const Object = struct { |
| 3121 | 3131 | .empty_tuple, |
| 3122 | 3132 | .none, |
| 3123 | 3133 | => unreachable, |
| 3124 | else => t: switch (ip.indexToKey(t.toIntern())) { | |
| 3134 | else => switch (ip.indexToKey(t.toIntern())) { | |
| 3125 | 3135 | .int_type => |int_type| try o.builder.intType(int_type.bits), |
| 3126 | 3136 | .ptr_type => |ptr_type| type: { |
| 3127 | 3137 | const ptr_ty = try o.builder.ptrType( |
| ... | ... | @@ -3135,10 +3145,6 @@ pub const Object = struct { |
| 3135 | 3145 | }), |
| 3136 | 3146 | }; |
| 3137 | 3147 | }, |
| 3138 | .restricted_ptr_type => |restricted_ptr_type| switch (t.restrictedRepr(zcu)) { | |
| 3139 | .indirect => .ptr, | |
| 3140 | .direct => continue :t .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type }, | |
| 3141 | }, | |
| 3142 | 3148 | .array_type => |array_type| o.builder.arrayType( |
| 3143 | 3149 | array_type.lenIncludingSentinel(), |
| 3144 | 3150 | try o.lowerType(.fromInterned(array_type.child)), |
| ... | ... | @@ -3217,6 +3223,10 @@ pub const Object = struct { |
| 3217 | 3223 | return o.builder.structType(.normal, fields[0..fields_len]); |
| 3218 | 3224 | }, |
| 3219 | 3225 | .simple_type => unreachable, |
| 3226 | .restricted_type => |restricted_type| switch (t.restrictedRepr(zcu)) { | |
| 3227 | .indirect => .ptr, | |
| 3228 | .direct => try o.lowerType(.fromInterned(restricted_type.unrestricted_type)), | |
| 3229 | }, | |
| 3220 | 3230 | .struct_type => { |
| 3221 | 3231 | if (o.type_map.get(t.toIntern())) |value| return value; |
| 3222 | 3232 | |
| ... | ... | @@ -3430,6 +3440,7 @@ pub const Object = struct { |
| 3430 | 3440 | .aggregate, |
| 3431 | 3441 | .un, |
| 3432 | 3442 | .bitpack, |
| 3443 | .restricted_value, | |
| 3433 | 3444 | // memoization, not types |
| 3434 | 3445 | .memoized_call, |
| 3435 | 3446 | => unreachable, |
| ... | ... | @@ -3521,13 +3532,13 @@ pub const Object = struct { |
| 3521 | 3532 | return switch (val_key) { |
| 3522 | 3533 | .int_type, |
| 3523 | 3534 | .ptr_type, |
| 3524 | .restricted_ptr_type, | |
| 3525 | 3535 | .array_type, |
| 3526 | 3536 | .vector_type, |
| 3527 | 3537 | .opt_type, |
| 3528 | 3538 | .anyframe_type, |
| 3529 | 3539 | .error_union_type, |
| 3530 | 3540 | .simple_type, |
| 3541 | .restricted_type, | |
| 3531 | 3542 | .struct_type, |
| 3532 | 3543 | .tuple_type, |
| 3533 | 3544 | .union_type, |
| ... | ... | @@ -3622,27 +3633,7 @@ pub const Object = struct { |
| 3622 | 3633 | 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)), |
| 3623 | 3634 | else => unreachable, |
| 3624 | 3635 | }, |
| 3625 | .ptr => switch (ty.restrictedRepr(zcu)) { | |
| 3626 | .indirect => { | |
| 3627 | const restricted_decls = try o.getRestrictedDecls(ty); | |
| 3628 | const gop = try restricted_decls.values.getOrPut(o.gpa, arg_val); | |
| 3629 | if (!gop.found_existing) gop.value_ptr.* = try o.lowerValue(try ip.getCoerced( | |
| 3630 | zcu.gpa, | |
| 3631 | zcu.comp.io, | |
| 3632 | .main, // FIXME | |
| 3633 | arg_val, | |
| 3634 | ty.unrestrictedType(zcu).?.toIntern(), | |
| 3635 | )); | |
| 3636 | return o.builder.gepConst( | |
| 3637 | .inbounds, | |
| 3638 | .ptr, | |
| 3639 | restricted_decls.array.toConst(&o.builder), | |
| 3640 | null, | |
| 3641 | &.{try o.builder.intConst(.i64, gop.index)}, | |
| 3642 | ); | |
| 3643 | }, | |
| 3644 | .direct => try o.lowerPtr(arg_val, 0), | |
| 3645 | }, | |
| 3636 | .ptr => try o.lowerPtr(arg_val, 0), | |
| 3646 | 3637 | .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{ |
| 3647 | 3638 | try o.lowerValue(slice.ptr), |
| 3648 | 3639 | try o.lowerValue(slice.len), |
| ... | ... | @@ -4006,6 +3997,21 @@ pub const Object = struct { |
| 4006 | 3997 | else |
| 4007 | 3998 | union_ty, vals[0..len]); |
| 4008 | 3999 | }, |
| 4000 | .restricted_value => |restricted_value| switch (ty.restrictedRepr(zcu)) { | |
| 4001 | .indirect => { | |
| 4002 | const restricted_decls = try o.getRestrictedDecls(ty); | |
| 4003 | const gop = try restricted_decls.values.getOrPut(o.gpa, arg_val); | |
| 4004 | if (!gop.found_existing) gop.value_ptr.* = try o.lowerValue(restricted_value.unrestricted_value); | |
| 4005 | return o.builder.gepConst( | |
| 4006 | .inbounds, | |
| 4007 | gop.value_ptr.typeOf(&o.builder), | |
| 4008 | restricted_decls.array.toConst(&o.builder), | |
| 4009 | null, | |
| 4010 | &.{try o.builder.intConst(.i64, gop.index)}, | |
| 4011 | ); | |
| 4012 | }, | |
| 4013 | .direct => try o.lowerValue(restricted_value.unrestricted_value), | |
| 4014 | }, | |
| 4009 | 4015 | .memoized_call => unreachable, |
| 4010 | 4016 | }; |
| 4011 | 4017 | } |
src/codegen/llvm/FuncGen.zig+41-20| ... | ... | @@ -3266,6 +3266,8 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat |
| 3266 | 3266 | if (safety) { |
| 3267 | 3267 | const restricted_decls = try o.getRestrictedDecls(restricted_ty); |
| 3268 | 3268 | const llvm_usize_ty = restricted_decls.len.typeOf(&o.builder); |
| 3269 | const unrestricted_size = unrestricted_ty.abiSize(zcu); | |
| 3270 | assert(unrestricted_size > 0); | |
| 3269 | 3271 | const array = try o.builder.castConst(.ptrtoint, restricted_decls.array.toConst(&o.builder), llvm_usize_ty); |
| 3270 | 3272 | const ptr_diff = try fg.wip.bin( |
| 3271 | 3273 | .sub, |
| ... | ... | @@ -3273,11 +3275,6 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat |
| 3273 | 3275 | array.toValue(), |
| 3274 | 3276 | "unwrap_restricted.ptr_diff", |
| 3275 | 3277 | ); |
| 3276 | const index = try fg.wip.callIntrinsic(.normal, .none, .fshr, &.{llvm_usize_ty}, &.{ | |
| 3277 | ptr_diff, | |
| 3278 | ptr_diff, | |
| 3279 | try o.builder.intValue(llvm_usize_ty, std.math.log2_int(u64, Type.ptrAbiSize(target))), | |
| 3280 | }, "unwrap_restricted.index"); | |
| 3281 | 3278 | const len = try fg.wip.load( |
| 3282 | 3279 | .normal, |
| 3283 | 3280 | llvm_usize_ty, |
| ... | ... | @@ -3285,18 +3282,38 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat |
| 3285 | 3282 | Type.ptrAbiAlignment(target).toLlvm(), |
| 3286 | 3283 | "unwrap_restricted.len", |
| 3287 | 3284 | ); |
| 3288 | const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok"); | |
| 3289 | ||
| 3290 | const invalid_block = try fg.wip.block(1, "unwrap_restricted.invalid"); | |
| 3285 | const is_po2_unrestricted_size = std.math.isPowerOfTwo(unrestricted_size); | |
| 3286 | const check_block = if (is_po2_unrestricted_size) undefined else try fg.wip.block(1, "unwrap_restricted.check"); | |
| 3287 | const invalid_block = try fg.wip.block(if (is_po2_unrestricted_size) 1 else 2, "unwrap_restricted.invalid"); | |
| 3291 | 3288 | const valid_block = try fg.wip.block(1, "unwrap_restricted.valid"); |
| 3292 | _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none); | |
| 3293 | ||
| 3289 | if (is_po2_unrestricted_size) { | |
| 3290 | const index = if (unrestricted_size == 1) | |
| 3291 | ptr_diff | |
| 3292 | else | |
| 3293 | try fg.wip.callIntrinsic(.normal, .none, .fshr, &.{llvm_usize_ty}, &.{ | |
| 3294 | ptr_diff, | |
| 3295 | ptr_diff, | |
| 3296 | try o.builder.intValue(llvm_usize_ty, std.math.log2_int(u64, unrestricted_size)), | |
| 3297 | }, "unwrap_restricted.index"); | |
| 3298 | const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok"); | |
| 3299 | _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none); | |
| 3300 | } else { | |
| 3301 | const unrestricted_size_value = try o.builder.intValue(llvm_usize_ty, unrestricted_size); | |
| 3302 | const misalignment = try fg.wip.bin(.urem, ptr_diff, unrestricted_size_value, "unwrap_restricted.misalignment"); | |
| 3303 | const misaligned = try fg.wip.icmp(.ne, misalignment, try o.builder.intValue(llvm_usize_ty, 0), "unwrap_restricted.misaligned"); | |
| 3304 | _ = try fg.wip.brCond(misaligned, invalid_block, check_block, .none); | |
| 3305 | ||
| 3306 | fg.wip.cursor = .{ .block = check_block }; | |
| 3307 | const index = try fg.wip.bin(.@"udiv exact", ptr_diff, unrestricted_size_value, "unwrap_restricted.index"); | |
| 3308 | const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok"); | |
| 3309 | _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none); | |
| 3310 | } | |
| 3294 | 3311 | fg.wip.cursor = .{ .block = invalid_block }; |
| 3295 | try fg.buildSimplePanic(.corrupt_restricted_pointer); | |
| 3312 | try fg.buildSimplePanic(.corrupt_restricted_value); | |
| 3296 | 3313 | |
| 3297 | 3314 | fg.wip.cursor = .{ .block = valid_block }; |
| 3298 | 3315 | } |
| 3299 | return fg.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "unwrap_restricted"); | |
| 3316 | return fg.load(operand, unrestricted_ty, unrestricted_ty.abiAlignment(zcu).toLlvm(), .normal); | |
| 3300 | 3317 | }, |
| 3301 | 3318 | .direct => return operand, |
| 3302 | 3319 | } |
| ... | ... | @@ -7275,7 +7292,11 @@ pub fn buildAllocaInner( |
| 7275 | 7292 | /// This is the one source of truth for whether a type is passed around as an LLVM pointer, |
| 7276 | 7293 | /// or as an LLVM value. |
| 7277 | 7294 | pub fn isByRef(ty: Type, zcu: *const Zcu) bool { |
| 7278 | return switch (ty.zigTypeTag(zcu)) { | |
| 7295 | const unrestricted_ty = if (ty.unrestrictedType(zcu)) |unrestricted_ty| switch (ty.restrictedRepr(zcu)) { | |
| 7296 | .indirect => return false, | |
| 7297 | .direct => unrestricted_ty, | |
| 7298 | } else ty; | |
| 7299 | return switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 7279 | 7300 | .type, |
| 7280 | 7301 | .comptime_int, |
| 7281 | 7302 | .comptime_float, |
| ... | ... | @@ -7300,19 +7321,19 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool { |
| 7300 | 7321 | |
| 7301 | 7322 | .array, |
| 7302 | 7323 | .frame, |
| 7303 | => ty.hasRuntimeBits(zcu), | |
| 7324 | => unrestricted_ty.hasRuntimeBits(zcu), | |
| 7304 | 7325 | |
| 7305 | .error_union => ty.errorUnionPayload(zcu).hasRuntimeBits(zcu), | |
| 7326 | .error_union => unrestricted_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu), | |
| 7306 | 7327 | |
| 7307 | .optional => !ty.optionalReprIsPayload(zcu) and ty.optionalChild(zcu).hasRuntimeBits(zcu), | |
| 7328 | .optional => !unrestricted_ty.optionalReprIsPayload(zcu) and unrestricted_ty.optionalChild(zcu).hasRuntimeBits(zcu), | |
| 7308 | 7329 | |
| 7309 | .@"struct" => switch (ty.containerLayout(zcu)) { | |
| 7330 | .@"struct" => switch (unrestricted_ty.containerLayout(zcu)) { | |
| 7310 | 7331 | .@"packed" => false, |
| 7311 | .auto, .@"extern" => ty.hasRuntimeBits(zcu), | |
| 7332 | .auto, .@"extern" => unrestricted_ty.hasRuntimeBits(zcu), | |
| 7312 | 7333 | }, |
| 7313 | .@"union" => switch (ty.containerLayout(zcu)) { | |
| 7334 | .@"union" => switch (unrestricted_ty.containerLayout(zcu)) { | |
| 7314 | 7335 | .@"packed" => false, |
| 7315 | else => ty.hasRuntimeBits(zcu) and !ty.unionHasAllZeroBitFieldTypes(zcu), | |
| 7336 | else => unrestricted_ty.hasRuntimeBits(zcu) and !unrestricted_ty.unionHasAllZeroBitFieldTypes(zcu), | |
| 7316 | 7337 | }, |
| 7317 | 7338 | }; |
| 7318 | 7339 | } |
src/codegen/spirv/CodeGen.zig+3-2| ... | ... | @@ -774,13 +774,13 @@ 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, | |
| 778 | 777 | .array_type, |
| 779 | 778 | .vector_type, |
| 780 | 779 | .opt_type, |
| 781 | 780 | .anyframe_type, |
| 782 | 781 | .error_union_type, |
| 783 | 782 | .simple_type, |
| 783 | .restricted_type, | |
| 784 | 784 | .struct_type, |
| 785 | 785 | .tuple_type, |
| 786 | 786 | .union_type, |
| ... | ... | @@ -990,6 +990,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { |
| 990 | 990 | break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr); |
| 991 | 991 | }, |
| 992 | 992 | |
| 993 | .restricted_value => return cg.todo("implement restricted values", .{}), | |
| 993 | 994 | .memoized_call => unreachable, |
| 994 | 995 | } |
| 995 | 996 | }; |
| ... | ... | @@ -2777,7 +2778,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void { |
| 2777 | 2778 | .wrap_errunion_err => try cg.airWrapErrUnionErr(inst), |
| 2778 | 2779 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), |
| 2779 | 2780 | |
| 2780 | .unwrap_restricted => return cg.fail("TODO implement restricted pointers", .{}), | |
| 2781 | .unwrap_restricted => return cg.todo("implement restricted values", .{}), | |
| 2781 | 2782 | |
| 2782 | 2783 | .is_null => try cg.airIsNull(inst, false, .is_null), |
| 2783 | 2784 | .is_non_null => try cg.airIsNull(inst, false, .is_non_null), |
src/codegen/wasm/CodeGen.zig+2-1| ... | ... | @@ -4679,13 +4679,13 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 4679 | 4679 | switch (ip.indexToKey(val.ip_index)) { |
| 4680 | 4680 | .int_type, |
| 4681 | 4681 | .ptr_type, |
| 4682 | .restricted_ptr_type, | |
| 4683 | 4682 | .array_type, |
| 4684 | 4683 | .vector_type, |
| 4685 | 4684 | .opt_type, |
| 4686 | 4685 | .anyframe_type, |
| 4687 | 4686 | .error_union_type, |
| 4688 | 4687 | .simple_type, |
| 4688 | .restricted_type, | |
| 4689 | 4689 | .struct_type, |
| 4690 | 4690 | .tuple_type, |
| 4691 | 4691 | .union_type, |
| ... | ... | @@ -4779,6 +4779,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 4779 | 4779 | }, |
| 4780 | 4780 | .un => unreachable, // packed unions use `bitpack` |
| 4781 | 4781 | .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)), |
| 4782 | .restricted_value => return cg.fail("Wasm TODO: LowerConstant for restricted value", .{}), | |
| 4782 | 4783 | .memoized_call => unreachable, |
| 4783 | 4784 | } |
| 4784 | 4785 | } |
src/codegen/x86_64/CodeGen.zig+215-12| ... | ... | @@ -103826,14 +103826,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103826 | 103826 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 103827 | 103827 | const unrestricted_ty = ty_op.ty.toType(); |
| 103828 | 103828 | const restricted_ty = cg.typeOf(ty_op.operand); |
| 103829 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | |
| 103829 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}) ++ .{try cg.tempInit(ty_op.ty.toType(), .none)}; | |
| 103830 | 103830 | const res = res: switch (restricted_ty.restrictedRepr(zcu)) { |
| 103831 | 103831 | .indirect => { |
| 103832 | 103832 | if (zcu.comp.config.use_new_linker) switch (air_tag) { |
| 103833 | 103833 | else => unreachable, |
| 103834 | 103834 | .unwrap_restricted => {}, |
| 103835 | 103835 | .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{ |
| 103836 | .required_features = .{ .avx, .bmi2, null, null }, | |
| 103837 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 103838 | .patterns = &.{ | |
| 103839 | .{ .src = .{ .mem, .none, .none } }, | |
| 103840 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103841 | }, | |
| 103842 | .call_frame = .{ .alignment = .@"32" }, | |
| 103843 | .extra_temps = .{ | |
| 103844 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103845 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 103846 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103847 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103848 | .unused, | |
| 103849 | .unused, | |
| 103850 | .unused, | |
| 103851 | .unused, | |
| 103852 | .unused, | |
| 103853 | .unused, | |
| 103854 | .unused, | |
| 103855 | }, | |
| 103856 | .clobbers = .{ .eflags = true }, | |
| 103857 | .each = .{ .once = &.{ | |
| 103858 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103859 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103860 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103861 | .{ ._, ._rx, .ro, .tmp2p, .tmp2p, .sa(.src1, .add_log2_size), ._ }, | |
| 103862 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103863 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103864 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 103865 | } }, | |
| 103866 | }, .{ | |
| 103836 | 103867 | .required_features = .{ .avx, null, null, null }, |
| 103868 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 103837 | 103869 | .patterns = &.{ |
| 103838 | 103870 | .{ .src = .{ .mem, .none, .none } }, |
| 103839 | 103871 | .{ .src = .{ .to_gpr, .none, .none } }, |
| ... | ... | @@ -103843,7 +103875,72 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103843 | 103875 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103844 | 103876 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, |
| 103845 | 103877 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103846 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 103878 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103879 | .unused, | |
| 103880 | .unused, | |
| 103881 | .unused, | |
| 103882 | .unused, | |
| 103883 | .unused, | |
| 103884 | .unused, | |
| 103885 | .unused, | |
| 103886 | }, | |
| 103887 | .clobbers = .{ .eflags = true }, | |
| 103888 | .each = .{ .once = &.{ | |
| 103889 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103890 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103891 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103892 | .{ ._, ._r, .ro, .tmp2p, .sa(.src1, .add_log2_size), ._, ._ }, | |
| 103893 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103894 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103895 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 103896 | } }, | |
| 103897 | }, .{ | |
| 103898 | .required_features = .{ .avx, null, null, null }, | |
| 103899 | .patterns = &.{ | |
| 103900 | .{ .src = .{ .mem, .none, .none } }, | |
| 103901 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103902 | }, | |
| 103903 | .call_frame = .{ .alignment = .@"32" }, | |
| 103904 | .extra_temps = .{ | |
| 103905 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103906 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 103907 | .{ .type = .usize, .kind = .{ .reg = .rax } }, | |
| 103908 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103909 | .{ .type = .usize, .kind = .{ .reg = .rdx } }, | |
| 103910 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103911 | .unused, | |
| 103912 | .unused, | |
| 103913 | .unused, | |
| 103914 | .unused, | |
| 103915 | .unused, | |
| 103916 | }, | |
| 103917 | .clobbers = .{ .eflags = true }, | |
| 103918 | .each = .{ .once = &.{ | |
| 103919 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 103920 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 103921 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 103922 | .{ ._, ._, .mov, .tmp3d, .sa(.src1, .add_size), ._, ._ }, | |
| 103923 | .{ ._, ._, .xor, .tmp4p, .tmp4p, ._, ._ }, | |
| 103924 | .{ ._, ._, .div, .tmp3p, ._, ._, ._ }, | |
| 103925 | .{ ._, ._, .@"test", .tmp4p, .tmp4p, ._, ._ }, | |
| 103926 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | |
| 103927 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 103928 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 103929 | .{ .@"1:", ._, .call, .tmp5d, ._, ._, ._ }, | |
| 103930 | } }, | |
| 103931 | }, .{ | |
| 103932 | .required_features = .{ .sse, .bmi2, null, null }, | |
| 103933 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 103934 | .patterns = &.{ | |
| 103935 | .{ .src = .{ .mem, .none, .none } }, | |
| 103936 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103937 | }, | |
| 103938 | .call_frame = .{ .alignment = .@"16" }, | |
| 103939 | .extra_temps = .{ | |
| 103940 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103941 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 103942 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 103943 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103847 | 103944 | .unused, |
| 103848 | 103945 | .unused, |
| 103849 | 103946 | .unused, |
| ... | ... | @@ -103857,13 +103954,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103857 | 103954 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, |
| 103858 | 103955 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, |
| 103859 | 103956 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, |
| 103860 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 103957 | .{ ._, ._rx, .ro, .tmp2p, .tmp2p, .sa(.src1, .add_log2_size), ._ }, | |
| 103861 | 103958 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, |
| 103862 | 103959 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, |
| 103863 | 103960 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, |
| 103864 | 103961 | } }, |
| 103865 | 103962 | }, .{ |
| 103866 | 103963 | .required_features = .{ .sse, null, null, null }, |
| 103964 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 103867 | 103965 | .patterns = &.{ |
| 103868 | 103966 | .{ .src = .{ .mem, .none, .none } }, |
| 103869 | 103967 | .{ .src = .{ .to_gpr, .none, .none } }, |
| ... | ... | @@ -103873,7 +103971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103873 | 103971 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103874 | 103972 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, |
| 103875 | 103973 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103876 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 103974 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103877 | 103975 | .unused, |
| 103878 | 103976 | .unused, |
| 103879 | 103977 | .unused, |
| ... | ... | @@ -103887,12 +103985,48 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103887 | 103985 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, |
| 103888 | 103986 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, |
| 103889 | 103987 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, |
| 103890 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 103988 | .{ ._, ._r, .ro, .tmp2p, .sa(.src1, .add_log2_size), ._, ._ }, | |
| 103891 | 103989 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, |
| 103892 | 103990 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, |
| 103893 | 103991 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, |
| 103894 | 103992 | } }, |
| 103895 | 103993 | }, .{ |
| 103994 | .required_features = .{ .sse, null, null, null }, | |
| 103995 | .patterns = &.{ | |
| 103996 | .{ .src = .{ .mem, .none, .none } }, | |
| 103997 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 103998 | }, | |
| 103999 | .call_frame = .{ .alignment = .@"16" }, | |
| 104000 | .extra_temps = .{ | |
| 104001 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104002 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 104003 | .{ .type = .usize, .kind = .{ .reg = .rax } }, | |
| 104004 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104005 | .{ .type = .usize, .kind = .{ .reg = .rdx } }, | |
| 104006 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 104007 | .unused, | |
| 104008 | .unused, | |
| 104009 | .unused, | |
| 104010 | .unused, | |
| 104011 | .unused, | |
| 104012 | }, | |
| 104013 | .clobbers = .{ .eflags = true }, | |
| 104014 | .each = .{ .once = &.{ | |
| 104015 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 104016 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 104017 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 104018 | .{ ._, ._, .mov, .tmp3d, .sa(.src1, .add_size), ._, ._ }, | |
| 104019 | .{ ._, ._, .xor, .tmp4p, .tmp4p, ._, ._ }, | |
| 104020 | .{ ._, ._, .div, .tmp3p, ._, ._, ._ }, | |
| 104021 | .{ ._, ._, .@"test", .tmp4p, .tmp4p, ._, ._ }, | |
| 104022 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | |
| 104023 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 104024 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 104025 | .{ .@"1:", ._, .call, .tmp5d, ._, ._, ._ }, | |
| 104026 | } }, | |
| 104027 | }, .{ | |
| 104028 | .required_features = .{ .bmi2, null, null, null }, | |
| 104029 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 103896 | 104030 | .patterns = &.{ |
| 103897 | 104031 | .{ .src = .{ .mem, .none, .none } }, |
| 103898 | 104032 | .{ .src = .{ .to_gpr, .none, .none } }, |
| ... | ... | @@ -103902,7 +104036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103902 | 104036 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103903 | 104037 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, |
| 103904 | 104038 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, |
| 103905 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | |
| 104039 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 103906 | 104040 | .unused, |
| 103907 | 104041 | .unused, |
| 103908 | 104042 | .unused, |
| ... | ... | @@ -103916,11 +104050,74 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103916 | 104050 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, |
| 103917 | 104051 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, |
| 103918 | 104052 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, |
| 103919 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | |
| 104053 | .{ ._, ._rx, .ro, .tmp2p, .tmp2p, .sa(.src1, .add_log2_size), ._ }, | |
| 103920 | 104054 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, |
| 103921 | 104055 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, |
| 103922 | 104056 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, |
| 103923 | 104057 | } }, |
| 104058 | }, .{ | |
| 104059 | .src_constraints = .{ .any, .po2_any, .any }, | |
| 104060 | .patterns = &.{ | |
| 104061 | .{ .src = .{ .mem, .none, .none } }, | |
| 104062 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 104063 | }, | |
| 104064 | .call_frame = .{ .alignment = .@"8" }, | |
| 104065 | .extra_temps = .{ | |
| 104066 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104067 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 104068 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104069 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 104070 | .unused, | |
| 104071 | .unused, | |
| 104072 | .unused, | |
| 104073 | .unused, | |
| 104074 | .unused, | |
| 104075 | .unused, | |
| 104076 | .unused, | |
| 104077 | }, | |
| 104078 | .clobbers = .{ .eflags = true }, | |
| 104079 | .each = .{ .once = &.{ | |
| 104080 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 104081 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 104082 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 104083 | .{ ._, ._r, .ro, .tmp2p, .sa(.src1, .add_log2_size), ._, ._ }, | |
| 104084 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 104085 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 104086 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | |
| 104087 | } }, | |
| 104088 | }, .{ | |
| 104089 | .patterns = &.{ | |
| 104090 | .{ .src = .{ .mem, .none, .none } }, | |
| 104091 | .{ .src = .{ .to_gpr, .none, .none } }, | |
| 104092 | }, | |
| 104093 | .call_frame = .{ .alignment = .@"8" }, | |
| 104094 | .extra_temps = .{ | |
| 104095 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104096 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } }, | |
| 104097 | .{ .type = .usize, .kind = .{ .reg = .rax } }, | |
| 104098 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | |
| 104099 | .{ .type = .usize, .kind = .{ .reg = .rdx } }, | |
| 104100 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } }, | |
| 104101 | .unused, | |
| 104102 | .unused, | |
| 104103 | .unused, | |
| 104104 | .unused, | |
| 104105 | .unused, | |
| 104106 | }, | |
| 104107 | .clobbers = .{ .eflags = true }, | |
| 104108 | .each = .{ .once = &.{ | |
| 104109 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | |
| 104110 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | |
| 104111 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | |
| 104112 | .{ ._, ._, .mov, .tmp3d, .sa(.src1, .add_size), ._, ._ }, | |
| 104113 | .{ ._, ._, .xor, .tmp4p, .tmp4p, ._, ._ }, | |
| 104114 | .{ ._, ._, .div, .tmp3p, ._, ._, ._ }, | |
| 104115 | .{ ._, ._, .@"test", .tmp4p, .tmp4p, ._, ._ }, | |
| 104116 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | |
| 104117 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | |
| 104118 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | |
| 104119 | .{ .@"1:", ._, .call, .tmp5d, ._, ._, ._ }, | |
| 104120 | } }, | |
| 103924 | 104121 | } }) catch |err| switch (err) { |
| 103925 | 104122 | error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{ |
| 103926 | 104123 | air_tag, |
| ... | ... | @@ -103935,7 +104132,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103935 | 104132 | }, |
| 103936 | 104133 | .direct => ops[0], |
| 103937 | 104134 | }; |
| 103938 | try res.finish(inst, &.{ty_op.operand}, &ops, cg); | |
| 104135 | for (ops[1..]) |op| try op.die(cg); | |
| 104136 | try res.finish(inst, &.{ty_op.operand}, ops[0..1], cg); | |
| 103939 | 104137 | }, |
| 103940 | 104138 | .struct_field_ptr => { |
| 103941 | 104139 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -174190,7 +174388,12 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok |
| 174190 | 174388 | }; |
| 174191 | 174389 | |
| 174192 | 174390 | if (reg_ok) need_mem: { |
| 174193 | if (std.math.isPowerOfTwo(abi_size) and abi_size <= @as(u32, max_abi_size: switch (ty.zigTypeTag(zcu)) { | |
| 174391 | if (!std.math.isPowerOfTwo(abi_size)) break :need_mem; | |
| 174392 | const unrestricted_ty: Type = if (ty.unrestrictedType(zcu)) |unrestricted_ty| switch (ty.restrictedRepr(zcu)) { | |
| 174393 | .indirect => .usize, | |
| 174394 | .direct => unrestricted_ty, | |
| 174395 | } else ty; | |
| 174396 | if (abi_size <= @as(u32, max_abi_size: switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 174194 | 174397 | .float => switch (ty.floatBits(self.target)) { |
| 174195 | 174398 | 16, 32, 64, 128 => 16, |
| 174196 | 174399 | 80 => break :need_mem, |
| ... | ... | @@ -189139,9 +189342,9 @@ const Select = struct { |
| 189139 | 189342 | lhs: enum(u6) { |
| 189140 | 189343 | none, |
| 189141 | 189344 | ptr_size, |
| 189142 | log2_ptr_size, | |
| 189143 | 189345 | ptr_bit_size, |
| 189144 | 189346 | size, |
| 189347 | log2_size, | |
| 189145 | 189348 | src0_size, |
| 189146 | 189349 | dst0_size, |
| 189147 | 189350 | delta_size, |
| ... | ... | @@ -189178,7 +189381,6 @@ const Select = struct { |
| 189178 | 189381 | const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" }; |
| 189179 | 189382 | const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; |
| 189180 | 189383 | const sub_ptr_size: Adjust = .{ .sign = .neg, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; |
| 189181 | const add_log2_ptr_size: Adjust = .{ .sign = .pos, .lhs = .log2_ptr_size, .op = .mul, .rhs = .@"1" }; | |
| 189182 | 189384 | const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" }; |
| 189183 | 189385 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 189184 | 189386 | const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" }; |
| ... | ... | @@ -189186,6 +189388,7 @@ const Select = struct { |
| 189186 | 189388 | const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" }; |
| 189187 | 189389 | const sub_size_div_4: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"4" }; |
| 189188 | 189390 | const sub_size: Adjust = .{ .sign = .neg, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 189391 | const add_log2_size: Adjust = .{ .sign = .pos, .lhs = .log2_size, .op = .mul, .rhs = .@"1" }; | |
| 189189 | 189392 | const sub_src0_size_div_8: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .div, .rhs = .@"8" }; |
| 189190 | 189393 | const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; |
| 189191 | 189394 | const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; |
| ... | ... | @@ -190119,8 +190322,8 @@ const Select = struct { |
| 190119 | 190322 | const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) { |
| 190120 | 190323 | .none => 0, |
| 190121 | 190324 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), |
| 190122 | .log2_ptr_size => std.math.log2(@divExact(s.cg.target.ptrBitWidth(), 8)), | |
| 190123 | 190325 | .ptr_bit_size => s.cg.target.ptrBitWidth(), |
| 190326 | .log2_size => std.math.log2_int_ceil(u64, op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), | |
| 190124 | 190327 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 190125 | 190328 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 190126 | 190329 | .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)), |
src/link/C.zig+2-2| ... | ... | @@ -1385,8 +1385,8 @@ fn mergeNeededRestricted( |
| 1385 | 1385 | for (new.keys()) |restricted_key| { |
| 1386 | 1386 | const restricted_ty = switch (ip.indexToKey(restricted_key)) { |
| 1387 | 1387 | else => unreachable, |
| 1388 | .restricted_ptr_type => restricted_key, | |
| 1389 | .ptr => |ptr| ptr.ty, | |
| 1388 | .restricted_type => restricted_key, | |
| 1389 | .restricted_value => |restricted_value| restricted_value.ty, | |
| 1390 | 1390 | }; |
| 1391 | 1391 | const gop = global.getOrPutAssumeCapacity(restricted_ty); |
| 1392 | 1392 | if (!gop.found_existing) gop.value_ptr.* = .empty; |
src/link/Coff.zig+8-1| ... | ... | @@ -2173,7 +2173,14 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 2173 | 2173 | |
| 2174 | 2174 | if (structure.modify) |modification| modification.operation.apply( |
| 2175 | 2175 | coff.lazySymbolIfExists(modification.lazy_sym).?.node(coff).slice(&coff.mf), |
| 2176 | coff.targetEndian(), | |
| 2176 | .{ | |
| 2177 | .ptr_bit_width = switch (coff.optionalHeaderStandardPtr().magic) { | |
| 2178 | else => unreachable, | |
| 2179 | .PE32 => 32, | |
| 2180 | .@"PE32+" => 64, | |
| 2181 | }, | |
| 2182 | .endian = coff.targetEndian(), | |
| 2183 | }, | |
| 2177 | 2184 | ); |
| 2178 | 2185 | } |
| 2179 | 2186 |
src/link/ConstPool.zig+23-21| ... | ... | @@ -181,8 +181,9 @@ fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Inde |
| 181 | 181 | } |
| 182 | 182 | } |
| 183 | 183 | fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool { |
| 184 | if (ty.isGenericPoison()) return true; | |
| 185 | return switch (ty.zigTypeTag(zcu)) { | |
| 184 | const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty; | |
| 185 | if (unrestricted_ty.isGenericPoison()) return true; | |
| 186 | return switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 186 | 187 | .type, |
| 187 | 188 | .void, |
| 188 | 189 | .bool, |
| ... | ... | @@ -201,33 +202,34 @@ fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool { |
| 201 | 202 | .enum_literal, |
| 202 | 203 | => true, |
| 203 | 204 | |
| 204 | .array, .vector => pool.checkType(ty.childType(zcu), zcu), | |
| 205 | .optional => pool.checkType(ty.optionalChild(zcu), zcu), | |
| 206 | .error_union => pool.checkType(ty.errorUnionPayload(zcu), zcu), | |
| 205 | .array, .vector => pool.checkType(unrestricted_ty.childType(zcu), zcu), | |
| 206 | .optional => pool.checkType(unrestricted_ty.optionalChild(zcu), zcu), | |
| 207 | .error_union => pool.checkType(unrestricted_ty.errorUnionPayload(zcu), zcu), | |
| 207 | 208 | .@"fn" => { |
| 208 | 209 | const ip = &zcu.intern_pool; |
| 209 | const func = ip.indexToKey(ty.toIntern()).func_type; | |
| 210 | const func = ip.indexToKey(unrestricted_ty.toIntern()).func_type; | |
| 210 | 211 | for (func.param_types.get(ip)) |param_ty_ip| { |
| 211 | 212 | if (!pool.checkType(.fromInterned(param_ty_ip), zcu)) return false; |
| 212 | 213 | } |
| 213 | 214 | return pool.checkType(.fromInterned(func.return_type), zcu); |
| 214 | 215 | }, |
| 215 | .@"struct" => if (ty.isTuple(zcu)) { | |
| 216 | for (0..ty.structFieldCount(zcu)) |field_index| { | |
| 217 | if (!pool.checkType(ty.fieldType(field_index, zcu), zcu)) return false; | |
| 216 | .@"struct" => if (unrestricted_ty.isTuple(zcu)) { | |
| 217 | for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| { | |
| 218 | if (!pool.checkType(unrestricted_ty.fieldType(field_index, zcu), zcu)) return false; | |
| 218 | 219 | } |
| 219 | 220 | return true; |
| 220 | 221 | } else { |
| 221 | return pool.complete_containers.contains(ty.toIntern()); | |
| 222 | return pool.complete_containers.contains(unrestricted_ty.toIntern()); | |
| 222 | 223 | }, |
| 223 | 224 | .@"union", .@"enum" => { |
| 224 | return pool.complete_containers.contains(ty.toIntern()); | |
| 225 | return pool.complete_containers.contains(unrestricted_ty.toIntern()); | |
| 225 | 226 | }, |
| 226 | 227 | }; |
| 227 | 228 | } |
| 228 | 229 | fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Allocator.Error!void { |
| 229 | if (ty.isGenericPoison()) return; | |
| 230 | switch (ty.zigTypeTag(zcu)) { | |
| 230 | const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty; | |
| 231 | if (unrestricted_ty.isGenericPoison()) return; | |
| 232 | switch (unrestricted_ty.zigTypeTag(zcu)) { | |
| 231 | 233 | .type, |
| 232 | 234 | .void, |
| 233 | 235 | .bool, |
| ... | ... | @@ -246,20 +248,20 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al |
| 246 | 248 | .enum_literal, |
| 247 | 249 | => {}, |
| 248 | 250 | |
| 249 | .array, .vector => try pool.registerTypeDeps(root, ty.childType(zcu), zcu), | |
| 250 | .optional => try pool.registerTypeDeps(root, ty.optionalChild(zcu), zcu), | |
| 251 | .error_union => try pool.registerTypeDeps(root, ty.errorUnionPayload(zcu), zcu), | |
| 251 | .array, .vector => try pool.registerTypeDeps(root, unrestricted_ty.childType(zcu), zcu), | |
| 252 | .optional => try pool.registerTypeDeps(root, unrestricted_ty.optionalChild(zcu), zcu), | |
| 253 | .error_union => try pool.registerTypeDeps(root, unrestricted_ty.errorUnionPayload(zcu), zcu), | |
| 252 | 254 | .@"fn" => { |
| 253 | 255 | const ip = &zcu.intern_pool; |
| 254 | const func = ip.indexToKey(ty.toIntern()).func_type; | |
| 256 | const func = ip.indexToKey(unrestricted_ty.toIntern()).func_type; | |
| 255 | 257 | for (func.param_types.get(ip)) |param_ty_ip| { |
| 256 | 258 | try pool.registerTypeDeps(root, .fromInterned(param_ty_ip), zcu); |
| 257 | 259 | } |
| 258 | 260 | try pool.registerTypeDeps(root, .fromInterned(func.return_type), zcu); |
| 259 | 261 | }, |
| 260 | .@"struct", .@"union", .@"enum" => if (ty.isTuple(zcu)) { | |
| 261 | for (0..ty.structFieldCount(zcu)) |field_index| { | |
| 262 | try pool.registerTypeDeps(root, ty.fieldType(field_index, zcu), zcu); | |
| 262 | .@"struct", .@"union", .@"enum" => if (unrestricted_ty.isTuple(zcu)) { | |
| 263 | for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| { | |
| 264 | try pool.registerTypeDeps(root, unrestricted_ty.fieldType(field_index, zcu), zcu); | |
| 263 | 265 | } |
| 264 | 266 | } else { |
| 265 | 267 | // `ty` is a container; register the dependency. |
| ... | ... | @@ -269,7 +271,7 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al |
| 269 | 271 | try pool.container_dep_entries.ensureUnusedCapacity(gpa, 1); |
| 270 | 272 | errdefer comptime unreachable; |
| 271 | 273 | |
| 272 | const gop = pool.container_deps.getOrPutAssumeCapacity(ty.toIntern()); | |
| 274 | const gop = pool.container_deps.getOrPutAssumeCapacity(unrestricted_ty.toIntern()); | |
| 273 | 275 | const entry: ContainerDepEntry.Index = @enumFromInt(pool.container_dep_entries.items.len); |
| 274 | 276 | pool.container_dep_entries.appendAssumeCapacity(.{ |
| 275 | 277 | .next = if (gop.found_existing) gop.value_ptr.toOptional() else .none, |
src/link/Dwarf.zig+45-17| ... | ... | @@ -1176,7 +1176,7 @@ pub const Loc = union(enum) { |
| 1176 | 1176 | implicit_pointer: struct { |
| 1177 | 1177 | unit: Unit.Index, |
| 1178 | 1178 | entry: Entry.Index, |
| 1179 | offset: i65, | |
| 1179 | offset: i65 = 0, | |
| 1180 | 1180 | }, |
| 1181 | 1181 | wasm_ext: union(enum) { |
| 1182 | 1182 | local: u32, |
| ... | ... | @@ -3060,13 +3060,13 @@ 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, | |
| 3064 | 3063 | .array_type, |
| 3065 | 3064 | .vector_type, |
| 3066 | 3065 | .opt_type, |
| 3067 | 3066 | .error_union_type, |
| 3068 | 3067 | .anyframe_type, |
| 3069 | 3068 | .simple_type, |
| 3069 | .restricted_type, | |
| 3070 | 3070 | .tuple_type, |
| 3071 | 3071 | .func_type, |
| 3072 | 3072 | .error_set_type, |
| ... | ... | @@ -3128,6 +3128,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3128 | 3128 | .aggregate, |
| 3129 | 3129 | .un, |
| 3130 | 3130 | .bitpack, |
| 3131 | .restricted_value, | |
| 3131 | 3132 | => if (nav.resolved.?.@"const") .@"const" else .@"var", |
| 3132 | 3133 | |
| 3133 | 3134 | .@"extern" => unreachable, |
| ... | ... | @@ -3509,12 +3510,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3509 | 3510 | |
| 3510 | 3511 | if (value_index == .anyerror_type) return; // handled in `flush` instead |
| 3511 | 3512 | |
| 3512 | const value_ip_key = ip.indexToKey(value_index); | |
| 3513 | switch (value_ip_key) { | |
| 3513 | const value_ip_key: InternPool.Key = switch (ip.indexToKey(value_index)) { | |
| 3514 | 3514 | .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`) |
| 3515 | 3515 | .@"extern" => return, // populated by the Nav instead (`initWipNav`) |
| 3516 | else => {}, | |
| 3517 | } | |
| 3516 | .restricted_value => |restricted_value| switch (Type.restrictedRepr(.fromInterned(restricted_value.ty), zcu)) { | |
| 3517 | .indirect => .{ .restricted_value = restricted_value }, | |
| 3518 | .direct => ip.indexToKey(restricted_value.unrestricted_value), | |
| 3519 | }, | |
| 3520 | else => |key| key, | |
| 3521 | }; | |
| 3518 | 3522 | |
| 3519 | 3523 | switch (value_index) { |
| 3520 | 3524 | .generic_poison_type => log.debug("updateValue(anytype)", .{}), |
| ... | ... | @@ -3567,7 +3571,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3567 | 3571 | |
| 3568 | 3572 | const diw = &wip_nav.debug_info.writer; |
| 3569 | 3573 | var big_int_space: Value.BigIntSpace = undefined; |
| 3570 | key: switch (value_ip_key) { | |
| 3574 | switch (value_ip_key) { | |
| 3571 | 3575 | .func => unreachable, // handled above |
| 3572 | 3576 | .@"extern" => unreachable, // handled above |
| 3573 | 3577 | |
| ... | ... | @@ -3630,13 +3634,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3630 | 3634 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 3631 | 3635 | }, |
| 3632 | 3636 | }, |
| 3633 | .restricted_ptr_type => |restricted_ptr_type| switch (Type.restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu)) { | |
| 3634 | .indirect => continue :key .{ .ptr_type = .{ | |
| 3635 | .child = restricted_ptr_type.unrestricted_ptr_type, | |
| 3636 | .flags = .{ .is_const = true }, | |
| 3637 | } }, | |
| 3638 | .direct => continue :key .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type }, | |
| 3639 | }, | |
| 3640 | 3637 | .array_type => |array_type| { |
| 3641 | 3638 | const array_child_type: Type = .fromInterned(array_type.child); |
| 3642 | 3639 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); |
| ... | ... | @@ -3847,6 +3844,28 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3847 | 3844 | .anyerror => unreachable, // already did early return above |
| 3848 | 3845 | .adhoc_inferred_error_set => unreachable, |
| 3849 | 3846 | }, |
| 3847 | .restricted_type => |restricted_type| { | |
| 3848 | const repr = Type.restrictedReprByTrackedInst(restricted_type.zir_index, zcu); | |
| 3849 | try wip_nav.abbrevCode(switch (repr) { | |
| 3850 | .indirect => .ptr_type, | |
| 3851 | .direct => .alias_type, | |
| 3852 | }); | |
| 3853 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); | |
| 3854 | switch (repr) { | |
| 3855 | .indirect => { | |
| 3856 | try diw.writeByte(@intFromEnum(InternPool.Key.PtrType.AddressSpace.generic)); | |
| 3857 | try wip_nav.infoSectionOffset( | |
| 3858 | .debug_info, | |
| 3859 | wip_nav.unit, | |
| 3860 | wip_nav.entry, | |
| 3861 | @intCast(diw.end + dwarf.sectionOffsetBytes()), | |
| 3862 | ); | |
| 3863 | try wip_nav.abbrevCode(.is_const); | |
| 3864 | }, | |
| 3865 | .direct => {}, | |
| 3866 | } | |
| 3867 | try wip_nav.refType(.fromInterned(restricted_type.unrestricted_type)); | |
| 3868 | }, | |
| 3850 | 3869 | .tuple_type => |tuple_type| if (tuple_type.types.len == 0) { |
| 3851 | 3870 | try wip_nav.abbrevCode(.generated_empty_struct_type); |
| 3852 | 3871 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); |
| ... | ... | @@ -4265,7 +4284,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4265 | 4284 | if (error_set_type.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4266 | 4285 | }, |
| 4267 | 4286 | .inferred_error_set_type => |func| { |
| 4268 | try wip_nav.abbrevCode(.inferred_error_set_type); | |
| 4287 | try wip_nav.abbrevCode(.alias_type); | |
| 4269 | 4288 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); |
| 4270 | 4289 | try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) { |
| 4271 | 4290 | .none => .anyerror_type, |
| ... | ... | @@ -4648,6 +4667,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4648 | 4667 | } |
| 4649 | 4668 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4650 | 4669 | }, |
| 4670 | .restricted_value => |restricted_value| { // repr checked above | |
| 4671 | try wip_nav.abbrevCode(.location_comptime_value); | |
| 4672 | const unrestricted_unit, const unrestricted_entry = | |
| 4673 | try wip_nav.getValueEntry(.fromInterned(restricted_value.unrestricted_value)); | |
| 4674 | try wip_nav.infoExprLoc(.{ .implicit_pointer = .{ | |
| 4675 | .unit = unrestricted_unit, | |
| 4676 | .entry = unrestricted_entry, | |
| 4677 | } }); | |
| 4678 | }, | |
| 4651 | 4679 | .memoized_call => unreachable, // not a value |
| 4652 | 4680 | } |
| 4653 | 4681 | try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written()); |
| ... | ... | @@ -5209,7 +5237,7 @@ const AbbrevCode = enum { |
| 5209 | 5237 | tagged_union_default_field, |
| 5210 | 5238 | void_type, |
| 5211 | 5239 | numeric_type, |
| 5212 | inferred_error_set_type, | |
| 5240 | alias_type, | |
| 5213 | 5241 | ptr_type, |
| 5214 | 5242 | ptr_sentinel_type, |
| 5215 | 5243 | ptr_aligned_type, |
| ... | ... | @@ -5839,7 +5867,7 @@ const AbbrevCode = enum { |
| 5839 | 5867 | .{ .alignment, .udata }, |
| 5840 | 5868 | }, |
| 5841 | 5869 | }, |
| 5842 | .inferred_error_set_type = .{ | |
| 5870 | .alias_type = .{ | |
| 5843 | 5871 | .tag = .typedef, |
| 5844 | 5872 | .attrs = &.{ |
| 5845 | 5873 | .{ .name, .strp }, |
src/link/Elf2.zig+8-1| ... | ... | @@ -3349,7 +3349,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 3349 | 3349 | |
| 3350 | 3350 | if (structure.modify) |modification| modification.operation.apply( |
| 3351 | 3351 | elf.lazySymbolIfExists(modification.lazy_sym).?.node(elf).slice(&elf.mf), |
| 3352 | elf.targetEndian(), | |
| 3352 | .{ | |
| 3353 | .ptr_bit_width = switch (elf.identClass()) { | |
| 3354 | .NONE, _ => unreachable, | |
| 3355 | .@"32" => 32, | |
| 3356 | .@"64" => 64, | |
| 3357 | }, | |
| 3358 | .endian = elf.targetEndian(), | |
| 3359 | }, | |
| 3353 | 3360 | ); |
| 3354 | 3361 | } |
| 3355 | 3362 |
src/print_value.zig+10-9| ... | ... | @@ -49,7 +49,6 @@ pub fn print( |
| 49 | 49 | switch (ip.indexToKey(val.toIntern())) { |
| 50 | 50 | .int_type, |
| 51 | 51 | .ptr_type, |
| 52 | .restricted_ptr_type, | |
| 53 | 52 | .array_type, |
| 54 | 53 | .vector_type, |
| 55 | 54 | .opt_type, |
| ... | ... | @@ -64,6 +63,7 @@ pub fn print( |
| 64 | 63 | .func_type, |
| 65 | 64 | .error_set_type, |
| 66 | 65 | .inferred_error_set_type, |
| 66 | .restricted_type, | |
| 67 | 67 | => try Type.print(val.toType(), writer, pt, null), |
| 68 | 68 | .undef => try writer.writeAll("undefined"), |
| 69 | 69 | .simple_value => |simple_value| switch (simple_value) { |
| ... | ... | @@ -88,7 +88,7 @@ pub fn print( |
| 88 | 88 | .err_name => |err_name| try writer.print("error.{f}", .{ |
| 89 | 89 | err_name.fmt(ip), |
| 90 | 90 | }), |
| 91 | .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), | |
| 91 | .payload => |payload| try print(.fromInterned(payload), writer, level, pt, opt_sema), | |
| 92 | 92 | }, |
| 93 | 93 | .enum_literal => |enum_literal| try writer.print(".{f}", .{ |
| 94 | 94 | enum_literal.fmt(ip), |
| ... | ... | @@ -102,7 +102,7 @@ pub fn print( |
| 102 | 102 | return writer.writeAll("@enumFromInt(...)"); |
| 103 | 103 | } |
| 104 | 104 | try writer.writeAll("@enumFromInt("); |
| 105 | try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema); | |
| 105 | try print(.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema); | |
| 106 | 106 | try writer.writeAll(")"); |
| 107 | 107 | }, |
| 108 | 108 | .float => |float| switch (float.storage) { |
| ... | ... | @@ -130,7 +130,7 @@ pub fn print( |
| 130 | 130 | if (level == 0) { |
| 131 | 131 | try writer.writeAll("(...)"); |
| 132 | 132 | } else { |
| 133 | try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema); | |
| 133 | try print(.fromInterned(slice.len), writer, level - 1, pt, opt_sema); | |
| 134 | 134 | } |
| 135 | 135 | try writer.writeAll("]"); |
| 136 | 136 | }, |
| ... | ... | @@ -148,7 +148,7 @@ pub fn print( |
| 148 | 148 | }, |
| 149 | 149 | .opt => |opt| switch (opt.val) { |
| 150 | 150 | .none => try writer.writeAll("null"), |
| 151 | else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), | |
| 151 | else => |payload| try print(.fromInterned(payload), writer, level, pt, opt_sema), | |
| 152 | 152 | }, |
| 153 | 153 | .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema), |
| 154 | 154 | .un => |un| { |
| ... | ... | @@ -159,13 +159,13 @@ pub fn print( |
| 159 | 159 | if (un.tag == .none) { |
| 160 | 160 | const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt); |
| 161 | 161 | try writer.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)}); |
| 162 | try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); | |
| 162 | try print(.fromInterned(un.val), writer, level - 1, pt, opt_sema); | |
| 163 | 163 | try writer.writeAll("))"); |
| 164 | 164 | } else { |
| 165 | 165 | try writer.writeAll(".{ "); |
| 166 | try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema); | |
| 166 | try print(.fromInterned(un.tag), writer, level - 1, pt, opt_sema); | |
| 167 | 167 | try writer.writeAll(" = "); |
| 168 | try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); | |
| 168 | try print(.fromInterned(un.val), writer, level - 1, pt, opt_sema); | |
| 169 | 169 | try writer.writeAll(" }"); |
| 170 | 170 | } |
| 171 | 171 | }, |
| ... | ... | @@ -198,6 +198,7 @@ pub fn print( |
| 198 | 198 | else => unreachable, |
| 199 | 199 | } |
| 200 | 200 | }, |
| 201 | .restricted_value => |restricted_value| try print(.fromInterned(restricted_value.unrestricted_value), writer, level, pt, opt_sema), | |
| 201 | 202 | .memoized_call => unreachable, |
| 202 | 203 | } |
| 203 | 204 | } |
| ... | ... | @@ -470,7 +471,7 @@ pub fn printPtrDerivation( |
| 470 | 471 | if (x.level == 0) { |
| 471 | 472 | try writer.writeAll("..."); |
| 472 | 473 | } else { |
| 473 | try print(Value.fromInterned(uav.val), writer, x.level - 1, pt, x.opt_sema); | |
| 474 | try print(.fromInterned(uav.val), writer, x.level - 1, pt, x.opt_sema); | |
| 474 | 475 | } |
| 475 | 476 | try writer.writeByte(')'); |
| 476 | 477 | }, |
src/print_zir.zig+11-8| ... | ... | @@ -622,14 +622,6 @@ 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 | }, | |
| 633 | 625 | .reify_fn => { |
| 634 | 626 | const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data; |
| 635 | 627 | try self.writeInstRef(stream, extra.param_types); |
| ... | ... | @@ -642,6 +634,17 @@ const Writer = struct { |
| 642 | 634 | try stream.writeAll(")) "); |
| 643 | 635 | try self.writeSrcNode(stream, extra.node); |
| 644 | 636 | }, |
| 637 | .reify_restricted => { | |
| 638 | const extra = self.code.extraData(Zir.Inst.ReifyRestricted, extended.operand).data; | |
| 639 | const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | |
| 640 | try stream.print("{t}, ", .{name_strat}); | |
| 641 | try self.writeInstRef(stream, extra.unrestricted_ty); | |
| 642 | try stream.writeAll(")) "); | |
| 643 | const prev_parent_decl_node = self.parent_decl_node; | |
| 644 | self.parent_decl_node = extra.node; | |
| 645 | defer self.parent_decl_node = prev_parent_decl_node; | |
| 646 | try self.writeSrcNode(stream, .zero); | |
| 647 | }, | |
| 645 | 648 | .reify_struct => { |
| 646 | 649 | const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data; |
| 647 | 650 | const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small); |
src/target.zig+3-2| ... | ... | @@ -908,7 +908,7 @@ pub fn zigBackend(target: *const std.Target, use_llvm: bool) std.builtin.Compile |
| 908 | 908 | }; |
| 909 | 909 | } |
| 910 | 910 | |
| 911 | pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, comptime feature: Feature) bool { | |
| 911 | pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, incremental: bool, comptime feature: Feature) bool { | |
| 912 | 912 | return switch (feature) { |
| 913 | 913 | .panic_fn => switch (backend) { |
| 914 | 914 | .stage2_aarch64, |
| ... | ... | @@ -949,7 +949,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt |
| 949 | 949 | else => true, |
| 950 | 950 | }, |
| 951 | 951 | .restricted_types => switch (backend) { |
| 952 | .stage2_c, .stage2_llvm, .stage2_x86_64 => true, | |
| 952 | .stage2_c => true, | |
| 953 | .stage2_llvm, .stage2_x86_64 => !incremental, | |
| 953 | 954 | else => false, |
| 954 | 955 | }, |
| 955 | 956 | }; |