authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-11 17:27:00-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-24 11:08:01-04:00
log24bf4387088cb2bee7329642c169a09dc48a7af0
treeb2920cbb21431c92d6784a517655ea882158d455
parentda85c089b8911189a9b42505cc44821bc87b5b23

remove pointer restriction from restricted types


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,9 +5771,9 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
57715771
5772 {#header_open|@Restricted#}5772 {#header_open|@Restricted#}
5773 <pre>{#syntax#}@Restricted(5773 <pre>{#syntax#}@Restricted(
5774 comptime Pointer: type,5774 comptime Underlying: type,
5775) type{#endsyntax#}</pre>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 {#header_close#}5777 {#header_close#}
57785778
5779 {#header_open|@Fn#}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,9 +201,9 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type {
201 @branchHint(.cold);201 @branchHint(.cold);
202 call("'noreturn' function returned", @returnAddress());202 call("'noreturn' function returned", @returnAddress());
203 }203 }
204 pub fn corruptRestrictedPointer() noreturn {204 pub fn corruptRestrictedValue() noreturn {
205 @branchHint(.cold);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,7 +135,7 @@ pub fn noreturnReturned() noreturn {
135 @trap();135 @trap();
136}136}
137137
138pub fn corruptRestrictedPointer() noreturn {138pub fn corruptRestrictedValue() noreturn {
139 @branchHint(.cold);139 @branchHint(.cold);
140 @trap();140 @trap();
141}141}
lib/std/debug/simple_panic.zig+2-2
...@@ -127,6 +127,6 @@ pub fn noreturnReturned() noreturn {...@@ -127,6 +127,6 @@ pub fn noreturnReturned() noreturn {
127 call("'noreturn' function returned", null);127 call("'noreturn' function returned", null);
128}128}
129129
130pub fn corruptRestrictedPointer() noreturn {130pub fn corruptRestrictedValue() noreturn {
131 call("corrupt restricted pointer value", null);131 call("corrupt restricted value", null);
132}132}
lib/std/zig/AstGen.zig+9-9
...@@ -9320,15 +9320,6 @@ fn builtinCall(...@@ -9320,15 +9320,6 @@ fn builtinCall(
9320 });9320 });
9321 return rvalue(gz, ri, result, node);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 .Fn => {9323 .Fn => {
9333 const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes);9324 const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes);
9334 const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types);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,6 +9340,15 @@ fn builtinCall(
9349 });9340 });
9350 return rvalue(gz, ri, result, node);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 .Struct => {9352 .Struct => {
9353 const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);9353 const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
9354 const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .struct_layout);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,13 +2062,13 @@ pub const Inst = struct {
2062 /// Implements builtin `@Pointer`.2062 /// Implements builtin `@Pointer`.
2063 /// `operand` is payload index to `ReifyPointer`.2063 /// `operand` is payload index to `ReifyPointer`.
2064 reify_pointer,2064 reify_pointer,
2065 /// Implements builtin `@Restricted`.
2066 /// `operand` is payload index to `UnNode`.
2067 /// `small` contains `NameStrategy`.
2068 reify_restricted,
2069 /// Implements builtin `@Fn`.2065 /// Implements builtin `@Fn`.
2070 /// `operand` is payload index to `ReifyFn`.2066 /// `operand` is payload index to `ReifyFn`.
2071 reify_fn,2067 reify_fn,
2068 /// Implements builtin `@Restricted`.
2069 /// `operand` is payload index to `ReifyRestricted`.
2070 /// `small` contains `NameStrategy`.
2071 reify_restricted,
2072 /// Implements builtin `@Struct`.2072 /// Implements builtin `@Struct`.
2073 /// `operand` is payload index to `ReifyStruct`.2073 /// `operand` is payload index to `ReifyStruct`.
2074 /// `small` contains `NameStrategy`.2074 /// `small` contains `NameStrategy`.
...@@ -3266,6 +3266,13 @@ pub const Inst = struct {...@@ -3266,6 +3266,13 @@ pub const Inst = struct {
3266 fn_attrs: Ref,3266 fn_attrs: Ref,
3267 };3267 };
32683268
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 pub const ReifyStruct = struct {3276 pub const ReifyStruct = struct {
3270 src_line: u32,3277 src_line: u32,
3271 /// This node is absolute, because `reify` instructions are tracked across updates, and3278 /// 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,7 +501,7 @@ pub fn resolve(options: Options) ResolveError!Config {
501 };501 };
502 };502 };
503503
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);
505505
506 const root_error_tracing = b: {506 const root_error_tracing = b: {
507 if (options.root_error_tracing) |x| break :b x;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,7 +1969,6 @@ pub const CaptureValue = packed struct(u32) {
1969pub const Key = union(enum) {1969pub const Key = union(enum) {
1970 int_type: IntType,1970 int_type: IntType,
1971 ptr_type: PtrType,1971 ptr_type: PtrType,
1972 restricted_ptr_type: RestrictedPtrType,
1973 array_type: ArrayType,1972 array_type: ArrayType,
1974 vector_type: VectorType,1973 vector_type: VectorType,
1975 opt_type: Index,1974 opt_type: Index,
...@@ -1978,6 +1977,7 @@ pub const Key = union(enum) {...@@ -1978,6 +1977,7 @@ pub const Key = union(enum) {
1978 anyframe_type: Index,1977 anyframe_type: Index,
1979 error_union_type: ErrorUnionType,1978 error_union_type: ErrorUnionType,
1980 simple_type: SimpleType,1979 simple_type: SimpleType,
1980 restricted_type: RestrictedType,
1981 /// This represents a struct that has been explicitly declared in source code,1981 /// This represents a struct that has been explicitly declared in source code,
1982 /// or was created with `@Struct`. It is unique and based on a declaration.1982 /// or was created with `@Struct`. It is unique and based on a declaration.
1983 struct_type: ContainerType,1983 struct_type: ContainerType,
...@@ -2021,6 +2021,8 @@ pub const Key = union(enum) {...@@ -2021,6 +2021,8 @@ pub const Key = union(enum) {
2021 un: Union,2021 un: Union,
2022 /// An instance of a `packed struct` or `packed union`.2022 /// An instance of a `packed struct` or `packed union`.
2023 bitpack: Bitpack,2023 bitpack: Bitpack,
2024 /// An instance of a restricted type.
2025 restricted_value: RestrictedValue,
20242026
2025 /// A comptime function call with a memoized result.2027 /// A comptime function call with a memoized result.
2026 memoized_call: Key.MemoizedCall,2028 memoized_call: Key.MemoizedCall,
...@@ -2095,14 +2097,6 @@ pub const Key = union(enum) {...@@ -2095,14 +2097,6 @@ pub const Key = union(enum) {
2095 pub const AddressSpace = std.builtin.AddressSpace;2097 pub const AddressSpace = std.builtin.AddressSpace;
2096 };2098 };
20972099
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 /// Extern so that hashing can be done via memory reinterpreting.2100 /// Extern so that hashing can be done via memory reinterpreting.
2107 pub const ArrayType = extern struct {2101 pub const ArrayType = extern struct {
2108 len: u64,2102 len: u64,
...@@ -2206,6 +2200,13 @@ pub const Key = union(enum) {...@@ -2206,6 +2200,13 @@ pub const Key = union(enum) {
2206 }2200 }
2207 };2201 };
22082202
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 pub const Extern = struct {2210 pub const Extern = struct {
2210 /// The name of the extern symbol.2211 /// The name of the extern symbol.
2211 name: NullTerminatedString,2212 name: NullTerminatedString,
...@@ -2581,6 +2582,12 @@ pub const Key = union(enum) {...@@ -2581,6 +2582,12 @@ pub const Key = union(enum) {
2581 backing_int_val: Index,2582 backing_int_val: Index,
2582 };2583 };
25832584
2585 pub const RestrictedValue = extern struct {
2586 /// The restricted type.
2587 ty: Index,
2588 unrestricted_value: Index,
2589 };
2590
2584 pub const MemoizedCall = struct {2591 pub const MemoizedCall = struct {
2585 func: Index,2592 func: Index,
2586 arg_values: []const Index,2593 arg_values: []const Index,
...@@ -2599,13 +2606,13 @@ pub const Key = union(enum) {...@@ -2599,13 +2606,13 @@ pub const Key = union(enum) {
2599 return switch (key) {2606 return switch (key) {
2600 // TODO: assert no padding in these types2607 // TODO: assert no padding in these types
2601 inline .ptr_type,2608 inline .ptr_type,
2602 .restricted_ptr_type,
2603 .array_type,2609 .array_type,
2604 .vector_type,2610 .vector_type,
2605 .opt_type,2611 .opt_type,
2606 .anyframe_type,2612 .anyframe_type,
2607 .error_union_type,2613 .error_union_type,
2608 .simple_type,2614 .simple_type,
2615 .restricted_type,
2609 .simple_value,2616 .simple_value,
2610 .opt,2617 .opt,
2611 .undef,2618 .undef,
...@@ -2614,6 +2621,7 @@ pub const Key = union(enum) {...@@ -2614,6 +2621,7 @@ pub const Key = union(enum) {
2614 .enum_tag,2621 .enum_tag,
2615 .inferred_error_set_type,2622 .inferred_error_set_type,
2616 .un,2623 .un,
2624 .restricted_value,
2617 => |x| Hash.hash(seed, asBytes(&x)),2625 => |x| Hash.hash(seed, asBytes(&x)),
26182626
2619 .int_type => |x| Hash.hash(seed | @shlExact(@as(u64, @intFromEnum(x.signedness)), 63), asBytes(&x.bits)),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,6 +2901,10 @@ pub const Key = union(enum) {
2893 const b_info = b.bitpack;2901 const b_info = b.bitpack;
2894 return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val;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 },
28962908
2897 .@"extern" => |a_info| {2909 .@"extern" => |a_info| {
2898 const b_info = b.@"extern";2910 const b_info = b.@"extern";
...@@ -3027,7 +3039,7 @@ pub const Key = union(enum) {...@@ -3027,7 +3039,7 @@ pub const Key = union(enum) {
3027 }3039 }
3028 },3040 },
30293041
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),
30313043
3032 inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| {3044 inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| {
3033 const b_info = @field(b, @tagName(a_tag_ct));3045 const b_info = @field(b, @tagName(a_tag_ct));
...@@ -3130,7 +3142,6 @@ pub const Key = union(enum) {...@@ -3130,7 +3142,6 @@ pub const Key = union(enum) {
3130 return switch (key) {3142 return switch (key) {
3131 .int_type,3143 .int_type,
3132 .ptr_type,3144 .ptr_type,
3133 .restricted_ptr_type,
3134 .array_type,3145 .array_type,
3135 .vector_type,3146 .vector_type,
3136 .opt_type,3147 .opt_type,
...@@ -3139,6 +3150,7 @@ pub const Key = union(enum) {...@@ -3139,6 +3150,7 @@ pub const Key = union(enum) {
3139 .error_set_type,3150 .error_set_type,
3140 .inferred_error_set_type,3151 .inferred_error_set_type,
3141 .simple_type,3152 .simple_type,
3153 .restricted_type,
3142 .struct_type,3154 .struct_type,
3143 .union_type,3155 .union_type,
3144 .opaque_type,3156 .opaque_type,
...@@ -3160,6 +3172,7 @@ pub const Key = union(enum) {...@@ -3160,6 +3172,7 @@ pub const Key = union(enum) {
3160 .aggregate,3172 .aggregate,
3161 .un,3173 .un,
3162 .bitpack,3174 .bitpack,
3175 .restricted_value,
3163 => |x| x.ty,3176 => |x| x.ty,
31643177
3165 .enum_literal => .enum_literal_type,3178 .enum_literal => .enum_literal_type,
...@@ -4187,7 +4200,6 @@ pub const Index = enum(u32) {...@@ -4187,7 +4200,6 @@ pub const Index = enum(u32) {
4187 type_array_small: struct { data: *Vector },4200 type_array_small: struct { data: *Vector },
4188 type_vector: struct { data: *Vector },4201 type_vector: struct { data: *Vector },
4189 type_pointer: struct { data: *Tag.TypePointer },4202 type_pointer: struct { data: *Tag.TypePointer },
4190 type_restricted: struct { data: *Tag.TypeRestricted },
4191 type_slice: DataIsIndex,4203 type_slice: DataIsIndex,
4192 type_optional: DataIsIndex,4204 type_optional: DataIsIndex,
4193 type_anyframe: DataIsIndex,4205 type_anyframe: DataIsIndex,
...@@ -4222,6 +4234,7 @@ pub const Index = enum(u32) {...@@ -4222,6 +4234,7 @@ pub const Index = enum(u32) {
4222 },4234 },
4223 },4235 },
42244236
4237 type_restricted: struct { data: *Tag.TypeRestricted },
4225 type_struct: struct { data: *Tag.TypeStruct },4238 type_struct: struct { data: *Tag.TypeStruct },
4226 type_struct_packed_auto: struct { data: *Tag.TypeStructPacked },4239 type_struct_packed_auto: struct { data: *Tag.TypeStructPacked },
4227 type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked },4240 type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked },
...@@ -4302,6 +4315,7 @@ pub const Index = enum(u32) {...@@ -4302,6 +4315,7 @@ pub const Index = enum(u32) {
4302 },4315 },
4303 repeated: struct { data: *Repeated },4316 repeated: struct { data: *Repeated },
4304 bitpack: struct { data: *Key.Bitpack },4317 bitpack: struct { data: *Key.Bitpack },
4318 restricted_value: struct { data: *Key.RestrictedValue },
43054319
4306 memoized_call: struct {4320 memoized_call: struct {
4307 const @"data.args_len" = opaque {};4321 const @"data.args_len" = opaque {};
...@@ -4786,9 +4800,6 @@ pub const Tag = enum(u8) {...@@ -4786,9 +4800,6 @@ pub const Tag = enum(u8) {
4786 /// A slice type.4800 /// A slice type.
4787 /// data is Index of underlying pointer type.4801 /// data is Index of underlying pointer type.
4788 type_slice,4802 type_slice,
4789 /// A restricted pointer type.
4790 /// data is payload to `TypeRestricted`.
4791 type_restricted,
4792 /// An optional type.4803 /// An optional type.
4793 /// data is the child type.4804 /// data is the child type.
4794 type_optional,4805 type_optional,
...@@ -4815,6 +4826,9 @@ pub const Tag = enum(u8) {...@@ -4815,6 +4826,9 @@ pub const Tag = enum(u8) {
4815 /// data is extra index of `TypeTuple`.4826 /// data is extra index of `TypeTuple`.
4816 type_tuple,4827 type_tuple,
48174828
4829 /// A restricted pointer type.
4830 /// data is payload to `TypeRestricted`.
4831 type_restricted,
4818 /// A non-packed struct type.4832 /// A non-packed struct type.
4819 /// data is extra index of `TypeStruct`.4833 /// data is extra index of `TypeStruct`.
4820 type_struct,4834 type_struct,
...@@ -5037,6 +5051,9 @@ pub const Tag = enum(u8) {...@@ -5037,6 +5051,9 @@ pub const Tag = enum(u8) {
5037 /// An instance of a `packed struct` or `packed union`.5051 /// An instance of a `packed struct` or `packed union`.
5038 /// data is extra index to `Key.Bitpack`.5052 /// data is extra index to `Key.Bitpack`.
5039 bitpack,5053 bitpack,
5054 /// An instance of a restricted type.
5055 /// data is extra index to `Key.RestrictedValue`.
5056 restricted_value,
50405057
5041 /// A memoized comptime function call result.5058 /// A memoized comptime function call result.
5042 /// data is extra index to `MemoizedCall`5059 /// data is extra index to `MemoizedCall`
...@@ -5127,7 +5144,6 @@ pub const Tag = enum(u8) {...@@ -5127,7 +5144,6 @@ pub const Tag = enum(u8) {
5127 .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector },5144 .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector },
5128 .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector },5145 .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector },
5129 .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer },5146 .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer },
5130 .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted },
5131 .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index },5147 .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index },
5132 .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index },5148 .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index },
5133 .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index },5149 .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index },
...@@ -5171,6 +5187,7 @@ pub const Tag = enum(u8) {...@@ -5171,6 +5187,7 @@ pub const Tag = enum(u8) {
5171 },5187 },
5172 },5188 },
51735189
5190 .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted },
5174 .type_struct = .{5191 .type_struct = .{
5175 .summary = .@"{.payload.name%summary#\"}",5192 .summary = .@"{.payload.name%summary#\"}",
5176 .payload = TypeStruct,5193 .payload = TypeStruct,
...@@ -5363,6 +5380,7 @@ pub const Tag = enum(u8) {...@@ -5363,6 +5380,7 @@ pub const Tag = enum(u8) {
5363 },5380 },
5364 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },5381 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },
5365 .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack },5382 .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack },
5383 .restricted_value = .{ .summary = .@"@as({.payload.unrestricted_value%summary}, {})", .payload = Key.RestrictedValue },
53665384
5367 .memoized_call = .{5385 .memoized_call = .{
5368 .summary = .@"@memoize({.payload.func%summary})",5386 .summary = .@"@memoize({.payload.func%summary})",
...@@ -5390,8 +5408,8 @@ pub const Tag = enum(u8) {...@@ -5390,8 +5408,8 @@ pub const Tag = enum(u8) {
5390 /// The name of this restricted type.5408 /// The name of this restricted type.
5391 name: NullTerminatedString,5409 name: NullTerminatedString,
53925410
5393 /// The pointer type this restricted type is based on.5411 /// The underlying unrestricted type.
5394 unrestricted_ptr_type: Index,5412 unrestricted_type: Index,
5395 };5413 };
53965414
5397 pub const Extern = struct {5415 pub const Extern = struct {
...@@ -6486,14 +6504,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6486,14 +6504,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6486 return .{ .ptr_type = ptr_info };6504 return .{ .ptr_type = ptr_info };
6487 },6505 },
64886506
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 .type_optional => .{ .opt_type = @enumFromInt(data) },6507 .type_optional => .{ .opt_type = @enumFromInt(data) },
6498 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },6508 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },
64996509
...@@ -6509,6 +6519,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6509,6 +6519,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6509 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },6519 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6510 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },6520 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
65116521
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 .type_struct => .{ .struct_type = ns: {6529 .type_struct => .{ .struct_type = ns: {
6513 const extra_list = unwrapped_index.getExtra(ip);6530 const extra_list = unwrapped_index.getExtra(ip);
6514 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);6531 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
...@@ -6903,6 +6920,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6903,6 +6920,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6903 .enum_literal => .{ .enum_literal = @enumFromInt(data) },6920 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
6904 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },6921 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
6905 .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) },6922 .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) },
6923 .restricted_value => .{ .restricted_value = extraData(unwrapped_index.getExtra(ip), Key.RestrictedValue, data) },
69066924
6907 .memoized_call => {6925 .memoized_call => {
6908 const extra_list = unwrapped_index.getExtra(ip);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,7 +7294,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
7276 .data = try addExtra(extra, ptr_type_adjusted),7294 .data = try addExtra(extra, ptr_type_adjusted),
7277 });7295 });
7278 },7296 },
7279 .restricted_ptr_type => unreachable, // instead getReifiedRestrictedType
7280 .array_type => |array_type| {7297 .array_type => |array_type| {
7281 assert(array_type.child != .none);7298 assert(array_type.child != .none);
7282 assert(array_type.sentinel == .none or ip.typeOf(array_type.sentinel) == array_type.child);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,6 +7399,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
7382 });7399 });
7383 },7400 },
73847401
7402 .restricted_type => unreachable, // instead use: getReifiedRestrictedType
7385 .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType7403 .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType
7386 .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType7404 .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType
7387 .enum_type => unreachable, // instead use: getDeclaredEnumType, getReifiedEnumType, getGeneratedEnumTagType7405 .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,11 +7425,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
7407 },7425 },
74087426
7409 .ptr => |ptr| {7427 .ptr => |ptr| {
7410 const ptr_type = switch (ip.indexToKey(ptr.ty)) {7428 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
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 };
7415 assert(ptr_type.flags.size != .slice);7429 assert(ptr_type.flags.size != .slice);
7416 items.appendAssumeCapacity(switch (ptr.base_addr) {7430 items.appendAssumeCapacity(switch (ptr.base_addr) {
7417 .nav => |nav| .{7431 .nav => |nav| .{
...@@ -7983,6 +7997,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -7983,6 +7997,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
7983 .data = try addExtra(extra, bitpack),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 },
79868008
7987 .memoized_call => |memoized_call| {8009 .memoized_call => |memoized_call| {
7988 for (memoized_call.arg_values) |arg| assert(arg != .none);8010 for (memoized_call.arg_values) |arg| assert(arg != .none);
...@@ -8009,11 +8031,11 @@ pub fn getReifiedRestrictedType(...@@ -8009,11 +8031,11 @@ pub fn getReifiedRestrictedType(
8009 io: Io,8031 io: Io,
8010 tid: Zcu.PerThread.Id,8032 tid: Zcu.PerThread.Id,
8011 zir_index: TrackedInst.Index,8033 zir_index: TrackedInst.Index,
8012 unrestricted_ptr_type: Index,8034 unrestricted_type: Index,
8013) Allocator.Error!WipRestrictedType.Result {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 .zir_index = zir_index,8037 .zir_index = zir_index,
8016 .unrestricted_ptr_type = unrestricted_ptr_type,8038 .unrestricted_type = unrestricted_type,
8017 } });8039 } });
8018 defer gop.deinit();8040 defer gop.deinit();
8019 if (gop == .existing) return .{ .existing = gop.existing };8041 if (gop == .existing) return .{ .existing = gop.existing };
...@@ -8028,7 +8050,7 @@ pub fn getReifiedRestrictedType(...@@ -8028,7 +8050,7 @@ pub fn getReifiedRestrictedType(
8028 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{8050 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{
8029 .zir_index = zir_index,8051 .zir_index = zir_index,
8030 .name = undefined,8052 .name = undefined,
8031 .unrestricted_ptr_type = unrestricted_ptr_type,8053 .unrestricted_type = unrestricted_type,
8032 });8054 });
8033 items.appendAssumeCapacity(.{8055 items.appendAssumeCapacity(.{
8034 .tag = .type_restricted,8056 .tag = .type_restricted,
...@@ -10028,7 +10050,6 @@ test "basic usage" {...@@ -10028,7 +10050,6 @@ test "basic usage" {
10028pub fn childType(ip: *const InternPool, i: Index) Index {10050pub fn childType(ip: *const InternPool, i: Index) Index {
10029 return switch (ip.indexToKey(i)) {10051 return switch (ip.indexToKey(i)) {
10030 .ptr_type => |ptr_type| ptr_type.child,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 .vector_type => |vector_type| vector_type.child,10053 .vector_type => |vector_type| vector_type.child,
10033 .array_type => |array_type| array_type.child,10054 .array_type => |array_type| array_type.child,
10034 .opt_type, .anyframe_type => |child| child,10055 .opt_type, .anyframe_type => |child| child,
...@@ -10111,28 +10132,22 @@ pub fn getCoerced(...@@ -10111,28 +10132,22 @@ pub fn getCoerced(
10111 .val = .none,10132 .val = .none,
10112 } });10133 } });
1011310134
10114 new_ty: switch (ip.indexToKey(new_ty)) {10135 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
10115 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {10136 .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{
10116 .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{10137 .ty = new_ty,
10117 .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 .base_addr = .int,10145 .base_addr = .int,
10119 .byte_offset = 0,10146 .byte_offset = 0,
10120 } }),10147 } }),
10121 .slice => return ip.get(gpa, io, tid, .{ .slice = .{10148 .len = .undef_usize,
10122 .ty = new_ty,10149 } }),
10123 .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{10150 };
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 }
10136 },10151 },
10137 else => {10152 else => {
10138 const unwrapped_val = val.unwrap(ip);10153 const unwrapped_val = val.unwrap(ip);
...@@ -10211,40 +10226,28 @@ pub fn getCoerced(...@@ -10211,40 +10226,28 @@ pub fn getCoerced(
10211 },10226 },
10212 else => {},10227 else => {},
10213 },10228 },
10214 .slice => |slice| new_ty: switch (ip.indexToKey(new_ty)) {10229 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .slice)
10215 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {10230 return ip.get(gpa, io, tid, .{ .slice = .{
10216 .one, .many, .c => {},10231 .ty = new_ty,
10217 .slice => return ip.get(gpa, io, tid, .{ .slice = .{10232 .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)),
10218 .ty = new_ty,10233 .len = slice.len,
10219 .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)),10234 } })
10220 .len = slice.len,10235 else if (ip.isIntegerType(new_ty))
10221 } }),10236 return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty),
10222 },10237 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .slice)
10223 .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{10238 return ip.get(gpa, io, tid, .{ .ptr = .{
10224 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,10239 .ty = new_ty,
10225 },10240 .base_addr = ptr.base_addr,
10226 else => if (ip.isIntegerType(new_ty)) return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty),10241 .byte_offset = ptr.byte_offset,
10227 },10242 } })
10228 .ptr => |ptr| new_ty: switch (ip.indexToKey(new_ty)) {10243 else if (ip.isIntegerType(new_ty))
10229 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {10244 switch (ptr.base_addr) {
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) {
10241 .int => return ip.get(gpa, io, tid, .{ .int = .{10245 .int => return ip.get(gpa, io, tid, .{ .int = .{
10242 .ty = .usize_type,10246 .ty = .usize_type,
10243 .storage = .{ .u64 = @intCast(ptr.byte_offset) },10247 .storage = .{ .u64 = @intCast(ptr.byte_offset) },
10244 } }),10248 } }),
10245 else => {},10249 else => {},
10246 },10250 },
10247 },
10248 .opt => |opt| switch (ip.indexToKey(new_ty)) {10251 .opt => |opt| switch (ip.indexToKey(new_ty)) {
10249 .ptr_type => |ptr_type| return switch (opt.val) {10252 .ptr_type => |ptr_type| return switch (opt.val) {
10250 .none => switch (ptr_type.flags.size) {10253 .none => switch (ptr_type.flags.size) {
...@@ -10484,6 +10487,22 @@ pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {...@@ -10484,6 +10487,22 @@ pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
10484/// includes .comptime_int_type10487/// includes .comptime_int_type
10485pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {10488pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
10486 return switch (ty) {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 .usize_type,10506 .usize_type,
10488 .isize_type,10507 .isize_type,
10489 .c_char_type,10508 .c_char_type,
...@@ -10497,7 +10516,8 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {...@@ -10497,7 +10516,8 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
10497 .c_ulonglong_type,10516 .c_ulonglong_type,
10498 .comptime_int_type,10517 .comptime_int_type,
10499 => true,10518 => true,
10500 else => switch (ty.unwrap(ip).getTag(ip)) {10519 else => false,
10520 _ => switch (ty.unwrap(ip).getTag(ip)) {
10501 .type_int_signed,10521 .type_int_signed,
10502 .type_int_unsigned,10522 .type_int_unsigned,
10503 => true,10523 => true,
...@@ -10508,53 +10528,114 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {...@@ -10508,53 +10528,114 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
1050810528
10509/// does not include .enum_literal_type10529/// does not include .enum_literal_type
10510pub fn isEnumType(ip: *const InternPool, ty: Index) bool {10530pub 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
10537pub 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}
1051310543
10514pub fn isUnion(ip: *const InternPool, ty: Index) bool {10544pub 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}
1051710550
10518pub fn isFunctionType(ip: *const InternPool, ty: Index) bool {10551pub 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
10555pub 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}
1052110561
10522pub fn isOptionalType(ip: *const InternPool, ty: Index) bool {10562pub 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}
1052510565
10526/// includes .inferred_error_set_type10566/// includes .inferred_error_set_type
10527pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {10567pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {
10528 return switch (ty) {10568 return switch (ty) {
10529 .anyerror_type, .adhoc_inferred_error_set_type => true,10569 .anyerror_type, .adhoc_inferred_error_set_type => true,
10530 else => switch (ip.indexToKey(ty)) {10570 else => false,
10531 .error_set_type, .inferred_error_set_type => true,10571 _ => switch (ty.unwrap(ip).getTag(ip)) {
10572 .type_error_set, .type_inferred_error_set => true,
10532 else => false,10573 else => false,
10533 },10574 },
10534 };10575 };
10535}10576}
1053610577
10537pub fn isInferredErrorSetType(ip: *const InternPool, ty: Index) bool {10578pub 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}
1054010581
10541pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {10582pub 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}
1054410592
10545pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {10593pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {
10546 return switch (ip.indexToKey(ty)) {10594 return switch (ty.unwrap(ip).getTag(ip)) {
10547 .array_type, .vector_type, .tuple_type, .struct_type => true,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 else => false,10605 else => false,
10549 };10606 };
10550}10607}
1055110608
10609pub fn isOpaqueType(ip: *const InternPool, ty: Index) bool {
10610 return ty == .anyopaque_type or ty.unwrap(ip).getTag(ip) == .type_opaque;
10611}
10612
10613pub fn isRestrictedType(ip: *const InternPool, ty: Index) bool {
10614 return ty.unwrap(ip).getTag(ip) == .type_restricted;
10615}
10616
10552pub fn errorUnionSet(ip: *const InternPool, ty: Index) Index {10617pub 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}
1055510628
10556pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {10629pub 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}
1055910640
10560pub fn dump(ip: *const InternPool) void {10641pub fn dump(ip: *const InternPool) void {
...@@ -10695,7 +10776,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10695,7 +10776,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10695 .type_array_big => @sizeOf(Array),10776 .type_array_big => @sizeOf(Array),
10696 .type_vector => @sizeOf(Vector),10777 .type_vector => @sizeOf(Vector),
10697 .type_pointer => @sizeOf(Tag.TypePointer),10778 .type_pointer => @sizeOf(Tag.TypePointer),
10698 .type_restricted => @sizeOf(Tag.TypeRestricted),
10699 .type_slice => 0,10779 .type_slice => 0,
10700 .type_optional => 0,10780 .type_optional => 0,
10701 .type_anyframe => 0,10781 .type_anyframe => 0,
...@@ -10718,6 +10798,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10718,6 +10798,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10718 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));10798 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
10719 },10799 },
1072010800
10801 .type_restricted => @sizeOf(Tag.TypeRestricted),
10721 .type_struct => b: {10802 .type_struct => b: {
10722 var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;10803 var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
10723 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);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,7 +10989,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10908 .func_coerced => @sizeOf(Tag.FuncCoerced),10989 .func_coerced => @sizeOf(Tag.FuncCoerced),
10909 .only_possible_value => 0,10990 .only_possible_value => 0,
10910 .union_value => @sizeOf(Key.Union),10991 .union_value => @sizeOf(Key.Union),
10911 .bitpack => 2 * @sizeOf(u32),10992 .bitpack => @sizeOf(Key.Bitpack),
10993 .restricted_value => @sizeOf(Key.RestrictedValue),
1091210994
10913 .memoized_call => b: {10995 .memoized_call => b: {
10914 const info = extraData(extra_list, MemoizedCall, data);10996 const info = extraData(extra_list, MemoizedCall, data);
...@@ -10957,7 +11039,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -10957,7 +11039,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
10957 .type_array_big,11039 .type_array_big,
10958 .type_vector,11040 .type_vector,
10959 .type_pointer,11041 .type_pointer,
10960 .type_restricted,
10961 .type_optional,11042 .type_optional,
10962 .type_anyframe,11043 .type_anyframe,
10963 .type_error_union,11044 .type_error_union,
...@@ -10966,6 +11047,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -10966,6 +11047,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
10966 .type_inferred_error_set,11047 .type_inferred_error_set,
10967 .type_tuple,11048 .type_tuple,
10968 .type_function,11049 .type_function,
11050 .type_restricted,
10969 .type_struct,11051 .type_struct,
10970 .type_struct_packed_auto,11052 .type_struct_packed_auto,
10971 .type_struct_packed_explicit,11053 .type_struct_packed_explicit,
...@@ -11023,6 +11105,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -11023,6 +11105,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
11023 .func_coerced,11105 .func_coerced,
11024 .union_value,11106 .union_value,
11025 .bitpack,11107 .bitpack,
11108 .restricted_value,
11026 .memoized_call,11109 .memoized_call,
11027 => try w.print("{d}", .{data}),11110 => try w.print("{d}", .{data}),
1102811111
...@@ -11696,7 +11779,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11696,7 +11779,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11696 .type_array_small,11779 .type_array_small,
11697 .type_vector,11780 .type_vector,
11698 .type_pointer,11781 .type_pointer,
11699 .type_restricted,
11700 .type_slice,11782 .type_slice,
11701 .type_optional,11783 .type_optional,
11702 .type_anyframe,11784 .type_anyframe,
...@@ -11706,6 +11788,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11706,6 +11788,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11706 .type_inferred_error_set,11788 .type_inferred_error_set,
11707 .type_tuple,11789 .type_tuple,
11708 .type_function,11790 .type_function,
11791 .type_restricted,
11709 .type_struct,11792 .type_struct,
11710 .type_struct_packed_auto,11793 .type_struct_packed_auto,
11711 .type_struct_packed_explicit,11794 .type_struct_packed_explicit,
...@@ -11753,6 +11836,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11753,6 +11836,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11753 .aggregate,11836 .aggregate,
11754 .repeated,11837 .repeated,
11755 .bitpack,11838 .bitpack,
11839 .restricted_value,
11756 => |t| {11840 => |t| {
11757 const extra_list = unwrapped_index.getExtra(ip);11841 const extra_list = unwrapped_index.getExtra(ip);
11758 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);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,7 +12111,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
12027 .bool_false => unreachable,12111 .bool_false => unreachable,
12028 .empty_tuple => unreachable,12112 .empty_tuple => unreachable,
1202912113
12030 _ => switch (index.unwrap(ip).getTag(ip)) {12114 _ => return switch (index.unwrap(ip).getTag(ip)) {
12031 .removed => unreachable,12115 .removed => unreachable,
1203212116
12033 .type_int_signed,12117 .type_int_signed,
...@@ -12042,7 +12126,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12042,7 +12126,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1204212126
12043 .type_pointer,12127 .type_pointer,
12044 .type_slice,12128 .type_slice,
12045 .type_restricted,
12046 => .pointer,12129 => .pointer,
1204712130
12048 .type_optional => .optional,12131 .type_optional => .optional,
...@@ -12079,6 +12162,8 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12079,6 +12162,8 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1207912162
12080 .type_function => .@"fn",12163 .type_function => .@"fn",
1208112164
12165 .type_restricted => unreachable,
12166
12082 // values, not types12167 // values, not types
12083 .undef,12168 .undef,
12084 .simple_value,12169 .simple_value,
...@@ -12128,6 +12213,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12128,6 +12213,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
12128 .aggregate,12213 .aggregate,
12129 .repeated,12214 .repeated,
12130 .bitpack,12215 .bitpack,
12216 .restricted_value,
12131 // memoization, not types12217 // memoization, not types
12132 .memoized_call,12218 .memoized_call,
12133 => unreachable,12219 => unreachable,
...@@ -12358,11 +12444,7 @@ pub fn addFieldTagValue(...@@ -12358,11 +12444,7 @@ pub fn addFieldTagValue(
12358/// encoding instead of `Tag.ptr_uav_aligned` when possible.12444/// encoding instead of `Tag.ptr_uav_aligned` when possible.
12359fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {12445fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
12360 if (a_ty == b_ty) return true;12446 if (a_ty == b_ty) return true;
12361 const b_info = switch (ip.indexToKey(b_ty)) {12447 const b_info = ip.indexToKey(b_ty).ptr_type;
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 };
12366 return a_info.flags.alignment == b_info.flags.alignment and12448 return a_info.flags.alignment == b_info.flags.alignment and
12367 (a_info.child == b_info.child or a_info.flags.alignment != .none);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,8 +1435,8 @@ fn analyzeBodyInner(
1435 .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended),1435 .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended),
1436 .reify_tuple => try sema.zirReifyTuple( block, extended),1436 .reify_tuple => try sema.zirReifyTuple( block, extended),
1437 .reify_pointer => try sema.zirReifyPointer( block, extended),1437 .reify_pointer => try sema.zirReifyPointer( block, extended),
1438 .reify_restricted => try sema.zirReifyRestricted( block, extended, inst),
1439 .reify_fn => try sema.zirReifyFn( block, extended),1438 .reify_fn => try sema.zirReifyFn( block, extended),
1439 .reify_restricted => try sema.zirReifyRestricted( block, extended, inst),
1440 .reify_struct => try sema.zirReifyStruct( block, extended, inst),1440 .reify_struct => try sema.zirReifyStruct( block, extended, inst),
1441 .reify_union => try sema.zirReifyUnion( block, extended, inst),1441 .reify_union => try sema.zirReifyUnion( block, extended, inst),
1442 .reify_enum => try sema.zirReifyEnum( block, extended, inst),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,10 +4641,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4641 const src = block.nodeOffset(inst_data.src_node);4641 const src = block.nodeOffset(inst_data.src_node);
4642 const operand = sema.resolveInst(inst_data.operand);4642 const operand = sema.resolveInst(inst_data.operand);
4643 const operand_ty = sema.typeOf(operand);4643 const operand_ty = sema.typeOf(operand);
4644 const operand_unrestricted_ty = operand_ty.unrestrictedType(zcu) orelse operand_ty;
46444645
4645 if (operand_ty.zigTypeTag(zcu) != .pointer) {4646 if (operand_unrestricted_ty.zigTypeTag(zcu) != .pointer) {
4646 return sema.fail(block, src, "cannot dereference non-pointer type '{f}'", .{operand_ty.fmt(pt)});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 .one, .c => {},4649 .one, .c => {},
4649 .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{operand_ty.fmt(pt)}),4650 .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{operand_ty.fmt(pt)}),
4650 .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}),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,7 +4653,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
46524653
4653 if (sema.resolveValue(operand)) |val| {4654 if (sema.resolveValue(operand)) |val| {
4654 // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal.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 return sema.fail(block, src, "cannot dereference undefined value", .{});4657 return sema.fail(block, src, "cannot dereference undefined value", .{});
4657 }4658 }
4658 }4659 }
...@@ -7815,23 +7816,22 @@ fn analyzeDeclLiteral(...@@ -7815,23 +7816,22 @@ fn analyzeDeclLiteral(
7815 block: *Block,7816 block: *Block,
7816 src: LazySrcLoc,7817 src: LazySrcLoc,
7817 name: InternPool.NullTerminatedString,7818 name: InternPool.NullTerminatedString,
7818 orig_ty: Type,7819 ty: Type,
7819 do_coerce: bool,7820 do_coerce: bool,
7820) CompileError!Air.Inst.Ref {7821) CompileError!Air.Inst.Ref {
7821 const pt = sema.pt;7822 const pt = sema.pt;
7822 const zcu = pt.zcu;7823 const zcu = pt.zcu;
78237824
7824 const uncoerced_result = res: {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 // Treat this as a normal enum literal.7828 // Treat this as a normal enum literal.
7827 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));7829 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
7828 }7830 }
78297831 while (true) switch (unrestricted_ty.zigTypeTag(zcu)) {
7830 var ty = orig_ty;7832 .error_union => unrestricted_ty = unrestricted_ty.errorUnionPayload(zcu),
7831 while (true) switch (ty.zigTypeTag(zcu)) {7833 .optional => unrestricted_ty = unrestricted_ty.optionalChild(zcu),
7832 .error_union => ty = ty.errorUnionPayload(zcu),7834 .pointer => unrestricted_ty = if (unrestricted_ty.isSinglePointer(zcu)) unrestricted_ty.childType(zcu) else break,
7833 .optional => ty = ty.optionalChild(zcu),
7834 .pointer => ty = if (ty.isSinglePointer(zcu)) ty.childType(zcu) else break,
7835 .enum_literal, .error_set => {7835 .enum_literal, .error_set => {
7836 // Treat this as a normal enum literal.7836 // Treat this as a normal enum literal.
7837 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));7837 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
...@@ -7839,7 +7839,7 @@ fn analyzeDeclLiteral(...@@ -7839,7 +7839,7 @@ fn analyzeDeclLiteral(
7839 else => break,7839 else => break,
7840 };7840 };
78417841
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 };
78447844
7845 // Decl literals cannot lookup runtime `var`s.7845 // Decl literals cannot lookup runtime `var`s.
...@@ -7848,7 +7848,7 @@ fn analyzeDeclLiteral(...@@ -7848,7 +7848,7 @@ fn analyzeDeclLiteral(
7848 }7848 }
78497849
7850 if (do_coerce) {7850 if (do_coerce) {
7851 return sema.coerce(block, orig_ty, uncoerced_result, src);7851 return sema.coerce(block, ty, uncoerced_result, src);
7852 } else {7852 } else {
7853 return uncoerced_result;7853 return uncoerced_result;
7854 }7854 }
...@@ -16170,16 +16170,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16170,16 +16170,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16170 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;16170 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
16171 const src = block.nodeOffset(inst_data.src_node);16171 const src = block.nodeOffset(inst_data.src_node);
16172 const ty = try sema.resolveType(block, src, inst_data.operand);16172 const ty = try sema.resolveType(block, src, inst_data.operand);
16173 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
16173 const type_info_ty = try sema.getBuiltinType(src, .Type);16174 const type_info_ty = try sema.getBuiltinType(src, .Type);
16174 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;16175 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1617516176
16176 try sema.ensureLayoutResolved(ty, src, .type_info);16177 try sema.ensureLayoutResolved(unrestricted_ty, src, .type_info);
1617716178
16178 if (ty.typeDeclInst(zcu)) |type_decl_inst| {16179 if (unrestricted_ty.typeDeclInst(zcu)) |type_decl_inst| {
16179 try sema.declareDependency(.{ .namespace = type_decl_inst });16180 try sema.declareDependency(.{ .namespace = type_decl_inst });
16180 }16181 }
1618116182
16182 switch (ty.zigTypeTag(zcu)) {16183 switch (unrestricted_ty.zigTypeTag(zcu)) {
16183 .type,16184 .type,
16184 .void,16185 .void,
16185 .bool,16186 .bool,
...@@ -16202,7 +16203,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16202,7 +16203,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16202 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");16203 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");
16203 const param_info_ty = try sema.getBuiltinType(src, .@"Type.Fn.Param");16204 const param_info_ty = try sema.getBuiltinType(src, .@"Type.Fn.Param");
1620416205
16205 const func_ty_info = zcu.typeToFunc(ty).?;16206 const func_ty_info = zcu.typeToFunc(unrestricted_ty).?;
16206 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);16207 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
16207 var func_is_generic = false;16208 var func_is_generic = false;
1620816209
...@@ -16308,7 +16309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16308,7 +16309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16308 .int => {16309 .int => {
16309 const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int");16310 const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int");
16310 const signedness_ty = try sema.getBuiltinType(src, .Signedness);16311 const signedness_ty = try sema.getBuiltinType(src, .Signedness);
16311 const info = ty.intInfo(zcu);16312 const info = unrestricted_ty.intInfo(zcu);
16312 const field_values = .{16313 const field_values = .{
16313 // signedness: Signedness,16314 // signedness: Signedness,
16314 (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),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,7 +16327,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1632616327
16327 const field_vals = .{16328 const field_vals = .{
16328 // bits: u16,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 return Air.internedToRef((try pt.internUnion(.{16332 return Air.internedToRef((try pt.internUnion(.{
16332 .ty = type_info_ty.toIntern(),16333 .ty = type_info_ty.toIntern(),
...@@ -16335,7 +16336,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16335,7 +16336,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16335 })));16336 })));
16336 },16337 },
16337 .pointer => {16338 .pointer => {
16338 const info = ty.ptrInfo(zcu);16339 const info = unrestricted_ty.ptrInfo(zcu);
16339 const alignment_ty = try pt.optionalType(.usize_type);16340 const alignment_ty = try pt.optionalType(.usize_type);
16340 const alignment_val: Value = val: {16341 const alignment_val: Value = val: {
16341 const bytes = info.flags.alignment.toByteUnits() orelse {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,7 +16383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16382 .array => {16383 .array => {
16383 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");16384 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");
1638416385
16385 const info = ty.arrayInfo(zcu);16386 const info = unrestricted_ty.arrayInfo(zcu);
16386 const field_values = .{16387 const field_values = .{
16387 // len: comptime_int,16388 // len: comptime_int,
16388 (try pt.intValue(.comptime_int, info.len)).toIntern(),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,7 +16401,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16400 .vector => {16401 .vector => {
16401 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");16402 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");
1640216403
16403 const info = ty.arrayInfo(zcu);16404 const info = unrestricted_ty.arrayInfo(zcu);
16404 const field_values = .{16405 const field_values = .{
16405 // len: comptime_int,16406 // len: comptime_int,
16406 (try pt.intValue(.comptime_int, info.len)).toIntern(),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,7 +16419,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1641816419
16419 const field_values = .{16420 const field_values = .{
16420 // child: type,16421 // child: type,
16421 ty.optionalChild(zcu).toIntern(),16422 unrestricted_ty.optionalChild(zcu).toIntern(),
16422 };16423 };
16423 return Air.internedToRef((try pt.internUnion(.{16424 return Air.internedToRef((try pt.internUnion(.{
16424 .ty = type_info_ty.toIntern(),16425 .ty = type_info_ty.toIntern(),
...@@ -16433,7 +16434,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16433,7 +16434,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16433 // Build our list of Error values16434 // Build our list of Error values
16434 // Optional value is only null if anyerror16435 // Optional value is only null if anyerror
16435 // Value can be zero-length slice otherwise16436 // 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 .anyerror_type => null,16438 .anyerror_type => null,
16438 else => |err_set_ty_index| blk: {16439 else => |err_set_ty_index| blk: {
16439 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;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,9 +16523,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1652216523
16523 const field_values = .{16524 const field_values = .{
16524 // error_set: type,16525 // error_set: type,
16525 ty.errorUnionSet(zcu).toIntern(),16526 unrestricted_ty.errorUnionSet(zcu).toIntern(),
16526 // payload: type,16527 // payload: type,
16527 ty.errorUnionPayload(zcu).toIntern(),16528 unrestricted_ty.errorUnionPayload(zcu).toIntern(),
16528 };16529 };
16529 return Air.internedToRef((try pt.internUnion(.{16530 return Air.internedToRef((try pt.internUnion(.{
16530 .ty = type_info_ty.toIntern(),16531 .ty = type_info_ty.toIntern(),
...@@ -16533,7 +16534,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16533,7 +16534,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16533 })));16534 })));
16534 },16535 },
16535 .@"enum" => {16536 .@"enum" => {
16536 const enum_obj = ip.loadEnumType(ty.toIntern());16537 const enum_obj = ip.loadEnumType(unrestricted_ty.toIntern());
16537 const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive);16538 const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive);
1653816539
16539 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");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,13 +16616,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16615 } });16616 } });
16616 };16617 };
1661716618
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());
1661916620
16620 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");16621 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1662116622
16622 const field_values = .{16623 const field_values = .{
16623 // tag_type: type,16624 // tag_type: type,
16624 ip.loadEnumType(ty.toIntern()).int_tag_type,16625 ip.loadEnumType(unrestricted_ty.toIntern()).int_tag_type,
16625 // fields: []const EnumField,16626 // fields: []const EnumField,
16626 fields_val,16627 fields_val,
16627 // decls: []const Declaration,16628 // decls: []const Declaration,
...@@ -16639,7 +16640,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16639,7 +16640,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16639 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");16640 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
16640 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");16641 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");
1664116642
16642 const union_obj = ip.loadUnionType(ty.toIntern());16643 const union_obj = ip.loadUnionType(unrestricted_ty.toIntern());
16643 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);16644 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
16644 const layout = union_obj.layout;16645 const layout = union_obj.layout;
1664516646
...@@ -16678,7 +16679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16678,7 +16679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16678 const alignment_ty = try pt.optionalType(.usize_type);16679 const alignment_ty = try pt.optionalType(.usize_type);
16679 const alignment_val: Value = val: {16680 const alignment_val: Value = val: {
16680 const a: Alignment = switch (layout) {16681 const a: Alignment = switch (layout) {
16681 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),16682 .auto, .@"extern" => unrestricted_ty.explicitFieldAlignment(field_index, zcu),
16682 .@"packed" => .none,16683 .@"packed" => .none,
16683 };16684 };
16684 const bytes = a.toByteUnits() orelse {16685 const bytes = a.toByteUnits() orelse {
...@@ -16730,11 +16731,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16730,11 +16731,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16730 } });16731 } });
16731 };16732 };
1673216733
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());
1673416735
16735 const enum_tag_ty_val = try pt.intern(.{ .opt = .{16736 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
16736 .ty = (try pt.optionalType(.type_type)).toIntern(),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 } });
1673916740
16740 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");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,7 +16764,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16763 var struct_field_vals: []InternPool.Index = &.{};16764 var struct_field_vals: []InternPool.Index = &.{};
16764 defer gpa.free(struct_field_vals);16765 defer gpa.free(struct_field_vals);
16765 fv: {16766 fv: {
16766 const struct_type = switch (ip.indexToKey(ty.toIntern())) {16767 const struct_type = switch (ip.indexToKey(unrestricted_ty.toIntern())) {
16767 .tuple_type => |tuple_type| {16768 .tuple_type => |tuple_type| {
16768 struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len);16769 struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len);
16769 for (struct_field_vals, 0..) |*struct_field_val, field_index| {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,10 +16816,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16815 }16816 }
16816 break :fv;16817 break :fv;
16817 },16818 },
16818 .struct_type => ip.loadStructType(ty.toIntern()),16819 .struct_type => ip.loadStructType(unrestricted_ty.toIntern()),
16819 else => unreachable,16820 else => unreachable,
16820 };16821 };
16821 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples16822 try sema.ensureStructDefaultsResolved(unrestricted_ty, src); // can't do this sooner, since it's not allowed on tuples
16822 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);16823 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1682316824
16824 for (struct_field_vals, 0..) |*field_val, field_index| {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,7 +16860,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16859 const alignment_ty = try pt.optionalType(.usize_type);16860 const alignment_ty = try pt.optionalType(.usize_type);
16860 const alignment_val: Value = val: {16861 const alignment_val: Value = val: {
16861 const a: Alignment = switch (struct_type.layout) {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 .@"packed" => .none,16864 .@"packed" => .none,
16864 };16865 };
16865 const bytes = a.toByteUnits() orelse {16866 const bytes = a.toByteUnits() orelse {
...@@ -16916,11 +16917,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16916,11 +16917,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16916 } });16917 } });
16917 };16918 };
1691816919
16919 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));16920 const decls_val = try sema.typeInfoDecls(src, unrestricted_ty.getNamespace(zcu));
1692016921
16921 const backing_integer_val = try pt.intern(.{ .opt = .{16922 const backing_integer_val = try pt.intern(.{ .opt = .{
16922 .ty = (try pt.optionalType(.type_type)).toIntern(),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 assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu));16925 assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu));
16925 break :val struct_obj.packed_backing_int_type;16926 break :val struct_obj.packed_backing_int_type;
16926 } else .none,16927 } else .none,
...@@ -16928,7 +16929,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16928,7 +16929,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1692816929
16929 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");16930 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1693016931
16931 const layout = ty.containerLayout(zcu);16932 const layout = unrestricted_ty.containerLayout(zcu);
1693216933
16933 const field_values = [_]InternPool.Index{16934 const field_values = [_]InternPool.Index{
16934 // layout: ContainerLayout,16935 // layout: ContainerLayout,
...@@ -16940,7 +16941,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16940,7 +16941,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16940 // decls: []const Declaration,16941 // decls: []const Declaration,
16941 decls_val,16942 decls_val,
16942 // is_tuple: bool,16943 // is_tuple: bool,
16943 Value.makeBool(ty.isTuple(zcu)).toIntern(),16944 Value.makeBool(unrestricted_ty.isTuple(zcu)).toIntern(),
16944 };16945 };
16945 return Air.internedToRef((try pt.internUnion(.{16946 return Air.internedToRef((try pt.internUnion(.{
16946 .ty = type_info_ty.toIntern(),16947 .ty = type_info_ty.toIntern(),
...@@ -16951,7 +16952,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16951,7 +16952,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16951 .@"opaque" => {16952 .@"opaque" => {
16952 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");16953 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1695316954
16954 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));16955 const decls_val = try sema.typeInfoDecls(src, unrestricted_ty.getNamespace(zcu));
1695516956
16956 const field_values = .{16957 const field_values = .{
16957 // decls: []const Declaration,16958 // decls: []const Declaration,
...@@ -19212,7 +19213,7 @@ fn arrayInitAnon(...@@ -19212,7 +19213,7 @@ fn arrayInitAnon(
19212 } });19213 } });
19213 const elem = sema.resolveInst(operand);19214 const elem = sema.resolveInst(operand);
19214 types[i] = sema.typeOf(elem).toIntern();19215 types[i] = sema.typeOf(elem).toIntern();
19215 if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {19216 if (ip.isOpaqueType(types[i])) {
19216 const msg = msg: {19217 const msg = msg: {
19217 const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});19218 const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
19218 errdefer msg.destroy(gpa);19219 errdefer msg.destroy(gpa);
...@@ -19599,22 +19600,24 @@ fn zirUnaryMath(...@@ -19599,22 +19600,24 @@ fn zirUnaryMath(
19599}19600}
1960019601
19601fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19602fn 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 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19607 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19603 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19608 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
19604 const src = block.nodeOffset(inst_data.src_node);19609 const src = block.nodeOffset(inst_data.src_node);
19605 const operand = sema.resolveInst(inst_data.operand);19610 const operand = sema.resolveInst(inst_data.operand);
19606 const operand_ty = sema.typeOf(operand);19611 const operand_ty = sema.typeOf(operand);
19607 const pt = sema.pt;19612 const unrestricted_operand_ty = operand_ty.unrestrictedType(zcu) orelse operand_ty;
19608 const zcu = pt.zcu;19613 const enum_ty = switch (unrestricted_operand_ty.zigTypeTag(zcu)) {
19609 const ip = &zcu.intern_pool;
19610 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
19611 .enum_literal => {19614 .enum_literal => {
19612 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;19615 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;
19613 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;19616 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
19614 return sema.addNullTerminatedStrLit(tag_name);19617 return sema.addNullTerminatedStrLit(tag_name);
19615 },19618 },
19616 .@"enum" => operand_ty,19619 .@"enum" => unrestricted_operand_ty,
19617 .@"union" => operand_ty.unionTagType(zcu) orelse19620 .@"union" => unrestricted_operand_ty.unionTagType(zcu) orelse
19618 return sema.fail(block, src, "union '{f}' is untagged", .{operand_ty.fmt(pt)}),19621 return sema.fail(block, src, "union '{f}' is untagged", .{operand_ty.fmt(pt)}),
19619 else => return sema.fail(block, operand_src, "expected enum or union; found '{f}'", .{19622 else => return sema.fail(block, operand_src, "expected enum or union; found '{f}'", .{
19620 operand_ty.fmt(pt),19623 operand_ty.fmt(pt),
...@@ -19881,62 +19884,6 @@ fn zirReifyPointer(...@@ -19881,62 +19884,6 @@ fn zirReifyPointer(
19881 }));19884 }));
19882}19885}
1988319886
19884fn 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
19940fn zirReifyFn(19887fn zirReifyFn(
19941 sema: *Sema,19888 sema: *Sema,
19942 block: *Block,19889 block: *Block,
...@@ -20035,6 +19982,58 @@ fn zirReifyFn(...@@ -20035,6 +19982,58 @@ fn zirReifyFn(
20035 }));19982 }));
20036}19983}
2003719984
19985fn 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
20038fn zirReifyStruct(20037fn zirReifyStruct(
20039 sema: *Sema,20038 sema: *Sema,
20040 block: *Block,20039 block: *Block,
...@@ -25149,7 +25148,7 @@ pub fn validateVarType(...@@ -25149,7 +25148,7 @@ pub fn validateVarType(
25149 return sema.failWithOwnedErrorMsg(block, msg);25148 return sema.failWithOwnedErrorMsg(block, msg);
25150 }25149 }
25151 } else {25150 } else {
25152 if (var_ty.zigTypeTag(zcu) == .@"opaque") {25151 if (zcu.intern_pool.isOpaqueType(var_ty.toIntern())) {
25153 return sema.fail(25152 return sema.fail(
25154 block,25153 block,
25155 src,25154 src,
...@@ -25166,8 +25165,11 @@ pub fn validateVarType(...@@ -25166,8 +25165,11 @@ pub fn validateVarType(
25166 errdefer msg.destroy(sema.gpa);25165 errdefer msg.destroy(sema.gpa);
2516725166
25168 try sema.explainWhyTypeIsComptime(msg, src, var_ty);25167 try sema.explainWhyTypeIsComptime(msg, src, var_ty);
25169 if (var_ty.zigTypeTag(zcu) == .comptime_int or var_ty.zigTypeTag(zcu) == .comptime_float) {25168 switch (var_ty.toIntern()) {
25170 try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});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 }
2517225174
25173 break :msg msg;25175 break :msg msg;
...@@ -25756,23 +25758,24 @@ fn fieldVal(...@@ -25756,23 +25758,24 @@ fn fieldVal(
25756 const ip = &zcu.intern_pool;25758 const ip = &zcu.intern_pool;
25757 const object_src = src; // TODO better source location25759 const object_src = src; // TODO better source location
25758 const object_ty = sema.typeOf(object);25760 const object_ty = sema.typeOf(object);
25761 const unrestricted_object_ty = object_ty.unrestrictedType(zcu) orelse object_ty;
2575925762
25760 // Zig allows dereferencing a single pointer during field lookup. Note that25763 // Zig allows dereferencing a single pointer during field lookup. Note that
25761 // we don't actually need to generate the dereference some field lookups, like the25764 // we don't actually need to generate the dereference some field lookups, like the
25762 // length of arrays and other comptime operations.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);
2576425767
25765 const inner_ty = if (is_pointer_to)25768 const inner_ty = if (is_pointer_to)
25766 object_ty.childType(zcu)25769 unrestricted_object_ty.childType(zcu)
25767 else25770 else
25768 object_ty;25771 unrestricted_object_ty;
2576925772
25770 switch (inner_ty.zigTypeTag(zcu)) {25773 switch (inner_ty.zigTypeTag(zcu)) {
25771 .array => {25774 .array => {
25772 if (field_name.eqlSlice("len", ip)) {25775 if (field_name.eqlSlice("len", ip)) {
25773 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());25776 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());
25774 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {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 const result_ty = try pt.ptrType(.{25779 const result_ty = try pt.ptrType(.{
25777 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),25780 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
25778 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,25781 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
...@@ -25829,11 +25832,12 @@ fn fieldVal(...@@ -25829,11 +25832,12 @@ fn fieldVal(
25829 object;25832 object;
2583025833
25831 const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?;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;
2583325837
25834 switch (child_type.zigTypeTag(zcu)) {25838 switch (unrestricted_child_ty.zigTypeTag(zcu)) {
25835 .error_set => {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 .inferred_error_set_type => |func_index| {25841 .inferred_error_set_type => |func_index| {
25838 try sema.ensureFuncIesResolved(block, src, func_index);25842 try sema.ensureFuncIesResolved(block, src, func_index);
25839 const resolved_ies = ip.funcIesResolvedUnordered(func_index);25843 const resolved_ies = ip.funcIesResolvedUnordered(func_index);
...@@ -25841,9 +25845,9 @@ fn fieldVal(...@@ -25841,9 +25845,9 @@ fn fieldVal(
25841 },25845 },
25842 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {25846 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {
25843 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{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 .simple_type => |t| {25851 .simple_type => |t| {
25848 assert(t == .anyerror);25852 assert(t == .anyerror);
25849 _ = try pt.getErrorValue(field_name);25853 _ = try pt.getErrorValue(field_name);
...@@ -25857,42 +25861,42 @@ fn fieldVal(...@@ -25857,42 +25861,42 @@ fn fieldVal(
25857 } }));25861 } }));
25858 },25862 },
25859 .@"union" => {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 return inst;25865 return inst;
25862 }25866 }
25863 try sema.ensureLayoutResolved(child_type, src, .field_used);25867 try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used);
25864 if (child_type.unionTagType(zcu)) |enum_ty| {25868 if (unrestricted_child_ty.unionTagType(zcu)) |enum_ty| {
25865 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {25869 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
25866 const field_index: u32 = @intCast(field_index_usize);25870 const field_index: u32 = @intCast(field_index_usize);
25867 return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern());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 .@"enum" => {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 return inst;25878 return inst;
25875 }25879 }
25876 try sema.ensureLayoutResolved(child_type, src, .field_used);25880 try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used);
25877 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse25881 const field_index_usize = unrestricted_child_ty.enumFieldIndex(field_name, zcu) orelse
25878 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);25882 return sema.failWithBadMemberAccess(block, child_ty, field_name_src, field_name);
25879 const field_index: u32 = @intCast(field_index_usize);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 return Air.internedToRef(enum_val.toIntern());25885 return Air.internedToRef(enum_val.toIntern());
25882 },25886 },
25883 .@"struct", .@"opaque" => {25887 .@"struct", .@"opaque" => {
25884 if (!child_type.isTuple(zcu) and child_type.toIntern() != .anyopaque_type) {25888 if (!unrestricted_child_ty.isTuple(zcu) and unrestricted_child_ty.toIntern() != .anyopaque_type) {
25885 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25889 if (try sema.namespaceLookupVal(block, src, unrestricted_child_ty.getNamespaceIndex(zcu), field_name)) |inst| {
25886 return inst;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 else => return sema.failWithOwnedErrorMsg(block, msg: {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 errdefer msg.destroy(sema.gpa);25897 errdefer msg.destroy(sema.gpa);
25894 if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});25898 if (unrestricted_child_ty.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", .{});25899 if (unrestricted_child_ty.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{});
25896 break :msg msg;25900 break :msg msg;
25897 }),25901 }),
25898 }25902 }
...@@ -27471,6 +27475,29 @@ fn coerceExtra(...@@ -27471,6 +27475,29 @@ fn coerceExtra(
2747127475
27472 const maybe_inst_val = sema.resolveValue(inst);27476 const maybe_inst_val = sema.resolveValue(inst);
2747327477
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 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);27501 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
27475 if (in_memory_result == .ok) {27502 if (in_memory_result == .ok) {
27476 if (maybe_inst_val) |val| {27503 if (maybe_inst_val) |val| {
...@@ -27796,22 +27823,6 @@ fn coerceExtra(...@@ -27796,22 +27823,6 @@ fn coerceExtra(
27796 return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src);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 .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) {27827 .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) {
27817 .float, .comptime_float => float: {27828 .float, .comptime_float => float: {
...@@ -28126,6 +28137,7 @@ fn coerceInMemory(...@@ -28126,6 +28137,7 @@ fn coerceInMemory(
2812628137
28127const InMemoryCoercionResult = union(enum) {28138const InMemoryCoercionResult = union(enum) {
28128 ok,28139 ok,
28140 restricted: Pair,
28129 no_match: Pair,28141 no_match: Pair,
28130 int_not_coercible: Int,28142 int_not_coercible: Int,
28131 comptime_int_not_coercible: TypeValuePair,28143 comptime_int_not_coercible: TypeValuePair,
...@@ -28160,7 +28172,6 @@ const InMemoryCoercionResult = union(enum) {...@@ -28160,7 +28172,6 @@ const InMemoryCoercionResult = union(enum) {
28160 ptr_alignment: AlignPair,28172 ptr_alignment: AlignPair,
28161 double_ptr_to_anyopaque: Pair,28173 double_ptr_to_anyopaque: Pair,
28162 slice_to_anyopaque: Pair,28174 slice_to_anyopaque: Pair,
28163 ptr_restricted: Pair,
2816428175
28165 const Pair = struct {28176 const Pair = struct {
28166 actual: Type,28177 actual: Type,
...@@ -28247,6 +28258,16 @@ const InMemoryCoercionResult = union(enum) {...@@ -28247,6 +28258,16 @@ const InMemoryCoercionResult = union(enum) {
28247 var cur = res;28258 var cur = res;
28248 while (true) switch (cur.*) {28259 while (true) switch (cur.*) {
28249 .ok => unreachable,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 .no_match => |types| {28271 .no_match => |types| {
28251 try sema.addDeclaredHereNote(msg, types.wanted);28272 try sema.addDeclaredHereNote(msg, types.wanted);
28252 try sema.addDeclaredHereNote(msg, types.actual);28273 try sema.addDeclaredHereNote(msg, types.actual);
...@@ -28492,15 +28513,6 @@ const InMemoryCoercionResult = union(enum) {...@@ -28492,15 +28513,6 @@ const InMemoryCoercionResult = union(enum) {
28492 try sema.errNote(src, msg, "consider using '.ptr'", .{});28513 try sema.errNote(src, msg, "consider using '.ptr'", .{});
28493 break;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,6 +28550,7 @@ pub fn coerceInMemoryAllowed(
28538) CompileError!InMemoryCoercionResult {28550) CompileError!InMemoryCoercionResult {
28539 const pt = sema.pt;28551 const pt = sema.pt;
28540 const zcu = pt.zcu;28552 const zcu = pt.zcu;
28553 const ip = &zcu.intern_pool;
2854128554
28542 if (src_val) |val| {28555 if (src_val) |val| {
28543 assert(val.typeOf(zcu).toIntern() == src_ty.toIntern());28556 assert(val.typeOf(zcu).toIntern() == src_ty.toIntern());
...@@ -28546,6 +28559,12 @@ pub fn coerceInMemoryAllowed(...@@ -28546,6 +28559,12 @@ pub fn coerceInMemoryAllowed(
28546 if (dest_ty.eql(src_ty, zcu))28559 if (dest_ty.eql(src_ty, zcu))
28547 return .ok;28560 return .ok;
2854828561
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 const dest_tag = dest_ty.zigTypeTag(zcu);28568 const dest_tag = dest_ty.zigTypeTag(zcu);
28550 const src_tag = src_ty.zigTypeTag(zcu);28569 const src_tag = src_ty.zigTypeTag(zcu);
2855128570
...@@ -29142,12 +29161,6 @@ fn coerceInMemoryAllowedPtrs(...@@ -29142,12 +29161,6 @@ fn coerceInMemoryAllowedPtrs(
29142 }29161 }
29143 }29162 }
2914429163
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 return .ok;29164 return .ok;
29152}29165}
2915329166
...@@ -29295,7 +29308,7 @@ fn storePtr2(...@@ -29295,7 +29308,7 @@ fn storePtr2(
29295 try sema.requireRuntimeBlock(block, src, runtime_src);29308 try sema.requireRuntimeBlock(block, src, runtime_src);
2929629309
29297 const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty|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 else29312 else
29300 ptr;29313 ptr;
2930129314
...@@ -30185,7 +30198,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde...@@ -30185,7 +30198,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde
3018530198
30186 const nav_index = nav: {30199 const nav_index = nav: {
30187 const orig_nav = ip.getNav(orig_nav_index);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 // A pointer to this `Nav` might actually be encoded as a pointer to a different `Nav`30202 // A pointer to this `Nav` might actually be encoded as a pointer to a different `Nav`
30190 // because this is either an `extern` definition or an `extern` alias. (The latter case30203 // because this is either an `extern` definition or an `extern` alias. (The latter case
30191 // is unsolved language weirdness; see https://github.com/ziglang/zig/issues/21027.) To30204 // 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,7 +30279,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i
3026630279
30267 try sema.ensureNavResolved(block, src, nav_index, .type);30280 try sema.ensureNavResolved(block, src, nav_index, .type);
30268 const nav_ty: Type = .fromInterned(ip.getNav(nav_index).resolved.?.type);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 if (!nav_ty.fnHasRuntimeBits(zcu)) return;30283 if (!nav_ty.fnHasRuntimeBits(zcu)) return;
3027130284
30272 try sema.ensureNavResolved(block, src, nav_index, .fully);30285 try sema.ensureNavResolved(block, src, nav_index, .fully);
...@@ -30349,8 +30362,9 @@ fn analyzeLoad(...@@ -30349,8 +30362,9 @@ fn analyzeLoad(
30349 const pt = sema.pt;30362 const pt = sema.pt;
30350 const zcu = pt.zcu;30363 const zcu = pt.zcu;
30351 const ptr_ty = sema.typeOf(ptr);30364 const ptr_ty = sema.typeOf(ptr);
30352 const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) {30365 const unrestricted_ptr_ty = ptr_ty.unrestrictedType(zcu) orelse ptr_ty;
30353 .pointer => ptr_ty.childType(zcu),30366 const elem_ty = switch (unrestricted_ptr_ty.zigTypeTag(zcu)) {
30367 .pointer => unrestricted_ptr_ty.childType(zcu),
30354 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),30368 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),
30355 };30369 };
3035630370
...@@ -30379,8 +30393,8 @@ fn analyzeLoad(...@@ -30379,8 +30393,8 @@ fn analyzeLoad(
30379 break :msg msg;30393 break :msg msg;
30380 });30394 });
3038130395
30382 const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty|30396 const unrestricted_ptr = if (unrestricted_ptr_ty.toIntern() != ptr_ty.toIntern())
30383 try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src)30397 try sema.unwrapRestricted(block, unrestricted_ptr_ty, ptr, ptr_src)
30384 else30398 else
30385 ptr;30399 ptr;
3038630400
...@@ -31596,17 +31610,17 @@ fn wrapErrorUnionSet(...@@ -31596,17 +31610,17 @@ fn wrapErrorUnionSet(
31596 }31610 }
31597}31611}
3159831612
31599fn unwrapRestrictedPtr(31613fn unwrapRestricted(
31600 sema: *Sema,31614 sema: *Sema,
31601 block: *Block,31615 block: *Block,
31602 unrestricted_ptr_ty: Type,31616 unrestricted_ty: Type,
31603 ptr: Air.Inst.Ref,31617 ptr: Air.Inst.Ref,
31604 ptr_src: LazySrcLoc,31618 ptr_src: LazySrcLoc,
31605) !Air.Inst.Ref {31619) !Air.Inst.Ref {
31606 return block.addTyOp(if (block.wantSafety()) tag: {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 break :tag .unwrap_restricted_safe;31622 break :tag .unwrap_restricted_safe;
31609 } else .unwrap_restricted, unrestricted_ptr_ty, ptr);31623 } else .unwrap_restricted, unrestricted_ty, ptr);
31610}31624}
3161131625
31612/// Returns the enum tag value for the active tag of a tagged union value.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,7 +34445,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
34431 .@"panic.copyLenMismatch",34445 .@"panic.copyLenMismatch",
34432 .@"panic.memcpyAlias",34446 .@"panic.memcpyAlias",
34433 .@"panic.noreturnReturned",34447 .@"panic.noreturnReturned",
34434 .@"panic.corruptRestrictedPointer",34448 .@"panic.corruptRestrictedValue",
34435 => try pt.funcType(.{34449 => try pt.funcType(.{
34436 .param_types = &.{},34450 .param_types = &.{},
34437 .return_type = .noreturn_type,34451 .return_type = .noreturn_type,
src/Sema/bitcast.zig+3-1
...@@ -239,13 +239,13 @@ const UnpackValueBits = struct {...@@ -239,13 +239,13 @@ const UnpackValueBits = struct {
239 switch (ip.indexToKey(val.toIntern())) {239 switch (ip.indexToKey(val.toIntern())) {
240 .int_type,240 .int_type,
241 .ptr_type,241 .ptr_type,
242 .restricted_ptr_type,
243 .array_type,242 .array_type,
244 .vector_type,243 .vector_type,
245 .opt_type,244 .opt_type,
246 .anyframe_type,245 .anyframe_type,
247 .error_union_type,246 .error_union_type,
248 .simple_type,247 .simple_type,
248 .restricted_type,
249 .struct_type,249 .struct_type,
250 .tuple_type,250 .tuple_type,
251 .union_type,251 .union_type,
...@@ -274,6 +274,8 @@ const UnpackValueBits = struct {...@@ -274,6 +274,8 @@ const UnpackValueBits = struct {
274274
275 .bitpack => |bitpack| try unpack.primitive(.fromInterned(bitpack.backing_int_val)),275 .bitpack => |bitpack| try unpack.primitive(.fromInterned(bitpack.backing_int_val)),
276276
277 .restricted_value => |restricted_value| try unpack.add(.fromInterned(restricted_value.unrestricted_value)),
278
277 .aggregate => switch (ty.zigTypeTag(zcu)) {279 .aggregate => switch (ty.zigTypeTag(zcu)) {
278 .vector => {280 .vector => {
279 const len: usize = @intCast(ty.arrayLen(zcu));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,7 +84,6 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons
84 switch (ip.indexToKey(ty.toIntern())) {84 switch (ip.indexToKey(ty.toIntern())) {
85 .int_type,85 .int_type,
86 .ptr_type,86 .ptr_type,
87 .restricted_ptr_type,
88 .anyframe_type,87 .anyframe_type,
89 .simple_type,88 .simple_type,
90 .opaque_type,89 .opaque_type,
...@@ -106,6 +105,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons...@@ -106,6 +105,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons
106 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {105 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {
107 try ensureLayoutResolvedInner(sema, .fromInterned(field_ty), orig_ty, reason);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 .struct_type, .union_type, .enum_type => {109 .struct_type, .union_type, .enum_type => {
110 try sema.declareDependency(.{ .type_layout = ty.toIntern() });110 try sema.declareDependency(.{ .type_layout = ty.toIntern() });
111 try sema.addReferenceEntry(null, reason.src, .wrap(.{ .type_layout = ty.toIntern() }));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,6 +132,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons
132 .aggregate,132 .aggregate,
133 .un,133 .un,
134 .bitpack,134 .bitpack,
135 .restricted_value,
135 // memoization, not types136 // memoization, not types
136 .memoized_call,137 .memoized_call,
137 => unreachable,138 => unreachable,
src/Type.zig+167-122
...@@ -165,7 +165,6 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {...@@ -165,7 +165,6 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
165 .error_set_type,165 .error_set_type,
166 .inferred_error_set_type,166 .inferred_error_set_type,
167 .ptr_type,167 .ptr_type,
168 .restricted_ptr_type,
169 .anyframe_type,168 .anyframe_type,
170 => .runtime,169 => .runtime,
171170
...@@ -201,6 +200,10 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {...@@ -201,6 +200,10 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
201 cur_ty = .fromInterned(child_ty_ip);200 cur_ty = .fromInterned(child_ty_ip);
202 continue;201 continue;
203 },202 },
203 .restricted_type => |restricted_type| {
204 cur_ty = .fromInterned(restricted_type.unrestricted_type);
205 continue;
206 },
204 .tuple_type => |tuple| {207 .tuple_type => |tuple| {
205 @branchHint(.unlikely);208 @branchHint(.unlikely);
206 break classifyTuple(tuple.types.get(ip), tuple.values.get(ip), zcu);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,6 +257,7 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
254 .aggregate,257 .aggregate,
255 .un,258 .un,
256 .bitpack,259 .bitpack,
260 .restricted_value,
257 // memoization, not types261 // memoization, not types
258 .memoized_call,262 .memoized_call,
259 => unreachable,263 => unreachable,
...@@ -374,28 +378,13 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo {...@@ -374,28 +378,13 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo {
374}378}
375379
376pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType {380pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType {
377 return ty.ptrInfoOrNull(&zcu.intern_pool, .{}).?;381 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
378}
379
380pub 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())) {
385 .ptr_type => |p| p,382 .ptr_type => |p| p,
386 .restricted_ptr_type => |rp| if (opts.allow_restricted)383 .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) {
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)) {
391 .ptr_type => |p| p,384 .ptr_type => |p| p,
392 .restricted_ptr_type => |rp| if (opts.allow_restricted)385 else => unreachable,
393 ip.indexToKey(rp.unrestricted_ptr_type).ptr_type386 },
394 else387 else => unreachable,
395 null,
396 else => null, // not a pointer type
397 } else null,
398 else => null, // not a pointer type
399 };388 };
400}389}
401390
...@@ -504,10 +493,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari...@@ -504,10 +493,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
504 try print(Type.fromInterned(info.child), writer, pt, ctx);493 try print(Type.fromInterned(info.child), writer, pt, ctx);
505 return;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 .array_type => |array_type| {496 .array_type => |array_type| {
512 if (array_type.sentinel == .none) {497 if (array_type.sentinel == .none) {
513 try writer.print("[{d}]", .{array_type.len});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,6 +592,10 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
607592
608 .generic_poison => unreachable,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 .struct_type => {599 .struct_type => {
611 const name = ip.loadStructType(ty.toIntern()).name;600 const name = ip.loadStructType(ty.toIntern()).name;
612 try writer.print("{f}", .{name.fmt(ip)});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,6 +697,7 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
708 .aggregate,697 .aggregate,
709 .un,698 .un,
710 .bitpack,699 .bitpack,
700 .restricted_value,
711 // memoization, not types701 // memoization, not types
712 .memoized_call,702 .memoized_call,
713 => unreachable,703 => unreachable,
...@@ -767,13 +757,13 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -767,13 +757,13 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
767 .vector_type,757 .vector_type,
768 => true,758 => true,
769759
770 .restricted_ptr_type,
771 .error_union_type,760 .error_union_type,
772 .error_set_type,761 .error_set_type,
773 .inferred_error_set_type,762 .inferred_error_set_type,
774 .tuple_type,763 .tuple_type,
775 .opaque_type,764 .opaque_type,
776 .anyframe_type,765 .anyframe_type,
766 .restricted_type,
777 // These are function bodies, not function pointers.767 // These are function bodies, not function pointers.
778 .func_type,768 .func_type,
779 => false,769 => false,
...@@ -847,6 +837,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -847,6 +837,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
847 .aggregate,837 .aggregate,
848 .un,838 .un,
849 .bitpack,839 .bitpack,
840 .restricted_value,
850 // memoization, not types841 // memoization, not types
851 .memoized_call,842 .memoized_call,
852 => unreachable,843 => unreachable,
...@@ -898,10 +889,7 @@ pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool {...@@ -898,10 +889,7 @@ pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool {
898889
899/// Like `hasRuntimeBits`, but also returns `true` for runtime functions.890/// Like `hasRuntimeBits`, but also returns `true` for runtime functions.
900pub fn isRuntimeFnOrHasRuntimeBits(ty: Type, zcu: *const Zcu) bool {891pub fn isRuntimeFnOrHasRuntimeBits(ty: Type, zcu: *const Zcu) bool {
901 switch (ty.zigTypeTag(zcu)) {892 return if (zcu.intern_pool.isFunctionType(ty.toIntern())) ty.fnHasRuntimeBits(zcu) else ty.hasRuntimeBits(zcu);
902 .@"fn" => return ty.fnHasRuntimeBits(zcu),
903 else => return ty.hasRuntimeBits(zcu),
904 }
905}893}
906894
907/// Returns whether `ty` is NPV, meaning it is "like `noreturn`" in a sense. See doc comments on895/// 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,13 +902,22 @@ pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool {
914902
915/// Never returns `none`. Asserts that all necessary type resolution is already done.903/// Never returns `none`. Asserts that all necessary type resolution is already done.
916pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment {904pub 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 if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment;911 if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment;
919 return Type.fromInterned(ptr_key.child).abiAlignment(zcu);912 return Type.fromInterned(ptr_key.child).abiAlignment(zcu);
920}913}
921914
922pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace {915pub 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}
925922
926/// Never returns `.none`. Asserts that the layout of `ty` is resolved.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,7 +933,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
936 if (int_type.bits == 0) return .@"1";933 if (int_type.bits == 0) return .@"1";
937 return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits));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 .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu),937 .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu),
941 .vector_type => |vector_type| {938 .vector_type => |vector_type| {
942 if (vector_type.len == 0) return .@"1";939 if (vector_type.len == 0) return .@"1";
...@@ -1020,6 +1017,10 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {...@@ -1020,6 +1017,10 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
10201017
1021 .generic_poison => unreachable,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 .tuple_type => |tuple| {1024 .tuple_type => |tuple| {
1024 var big_align: Alignment = .@"1";1025 var big_align: Alignment = .@"1";
1025 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {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,6 +1070,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
1069 .aggregate,1070 .aggregate,
1070 .un,1071 .un,
1071 .bitpack,1072 .bitpack,
1073 .restricted_value,
1072 // memoization, not types1074 // memoization, not types
1073 .memoized_call,1075 .memoized_call,
1074 => unreachable,1076 => unreachable,
...@@ -1090,7 +1092,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1090,7 +1092,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1090 .slice => ptrAbiSize(target) * 2,1092 .slice => ptrAbiSize(target) * 2,
1091 .one, .many, .c => ptrAbiSize(target),1093 .one, .many, .c => ptrAbiSize(target),
1092 },1094 },
1093 .restricted_ptr_type, .anyframe_type => ptrAbiSize(target),1095 .anyframe_type => ptrAbiSize(target),
1094 .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu),1096 .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu),
1095 .vector_type => |vec| {1097 .vector_type => |vec| {
1096 const elem_ty: Type = .fromInterned(vec.child);1098 const elem_ty: Type = .fromInterned(vec.child);
...@@ -1169,6 +1171,10 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1169,6 +1171,10 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1169 .anyopaque => unreachable,1171 .anyopaque => unreachable,
1170 .generic_poison => unreachable,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 .tuple_type => |tuple| switch (ty.classify(zcu)) {1178 .tuple_type => |tuple| switch (ty.classify(zcu)) {
1173 // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with1179 // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with
1174 // non-zero size.1180 // non-zero size.
...@@ -1209,6 +1215,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1209,6 +1215,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1209 .aggregate,1215 .aggregate,
1210 .un,1216 .un,
1211 .bitpack,1217 .bitpack,
1218 .restricted_value,
1212 // memoization, not types1219 // memoization, not types
1213 .memoized_call,1220 .memoized_call,
1214 => unreachable,1221 => unreachable,
...@@ -1243,7 +1250,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1243,7 +1250,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
1243 .slice => target.ptrBitWidth() * 2,1250 .slice => target.ptrBitWidth() * 2,
1244 else => target.ptrBitWidth(),1251 else => target.ptrBitWidth(),
1245 },1252 },
1246 .restricted_ptr_type, .anyframe_type => target.ptrBitWidth(),1253 .anyframe_type => target.ptrBitWidth(),
1247 .array_type => |array_type| {1254 .array_type => |array_type| {
1248 const elem_ty: Type = .fromInterned(array_type.child);1255 const elem_ty: Type = .fromInterned(array_type.child);
1249 const len = array_type.lenIncludingSentinel();1256 const len = array_type.lenIncludingSentinel();
...@@ -1294,6 +1301,10 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1294,6 +1301,10 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
1294 .generic_poison => unreachable,1301 .generic_poison => unreachable,
1295 },1302 },
12961303
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 .struct_type => {1308 .struct_type => {
1298 const struct_obj = ip.loadStructType(ty.toIntern());1309 const struct_obj = ip.loadStructType(ty.toIntern());
1299 switch (struct_obj.layout) {1310 switch (struct_obj.layout) {
...@@ -1335,29 +1346,27 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1335,29 +1346,27 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
1335 .aggregate,1346 .aggregate,
1336 .un,1347 .un,
1337 .bitpack,1348 .bitpack,
1349 .restricted_value,
1338 // memoization, not types1350 // memoization, not types
1339 .memoized_call,1351 .memoized_call,
1340 => unreachable,1352 => unreachable,
1341 };1353 };
1342}1354}
13431355
1344/// Returns `null` if `ty` is not a restricted pointer.1356/// Returns `null` if `ty` is not a restricted type.
1345pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {1357pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {
1346 const ip = &zcu.intern_pool;1358 const ip = &zcu.intern_pool;
1347 return switch (ip.indexToKey(ty.toIntern())) {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 else => null,1361 else => null,
1350 };1362 };
1351}1363}
13521364
1353const RestrictedRepr = enum { indirect, direct };1365const RestrictedRepr = enum { indirect, direct };
1354pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr {1366pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr {
1355 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1367 return restrictedReprByTrackedInst(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_type.zir_index, zcu);
1356 .restricted_ptr_type => |restricted_ptr_type| restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu),
1357 else => .direct,
1358 };
1359}1368}
1360pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {1369pub fn restrictedReprByTrackedInst(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {
1361 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {1370 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {
1362 .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct,1371 .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct,
1363 .ReleaseFast, .ReleaseSmall => .direct,1372 .ReleaseFast, .ReleaseSmall => .direct,
...@@ -1365,8 +1374,10 @@ pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *c...@@ -1365,8 +1374,10 @@ pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *c
1365}1374}
13661375
1367pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool {1376pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool {
1368 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;1377 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1369 return ptr_info.flags.size == .one;1378 .ptr_type => |ptr_info| ptr_info.flags.size == .one,
1379 else => false,
1380 };
1370}1381}
13711382
1372/// Asserts `ty` is a pointer.1383/// Asserts `ty` is a pointer.
...@@ -1376,27 +1387,24 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size {...@@ -1376,27 +1387,24 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size {
13761387
1377/// Returns `null` if `ty` is not a pointer.1388/// Returns `null` if `ty` is not a pointer.
1378pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size {1389pub 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;1390 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1380 return ptr_info.flags.size;1391 .ptr_type => |ptr_info| ptr_info.flags.size,
1392 else => null,
1393 };
1381}1394}
13821395
1383pub fn isSlice(ty: Type, zcu: *const Zcu) bool {1396pub fn isSlice(ty: Type, zcu: *const Zcu) bool {
1384 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;1397 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1385 return ptr_info.flags.size == .slice;1398 .ptr_type => |ptr_type| ptr_type.flags.size == .slice,
1399 else => false,
1400 };
1386}1401}
13871402
1388pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {1403pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {
1389 const ip = &zcu.intern_pool;1404 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1390 return ty: switch (ip.indexToKey(ty.toIntern())) {
1391 .ptr_type => |ptr_type| ptr_type.flags.size == .slice,1405 .ptr_type => |ptr_type| ptr_type.flags.size == .slice,
1392 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{1406 .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) {
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)) {
1396 .ptr_type => |ptr_type| !ptr_type.flags.is_allowzero and ptr_type.flags.size == .slice,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 else => false,1408 else => false,
1401 },1409 },
1402 else => false,1410 else => false,
...@@ -1408,8 +1416,10 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type {...@@ -1408,8 +1416,10 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type {
1408}1416}
14091417
1410pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {1418pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {
1411 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;1419 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1412 return ptr_info.flags.is_const;1420 .ptr_type => |ptr_type| ptr_type.flags.is_const,
1421 else => false,
1422 };
1413}1423}
14141424
1415pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {1425pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {
...@@ -1417,25 +1427,25 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {...@@ -1417,25 +1427,25 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {
1417}1427}
14181428
1419pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool {1429pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool {
1420 const ptr_info = ty.ptrInfoOrNull(ip, .{ .allow_optional = false }) orelse return false;1430 return switch (ip.indexToKey(ty.toIntern())) {
1421 return ptr_info.flags.is_volatile;1431 .ptr_type => |ptr_type| ptr_type.flags.is_volatile,
1432 else => false,
1433 };
1422}1434}
14231435
1424pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool {1436pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool {
1425 const ip = &zcu.intern_pool;1437 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1426 return ty: switch (ip.indexToKey(ty.toIntern())) {
1427 .ptr_type => |ptr_type| ptr_type.flags.is_allowzero,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 .opt_type => true,1439 .opt_type => true,
1432 else => false,1440 else => false,
1433 };1441 };
1434}1442}
14351443
1436pub fn isCPtr(ty: Type, zcu: *const Zcu) bool {1444pub fn isCPtr(ty: Type, zcu: *const Zcu) bool {
1437 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;1445 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1438 return ptr_info.flags.size == .c;1446 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1447 else => false,
1448 };
1439}1449}
14401450
1441pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {1451pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
...@@ -1445,16 +1455,18 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {...@@ -1445,16 +1455,18 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
1445 .slice => false,1455 .slice => false,
1446 .one, .many, .c => true,1456 .one, .many, .c => true,
1447 },1457 },
1448 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{1458 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1449 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,1459 .indirect => true,
1460 .direct => continue :ty ip.indexToKey(restricted_type.unrestricted_type),
1450 },1461 },
1451 .opt_type => |child| opt_child: switch (ip.indexToKey(child)) {1462 .opt_type => |child| opt_child: switch (ip.indexToKey(child)) {
1452 .ptr_type => |p| switch (p.flags.size) {1463 .ptr_type => |p| switch (p.flags.size) {
1453 .slice, .c => false,1464 .slice, .c => false,
1454 .many, .one => !p.flags.is_allowzero,1465 .many, .one => !p.flags.is_allowzero,
1455 },1466 },
1456 .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{1467 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1457 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,1468 .indirect => true,
1469 .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type),
1458 },1470 },
1459 else => false,1471 else => false,
1460 },1472 },
...@@ -1473,17 +1485,19 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {...@@ -1473,17 +1485,19 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {
1473 const ip = &zcu.intern_pool;1485 const ip = &zcu.intern_pool;
1474 return ty: switch (ip.indexToKey(ty.toIntern())) {1486 return ty: switch (ip.indexToKey(ty.toIntern())) {
1475 .ptr_type => |ptr_type| ptr_type.flags.size == .c,1487 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1476 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{1488 .opt_type => |opt_child_type| opt_child_type == .anyerror_type or opt_child: switch (ip.indexToKey(opt_child_type)) {
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)) {
1480 .ptr_type => |ptr_type| ptr_type.flags.size != .c and !ptr_type.flags.is_allowzero,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 .error_set_type, .inferred_error_set_type => true,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 else => false,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 else => false,1501 else => false,
1488 };1502 };
1489}1503}
...@@ -1494,19 +1508,21 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {...@@ -1494,19 +1508,21 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
1494 const ip = &zcu.intern_pool;1508 const ip = &zcu.intern_pool;
1495 return ty: switch (ip.indexToKey(ty.toIntern())) {1509 return ty: switch (ip.indexToKey(ty.toIntern())) {
1496 .ptr_type => |ptr_type| ptr_type.flags.size == .c,1510 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1497 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{1511 .opt_type => |opt_child_type| opt_child: switch (ip.indexToKey(opt_child_type)) {
1498 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1499 },
1500 .opt_type => |child| opt_child: switch (ip.indexToKey(child)) {
1501 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1512 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1502 .slice, .c => false,1513 .slice, .c => false,
1503 .many, .one => !ptr_type.flags.is_allowzero,1514 .many, .one => !ptr_type.flags.is_allowzero,
1504 },1515 },
1505 .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{1516 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1506 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,1517 .indirect => true,
1518 .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type),
1507 },1519 },
1508 else => false,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 else => false,1526 else => false,
1511 };1527 };
1512}1528}
...@@ -1541,7 +1557,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {...@@ -1541,7 +1557,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
1541 .pointer => return ty.childType(zcu),1557 .pointer => return ty.childType(zcu),
1542 .optional => {1558 .optional => {
1543 const ptr_ty = ty.childType(zcu);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 assert(ptr_info.flags.size != .c);1561 assert(ptr_info.flags.size != .c);
1546 assert(!ptr_info.flags.is_allowzero);1562 assert(!ptr_info.flags.is_allowzero);
1547 return .fromInterned(ptr_info.child);1563 return .fromInterned(ptr_info.child);
...@@ -1563,7 +1579,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {...@@ -1563,7 +1579,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
1563/// * `[*c]T`1579/// * `[*c]T`
1564pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {1580pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {
1565 const ip = &zcu.intern_pool;1581 const ip = &zcu.intern_pool;
1566 return ty: switch (ip.indexToKey(ty.toIntern())) {1582 return switch (ip.indexToKey(ty.toIntern())) {
1567 inline .array_type, .vector_type => |arr| .fromInterned(arr.child),1583 inline .array_type, .vector_type => |arr| .fromInterned(arr.child),
1568 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1584 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1569 .many, .slice, .c => .fromInterned(ptr_type.child),1585 .many, .slice, .c => .fromInterned(ptr_type.child),
...@@ -1572,9 +1588,6 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {...@@ -1572,9 +1588,6 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {
1572 else => unreachable,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 else => unreachable,1591 else => unreachable,
1579 };1592 };
1580}1593}
...@@ -1590,16 +1603,12 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {...@@ -1590,16 +1603,12 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {
1590/// Asserts that the type is an optional, or a C pointer.1603/// Asserts that the type is an optional, or a C pointer.
1591/// For C pointers this returns the type unmodified.1604/// For C pointers this returns the type unmodified.
1592pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {1605pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {
1593 const ip = &zcu.intern_pool;1606 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1594 ty: switch (ip.indexToKey(ty.toIntern())) {
1595 .opt_type => |child| return .fromInterned(child),1607 .opt_type => |child| return .fromInterned(child),
1596 .ptr_type => |ptr_type| {1608 .ptr_type => |ptr_type| {
1597 assert(ptr_type.flags.size == .c);1609 assert(ptr_type.flags.size == .c);
1598 return ty;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 else => unreachable,1612 else => unreachable,
1604 }1613 }
1605}1614}
...@@ -1699,6 +1708,15 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo...@@ -1699,6 +1708,15 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo
1699 };1708 };
1700}1709}
17011710
1711pub 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
1702pub fn bitpackBackingInt(ty: Type, zcu: *const Zcu) Type {1720pub fn bitpackBackingInt(ty: Type, zcu: *const Zcu) Type {
1703 const ip = &zcu.intern_pool;1721 const ip = &zcu.intern_pool;
1704 return switch (ip.indexToKey(ty.toIntern())) {1722 return switch (ip.indexToKey(ty.toIntern())) {
...@@ -1728,7 +1746,7 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {...@@ -1728,7 +1746,7 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
1728 const ip = &zcu.intern_pool;1746 const ip = &zcu.intern_pool;
1729 return switch (ty.toIntern()) {1747 return switch (ty.toIntern()) {
1730 .anyerror_type, .adhoc_inferred_error_set_type => false,1748 .anyerror_type, .adhoc_inferred_error_set_type => false,
1731 else => switch (ip.indexToKey(ty.toIntern())) {1749 else => |index| switch (ip.indexToKey(index)) {
1732 .error_set_type => |error_set_type| error_set_type.names.len == 0,1750 .error_set_type => |error_set_type| error_set_type.names.len == 0,
1733 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {1751 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
1734 .none, .anyerror_type => false,1752 .none, .anyerror_type => false,
...@@ -1752,7 +1770,7 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {...@@ -1752,7 +1770,7 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
1752 return switch (ty.toIntern()) {1770 return switch (ty.toIntern()) {
1753 .anyerror_type => true,1771 .anyerror_type => true,
1754 .adhoc_inferred_error_set_type => false,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 .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type,1774 .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type,
1757 else => false,1775 else => false,
1758 },1776 },
...@@ -1760,9 +1778,13 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {...@@ -1760,9 +1778,13 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
1760}1778}
17611779
1762pub fn isError(ty: Type, zcu: *const Zcu) bool {1780pub fn isError(ty: Type, zcu: *const Zcu) bool {
1763 return switch (ty.zigTypeTag(zcu)) {1781 return switch (ty.toIntern()) {
1764 .error_union, .error_set => true,1782 .anyerror_type, .adhoc_inferred_error_set_type, .anyerror_void_error_union_type => true,
1765 else => false,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}
17681790
...@@ -1782,7 +1804,7 @@ pub fn errorSetHasField(...@@ -1782,7 +1804,7 @@ pub fn errorSetHasField(
1782 const ip = &zcu.intern_pool;1804 const ip = &zcu.intern_pool;
1783 return switch (ty.toIntern()) {1805 return switch (ty.toIntern()) {
1784 .anyerror_type => true,1806 .anyerror_type => true,
1785 else => switch (ip.indexToKey(ty.toIntern())) {1807 else => |index| switch (ip.indexToKey(index)) {
1786 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,1808 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
1787 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {1809 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
1788 .anyerror_type => true,1810 .anyerror_type => true,
...@@ -1817,8 +1839,7 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {...@@ -1817,8 +1839,7 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {
18171839
1818/// Asserts the type is an array, pointer or vector.1840/// Asserts the type is an array, pointer or vector.
1819pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {1841pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
1820 const ip = &zcu.intern_pool;1842 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1821 return ty: switch (ip.indexToKey(ty.toIntern())) {
1822 .vector_type,1843 .vector_type,
1823 .struct_type,1844 .struct_type,
1824 .tuple_type,1845 .tuple_type,
...@@ -1826,9 +1847,6 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {...@@ -1826,9 +1847,6 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
18261847
1827 .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,1848 .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,
1828 .ptr_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,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 },
18321850
1833 else => unreachable,1851 else => unreachable,
1834 };1852 };
...@@ -1867,10 +1885,27 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {...@@ -1867,10 +1885,27 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {
1867/// Returns true for integers, enums, error sets, and packed structs/unions.1885/// Returns true for integers, enums, error sets, and packed structs/unions.
1868/// If this function returns true, then intInfo() can be called on the type.1886/// If this function returns true, then intInfo() can be called on the type.
1869pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {1887pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {
1870 return switch (ty.zigTypeTag(zcu)) {1888 const ip = &zcu.intern_pool;
1871 .int, .@"enum", .error_set => true,1889 return switch (ty.toIntern()) {
1872 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",1890 .usize_type,
1873 else => false,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}
18761911
...@@ -1914,10 +1949,10 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -1914,10 +1949,10 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
1914 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };1949 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };
1915 },1950 },
19161951
1952 .restricted_type => unreachable,
1917 .tuple_type => unreachable,1953 .tuple_type => unreachable,
19181954
1919 .ptr_type => unreachable,1955 .ptr_type => unreachable,
1920 .restricted_ptr_type => unreachable,
1921 .anyframe_type => unreachable,1956 .anyframe_type => unreachable,
1922 .array_type => unreachable,1957 .array_type => unreachable,
19231958
...@@ -1945,6 +1980,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -1945,6 +1980,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
1945 .aggregate,1980 .aggregate,
1946 .un,1981 .un,
1947 .bitpack,1982 .bitpack,
1983 .restricted_value,
1948 // memoization, not types1984 // memoization, not types
1949 .memoized_call,1985 .memoized_call,
1950 => unreachable,1986 => unreachable,
...@@ -2070,7 +2106,6 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {...@@ -2070,7 +2106,6 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {
2070 .c_longlong_type,2106 .c_longlong_type,
2071 .c_ulonglong_type,2107 .c_ulonglong_type,
2072 => true,2108 => true,
2073
2074 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {2109 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
2075 .int_type => true,2110 .int_type => true,
2076 else => false,2111 else => false,
...@@ -2088,7 +2123,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {...@@ -2088,7 +2123,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
2088 assertHasLayout(ty, zcu);2123 assertHasLayout(ty, zcu);
2089 return switch (ip.indexToKey(ty.toIntern())) {2124 return switch (ip.indexToKey(ty.toIntern())) {
2090 .ptr_type,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 .error_union_type,2126 .error_union_type,
2093 .func_type,2127 .func_type,
2094 .anyframe_type,2128 .anyframe_type,
...@@ -2152,6 +2186,13 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {...@@ -2152,6 +2186,13 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
2152 .no_possible_value => try pt.nullValue(ty),2186 .no_possible_value => try pt.nullValue(ty),
2153 else => null,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 .tuple_type => |tuple| {2196 .tuple_type => |tuple| {
2156 // Check *whether* the OPV exists first, because constructing it is a little more expensive.2197 // Check *whether* the OPV exists first, because constructing it is a little more expensive.
2157 if (ty.classify(zcu) != .one_possible_value) return null;2198 if (ty.classify(zcu) != .one_possible_value) return null;
...@@ -2240,6 +2281,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {...@@ -2240,6 +2281,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
2240 .aggregate,2281 .aggregate,
2241 .un,2282 .un,
2242 .bitpack,2283 .bitpack,
2284 .restricted_value,
2243 // memoization, not types2285 // memoization, not types
2244 .memoized_call,2286 .memoized_call,
2245 => unreachable,2287 => unreachable,
...@@ -2249,7 +2291,8 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {...@@ -2249,7 +2291,8 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
2249/// Asserts that `ty` has its layout resolved. `generic_poison` will return `false`.2291/// Asserts that `ty` has its layout resolved. `generic_poison` will return `false`.
2250pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {2292pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
2251 if (ty.toIntern() == .generic_poison_type) return false;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 return switch (ty.classify(zcu)) {2296 return switch (ty.classify(zcu)) {
2254 .no_possible_value, .one_possible_value, .runtime => false,2297 .no_possible_value, .one_possible_value, .runtime => false,
2255 .partially_comptime, .fully_comptime => true,2298 .partially_comptime, .fully_comptime => true,
...@@ -2257,7 +2300,7 @@ pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {...@@ -2257,7 +2300,7 @@ pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
2257}2300}
22582301
2259pub fn isVector(ty: Type, zcu: *const Zcu) bool {2302pub fn isVector(ty: Type, zcu: *const Zcu) bool {
2260 return ty.zigTypeTag(zcu) == .vector;2303 return zcu.intern_pool.isVectorType(ty.toIntern());
2261}2304}
22622305
2263/// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len.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,7 +2716,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
2673 const ip = &zcu.intern_pool;2716 const ip = &zcu.intern_pool;
2674 return .{2717 return .{
2675 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {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 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {2720 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2678 .declared => |d| d.zir_index,2721 .declared => |d| d.zir_index,
2679 .reified => |r| r.zir_index,2722 .reified => |r| r.zir_index,
...@@ -2898,7 +2941,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -2898,7 +2941,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
2898pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type {2941pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type {
2899 const zcu = pt.zcu;2942 const zcu = pt.zcu;
2900 const ip = &zcu.intern_pool;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 const elem_ty: Type = switch (ptr_info.flags.size) {2945 const elem_ty: Type = switch (ptr_info.flags.size) {
2903 .slice, .many, .c => .fromInterned(ptr_info.child),2946 .slice, .many, .c => .fromInterned(ptr_info.child),
2904 .one => switch (ip.indexToKey(ptr_info.child)) {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,7 +2995,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error
2952pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type {2995pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type {
2953 const zcu = pt.zcu;2996 const zcu = pt.zcu;
2954 const ip = &zcu.intern_pool;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 assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c);2999 assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c);
2957 const aggregate_ty: Type = .fromInterned(ptr_info.child);3000 const aggregate_ty: Type = .fromInterned(ptr_info.child);
2958 aggregate_ty.assertHasLayout(zcu);3001 aggregate_ty.assertHasLayout(zcu);
...@@ -3080,7 +3123,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator...@@ -3080,7 +3123,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator
3080 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {3123 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {
3081 .tuple_type, .union_type => field_ty.abiAlignment(zcu),3124 .tuple_type, .union_type => field_ty.abiAlignment(zcu),
3082 .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu),3125 .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu),
3083 .ptr_type, .restricted_ptr_type => ptrAbiAlignment(zcu.getTarget()),3126 .ptr_type => ptrAbiAlignment(zcu.getTarget()),
3084 else => unreachable,3127 else => unreachable,
3085 },3128 },
3086 else => |a| a,3129 else => |a| a,
...@@ -3109,7 +3152,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator...@@ -3109,7 +3152,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator
31093152
3110pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {3153pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
3111 return switch (ip.indexToKey(ty.toIntern())) {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 .struct_type => ip.loadStructType(ty.toIntern()).name,3156 .struct_type => ip.loadStructType(ty.toIntern()).name,
3114 .union_type => ip.loadUnionType(ty.toIntern()).name,3157 .union_type => ip.loadUnionType(ty.toIntern()).name,
3115 .enum_type => ip.loadEnumType(ty.toIntern()).name,3158 .enum_type => ip.loadEnumType(ty.toIntern()).name,
...@@ -3317,7 +3360,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {...@@ -3317,7 +3360,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3317 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {3360 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
3318 .int_type,3361 .int_type,
3319 .ptr_type,3362 .ptr_type,
3320 .restricted_ptr_type,
3321 .anyframe_type,3363 .anyframe_type,
3322 .simple_type,3364 .simple_type,
3323 .opaque_type,3365 .opaque_type,
...@@ -3337,6 +3379,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {...@@ -3337,6 +3379,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3337 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {3379 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {
3338 assertHasLayout(.fromInterned(field_ty), zcu);3380 assertHasLayout(.fromInterned(field_ty), zcu);
3339 },3381 },
3382 .restricted_type => |restricted_type| assertHasLayout(.fromInterned(restricted_type.unrestricted_type), zcu),
3340 .struct_type => {3383 .struct_type => {
3341 assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout);3384 assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout);
3342 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));3385 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));
...@@ -3351,6 +3394,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {...@@ -3351,6 +3394,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3351 },3394 },
33523395
3353 // values, not types3396 // values, not types
3397 .undef,
3354 .simple_value,3398 .simple_value,
3355 .@"extern",3399 .@"extern",
3356 .func,3400 .func,
...@@ -3366,7 +3410,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {...@@ -3366,7 +3410,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3366 .aggregate,3410 .aggregate,
3367 .un,3411 .un,
3368 .bitpack,3412 .bitpack,
3369 .undef,3413 .restricted_value,
3370 // memoization, not types3414 // memoization, not types
3371 .memoized_call,3415 .memoized_call,
3372 => unreachable,3416 => unreachable,
...@@ -3419,13 +3463,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn...@@ -3419,13 +3463,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
3419 .undef,3463 .undef,
3420 .inferred_error_set_type,3464 .inferred_error_set_type,
3421 .error_set_type,3465 .error_set_type,
3466 .restricted_type,
3422 .struct_type,3467 .struct_type,
3423 .union_type,3468 .union_type,
3424 .opaque_type,3469 .opaque_type,
3425 .enum_type,3470 .enum_type,
3426 .simple_type,3471 .simple_type,
3427 .int_type,3472 .int_type,
3428 .restricted_ptr_type,
3429 => {},3473 => {},
34303474
3431 // values, not types3475 // values, not types
...@@ -3444,6 +3488,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn...@@ -3444,6 +3488,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
3444 .aggregate,3488 .aggregate,
3445 .un,3489 .un,
3446 .bitpack,3490 .bitpack,
3491 .restricted_value,
3447 // memoization, not types3492 // memoization, not types
3448 .memoized_call,3493 .memoized_call,
3449 => unreachable,3494 => unreachable,
src/Zcu.zig+8-7
...@@ -501,7 +501,7 @@ pub const BuiltinDecl = enum {...@@ -501,7 +501,7 @@ pub const BuiltinDecl = enum {
501 @"panic.copyLenMismatch",501 @"panic.copyLenMismatch",
502 @"panic.memcpyAlias",502 @"panic.memcpyAlias",
503 @"panic.noreturnReturned",503 @"panic.noreturnReturned",
504 @"panic.corruptRestrictedPointer",504 @"panic.corruptRestrictedValue",
505505
506 VaList,506 VaList,
507507
...@@ -589,7 +589,7 @@ pub const BuiltinDecl = enum {...@@ -589,7 +589,7 @@ pub const BuiltinDecl = enum {
589 .@"panic.copyLenMismatch",589 .@"panic.copyLenMismatch",
590 .@"panic.memcpyAlias",590 .@"panic.memcpyAlias",
591 .@"panic.noreturnReturned",591 .@"panic.noreturnReturned",
592 .@"panic.corruptRestrictedPointer",592 .@"panic.corruptRestrictedValue",
593 => .func,593 => .func,
594 };594 };
595 }595 }
...@@ -663,7 +663,7 @@ pub const SimplePanicId = enum {...@@ -663,7 +663,7 @@ pub const SimplePanicId = enum {
663 copy_len_mismatch,663 copy_len_mismatch,
664 memcpy_alias,664 memcpy_alias,
665 noreturn_returned,665 noreturn_returned,
666 corrupt_restricted_pointer,666 corrupt_restricted_value,
667667
668 pub fn toBuiltin(id: SimplePanicId) BuiltinDecl {668 pub fn toBuiltin(id: SimplePanicId) BuiltinDecl {
669 return switch (id) {669 return switch (id) {
...@@ -687,7 +687,7 @@ pub const SimplePanicId = enum {...@@ -687,7 +687,7 @@ pub const SimplePanicId = enum {
687 .copy_len_mismatch => .@"panic.copyLenMismatch",687 .copy_len_mismatch => .@"panic.copyLenMismatch",
688 .memcpy_alias => .@"panic.memcpyAlias",688 .memcpy_alias => .@"panic.memcpyAlias",
689 .noreturn_returned => .@"panic.noreturnReturned",689 .noreturn_returned => .@"panic.noreturnReturned",
690 .corrupt_restricted_pointer => .@"panic.corruptRestrictedPointer",690 .corrupt_restricted_value => .@"panic.corruptRestrictedValue",
691 // zig fmt: on691 // zig fmt: on
692 };692 };
693 }693 }
...@@ -2748,12 +2748,13 @@ pub const LazySrcLoc = struct {...@@ -2748,12 +2748,13 @@ pub const LazySrcLoc = struct {
2748 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,2748 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
2749 .extended => switch (inst.data.extended.opcode) {2749 .extended => switch (inst.data.extended.opcode) {
2750 .struct_decl => zir.getStructDecl(zir_inst).src_node,2750 .struct_decl => zir.getStructDecl(zir_inst).src_node,
2751 .union_decl => zir.getUnionDecl(zir_inst).src_node,
2752 .enum_decl => zir.getEnumDecl(zir_inst).src_node,2751 .enum_decl => zir.getEnumDecl(zir_inst).src_node,
2752 .union_decl => zir.getUnionDecl(zir_inst).src_node,
2753 .opaque_decl => zir.getOpaqueDecl(zir_inst).src_node,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 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,2755 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
2756 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,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 else => unreachable,2758 else => unreachable,
2758 },2759 },
2759 else => unreachable,2760 else => unreachable,
...@@ -4000,7 +4001,7 @@ pub const Feature = enum {...@@ -4000,7 +4001,7 @@ pub const Feature = enum {
40004001
4001pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {4002pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {
4002 const backend = target_util.zigBackend(&zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);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}
40054006
4006pub const AtomicPtrAlignmentError = error{4007pub const AtomicPtrAlignmentError = error{
src/codegen.zig+89-89
...@@ -232,15 +232,26 @@ const LazySymbolStructure = struct {...@@ -232,15 +232,26 @@ const LazySymbolStructure = struct {
232 operation: Operation,232 operation: Operation,
233233
234 pub const Operation = enum {234 pub const Operation = enum {
235 ptr_inc,235 end_ptr_inc,
236236
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 switch (operation) {241 switch (operation) {
239 .ptr_inc => switch (slice.len) {242 .end_ptr_inc => switch (target_opts.ptr_bit_width) {
240 else => unreachable,243 else => unreachable,
241 2 => std.mem.writeInt(u16, slice[0..2], std.mem.readInt(u16, slice[0..2], endian) + 1, endian),244 inline 16, 32, 64 => |ptr_bit_width| {
242 4 => std.mem.writeInt(u32, slice[0..4], std.mem.readInt(u32, slice[0..4], endian) + 1, endian),245 const ptr_size = @divExact(ptr_bit_width, 8);
243 8 => std.mem.writeInt(u64, slice[0..8], std.mem.readInt(u64, slice[0..8], endian) + 1, endian),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,14 +290,14 @@ pub fn getLazySymbolInfo(
279 .structure => .{},290 .structure => .{},
280 .attributes => .{ .required_alignment = .@"1" },291 .attributes => .{ .required_alignment = .@"1" },
281 },292 },
282 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {293 .restricted_type => |restricted_type| switch (kind) {
283 .structure => .{},294 .structure => .{},
284 .attributes => {295 .attributes => {
285 const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key);296 const restricted_ty: Type = .fromInterned(lazy_sym.key);
286 const unrestricted_ptr_ty: Type =297 const unrestricted_ty: Type =
287 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);298 .fromInterned(restricted_type.unrestricted_type);
288 return .{ .required_alignment = restricted_ptr_ty.abiAlignment(zcu)299 return .{ .required_alignment = restricted_ty.abiAlignment(zcu)
289 .maxStrict(unrestricted_ptr_ty.abiAlignment(zcu)) };300 .maxStrict(unrestricted_ty.abiAlignment(zcu)) };
290 },301 },
291 },302 },
292 },303 },
...@@ -298,31 +309,32 @@ pub fn getLazySymbolInfo(...@@ -298,31 +309,32 @@ pub fn getLazySymbolInfo(
298 },309 },
299 _ => switch (ip.indexToKey(lazy_sym.key)) {310 _ => switch (ip.indexToKey(lazy_sym.key)) {
300 else => unreachable,311 else => unreachable,
301 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {312 .restricted_value => |restricted_value| switch (kind) {
302 else => unreachable,313 .structure => .{ .parent = .{ .kind = .const_data, .key = restricted_value.ty }, .modify = .{
303 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {314 .lazy_sym = .{ .kind = .deferred_const_data, .key = restricted_value.ty },
304 .structure => .{ .parent = .{ .kind = .const_data, .key = ptr.ty }, .modify = .{315 .operation = .end_ptr_inc,
305 .lazy_sym = .{ .kind = .deferred_const_data, .key = ptr.ty },316 } },
306 .operation = .ptr_inc,317 .attributes => {
307 } },318 const unrestricted_ty: Type = .fromInterned(
308 .attributes => {319 ip.indexToKey(restricted_value.ty).restricted_type.unrestricted_type,
309 const unrestricted_ptr_ty: Type =320 );
310 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);321 return .{
311 return .{322 .required_alignment = unrestricted_ty.abiAlignment(zcu),
312 .required_alignment = unrestricted_ptr_ty.abiAlignment(zcu),323 .size = unrestricted_ty.abiSize(zcu),
313 .size = unrestricted_ptr_ty.abiSize(zcu),324 };
314 };
315 },
316 },325 },
317 },326 },
318 .restricted_ptr_type => switch (kind) {327 .restricted_type => switch (kind) {
319 .structure => .{ .parent = .{ .kind = .const_data, .key = lazy_sym.key } },328 .structure => .{ .parent = .{ .kind = .const_data, .key = lazy_sym.key } },
320 .attributes => {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 return .{334 return .{
323 .header = true,335 .header = true,
324 .required_alignment = restricted_ptr_ty.abiAlignment(zcu),336 .required_alignment = restricted_ty.abiAlignment(zcu),
325 .size = restricted_ptr_ty.abiSize(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,7 +379,7 @@ pub fn generateLazySymbol(
367 }379 }
368 return;380 return;
369 },381 },
370 .restricted_ptr_type => return,382 .restricted_type => return,
371 else => {},383 else => {},
372 },384 },
373 .deferred_const_data => switch (lazy_sym.key) {385 .deferred_const_data => switch (lazy_sym.key) {
...@@ -392,25 +404,10 @@ pub fn generateLazySymbol(...@@ -392,25 +404,10 @@ pub fn generateLazySymbol(
392 return;404 return;
393 },405 },
394 _ => switch (ip.indexToKey(lazy_sym.key)) {406 _ => switch (ip.indexToKey(lazy_sym.key)) {
395 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {407 .restricted_value => |restricted_value| return generateSymbol(bin_file, pt, src_loc, .fromInterned(
396 .restricted_ptr_type => |restricted_ptr_type| return lowerPtr(408 restricted_value.unrestricted_value,
397 bin_file,409 ), w, reloc_parent),
398 pt,410 .restricted_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)),
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)),
414 else => {},411 else => {},
415 },412 },
416 else => {},413 else => {},
...@@ -463,13 +460,13 @@ pub fn generateSymbol(...@@ -463,13 +460,13 @@ pub fn generateSymbol(
463 switch (ip.indexToKey(val.toIntern())) {460 switch (ip.indexToKey(val.toIntern())) {
464 .int_type,461 .int_type,
465 .ptr_type,462 .ptr_type,
466 .restricted_ptr_type,
467 .array_type,463 .array_type,
468 .vector_type,464 .vector_type,
469 .opt_type,465 .opt_type,
470 .anyframe_type,466 .anyframe_type,
471 .error_union_type,467 .error_union_type,
472 .simple_type,468 .simple_type,
469 .restricted_type,
473 .struct_type,470 .struct_type,
474 .tuple_type,471 .tuple_type,
475 .union_type,472 .union_type,
...@@ -576,10 +573,7 @@ pub fn generateSymbol(...@@ -576,10 +573,7 @@ pub fn generateSymbol(
576 128 => try w.writeInt(u128, @bitCast(f128_val), endian),573 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
577 },574 },
578 },575 },
579 .ptr => switch (ty.restrictedRepr(zcu)) {576 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
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 },
583 .slice => |slice| {577 .slice => |slice| {
584 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);578 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
585 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);579 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
...@@ -788,6 +782,10 @@ pub fn generateSymbol(...@@ -788,6 +782,10 @@ pub fn generateSymbol(
788 }782 }
789 },783 },
790 .bitpack => |bitpack| try generateSymbol(bin_file, pt, src_loc, .fromInterned(bitpack.backing_int_val), w, reloc_parent),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 .memoized_call => unreachable,789 .memoized_call => unreachable,
792 }790 }
793}791}
...@@ -1185,55 +1183,57 @@ const LowerResult = union(enum) {...@@ -1185,55 +1183,57 @@ const LowerResult = union(enum) {
1185 lea_lazy_sym: link.File.LazySymbol,1183 lea_lazy_sym: link.File.LazySymbol,
1186};1184};
11871185
1188pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {1186pub fn lowerValue(pt: Zcu.PerThread, start_val: Value, target: *const std.Target) Allocator.Error!LowerResult {
1189 const zcu = pt.zcu;1187 const zcu = pt.zcu;
1190 const ip = &zcu.intern_pool;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) });
11921192
1193 log.debug("lowerValue(@as({f}, {f}))", .{ ty.fmt(pt), val.fmtValue(pt) });1193 if (start_val.isUndef(zcu)) return .undef;
11941194
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 };
11961199
1197 switch (ty.zigTypeTag(zcu)) {1200 switch (ty.zigTypeTag(zcu)) {
1198 .void => return .none,1201 .void => return .none,
1199 .bool => return .{ .immediate = @intFromBool(val.toBool()) },1202 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
1200 .pointer => switch (ty.ptrSize(zcu)) {1203 .pointer => switch (ty.ptrSize(zcu)) {
1201 .slice => {},1204 .slice => {},
1202 .one, .many, .c => switch (ty.restrictedRepr(zcu)) {1205 .one, .many, .c => {
1203 .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = val.toIntern() } },1206 const ptr = ip.indexToKey(val.toIntern()).ptr;
1204 .direct => {1207 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1205 const ptr = ip.indexToKey(val.toIntern()).ptr;1208 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1206 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };1209 .int => unreachable, // handled above
1207 if (ptr.byte_offset == 0) switch (ptr.base_addr) {1210
1208 .int => unreachable, // handled above1211 .nav => |nav_index| {
12091212 const nav = ip.getNav(nav_index);
1210 .nav => |nav_index| {1213 const nav_ty: Type = .fromInterned(nav.resolved.?.type);
1211 const nav = ip.getNav(nav_index);1214 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1212 const nav_ty: Type = .fromInterned(nav.resolved.?.type);1215 return .{ .lea_nav = nav_index };
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 };
1226 } else {1216 } else {
1227 // Create the 0xaa bit pattern...1217 // Create the 0xaa bit pattern...
1228 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);1218 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1229 // ...but align the pointer1219 // ...but align the pointer
1230 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);1220 const alignment = zcu.navAlignment(nav_index);
1231 return .{ .immediate = alignment.forward(undef_ptr_bits) };1221 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1232 },1222 }
1223 },
12331224
1234 else => {},1225 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1235 };1226 return .{ .lea_uav = uav };
1236 },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 .int => {1239 .int => {
src/codegen/c.zig+99-77
...@@ -767,7 +767,7 @@ pub const DeclGen = struct {...@@ -767,7 +767,7 @@ pub const DeclGen = struct {
767 // somewhere and we should let the C compiler tell us about it.767 // somewhere and we should let the C compiler tell us about it.
768 const elem_ty = ptr_ty.childType(zcu);768 const elem_ty = ptr_ty.childType(zcu);
769 const need_cast = elem_ty.toIntern() != nav_ty.toIntern() and769 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 if (need_cast) {771 if (need_cast) {
772 try w.writeAll("((");772 try w.writeAll("((");
773 try dg.renderType(w, ptr_ty);773 try dg.renderType(w, ptr_ty);
...@@ -919,13 +919,13 @@ pub const DeclGen = struct {...@@ -919,13 +919,13 @@ pub const DeclGen = struct {
919 // types, not values919 // types, not values
920 .int_type,920 .int_type,
921 .ptr_type,921 .ptr_type,
922 .restricted_ptr_type,
923 .array_type,922 .array_type,
924 .vector_type,923 .vector_type,
925 .opt_type,924 .opt_type,
926 .anyframe_type,925 .anyframe_type,
927 .error_union_type,926 .error_union_type,
928 .simple_type,927 .simple_type,
928 .restricted_type,
929 .struct_type,929 .struct_type,
930 .tuple_type,930 .tuple_type,
931 .union_type,931 .union_type,
...@@ -1078,24 +1078,11 @@ pub const DeclGen = struct {...@@ -1078,24 +1078,11 @@ pub const DeclGen = struct {
1078 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);1078 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
1079 try w.writeByte('}');1079 try w.writeByte('}');
1080 },1080 },
1081 .ptr => switch (ty.restrictedRepr(zcu)) {1081 .ptr => {
1082 .indirect => {1082 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1083 try dg.need_restricted.ensureUnusedCapacity(zcu.gpa, 2);1083 try w.writeByte('(');
1084 dg.need_restricted.putAssumeCapacity(ty.toIntern(), {});1084 try dg.renderPointer(w, derivation, location);
1085 dg.need_restricted.putAssumeCapacity(val.toIntern(), {});1085 try w.writeByte(')');
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 },
1099 },1086 },
1100 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {1087 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
1101 .npv_payload => unreachable, // opv optional1088 .npv_payload => unreachable, // opv optional
...@@ -1319,13 +1306,28 @@ pub const DeclGen = struct {...@@ -1319,13 +1306,28 @@ pub const DeclGen = struct {
1319 if (loaded_union.layout == .auto) try w.writeByte('}');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 }
13241326
1325 fn renderUndefValue(1327 fn renderUndefValue(
1326 dg: *DeclGen,1328 dg: *DeclGen,
1327 w: *Writer,1329 w: *Writer,
1328 ty: Type,1330 start_ty: Type,
1329 location: ValueRenderLocation,1331 location: ValueRenderLocation,
1330 ) Error!void {1332 ) Error!void {
1331 const pt = dg.pt;1333 const pt = dg.pt;
...@@ -1343,7 +1345,8 @@ pub const DeclGen = struct {...@@ -1343,7 +1345,8 @@ pub const DeclGen = struct {
1343 .ReleaseFast, .ReleaseSmall => false,1345 .ReleaseFast, .ReleaseSmall => false,
1344 };1346 };
13451347
1346 switch (ty.toIntern()) {1348 var ty = start_ty;
1349 ty: switch (start_ty.toIntern()) {
1347 .c_longdouble_type,1350 .c_longdouble_type,
1348 .f16_type,1351 .f16_type,
1349 .f32_type,1352 .f32_type,
...@@ -1371,7 +1374,7 @@ pub const DeclGen = struct {...@@ -1371,7 +1374,7 @@ pub const DeclGen = struct {
1371 return w.writeByte(')');1374 return w.writeByte(')');
1372 },1375 },
1373 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),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 .simple_type, // anyerror, c_char (etc), usize, isize1378 .simple_type, // anyerror, c_char (etc), usize, isize
1376 .int_type,1379 .int_type,
1377 .enum_type,1380 .enum_type,
...@@ -1442,9 +1445,6 @@ pub const DeclGen = struct {...@@ -1442,9 +1445,6 @@ pub const DeclGen = struct {
1442 try w.writeByte('}');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 .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) {1448 .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) {
1449 .npv_payload => unreachable, // opv optional1449 .npv_payload => unreachable, // opv optional
14501450
...@@ -1475,6 +1475,16 @@ pub const DeclGen = struct {...@@ -1475,6 +1475,16 @@ pub const DeclGen = struct {
1475 try w.writeAll(" }");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 .struct_type => {1488 .struct_type => {
1479 const loaded_struct = ip.loadStructType(ty.toIntern());1489 const loaded_struct = ip.loadStructType(ty.toIntern());
1480 switch (loaded_struct.layout) {1490 switch (loaded_struct.layout) {
...@@ -1628,6 +1638,7 @@ pub const DeclGen = struct {...@@ -1628,6 +1638,7 @@ pub const DeclGen = struct {
1628 .aggregate,1638 .aggregate,
1629 .un,1639 .un,
1630 .bitpack,1640 .bitpack,
1641 .restricted_value,
1631 .memoized_call,1642 .memoized_call,
1632 => unreachable, // values, not types1643 => unreachable, // values, not types
1633 },1644 },
...@@ -2106,9 +2117,9 @@ pub fn genRestricted(...@@ -2106,9 +2117,9 @@ pub fn genRestricted(
2106 const zcu = pt.zcu;2117 const zcu = pt.zcu;
2107 const ip = &zcu.intern_pool;2118 const ip = &zcu.intern_pool;
2108 for (need_restricted.keys(), need_restricted.values()) |restricted_ty, *restricted_vals| {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;2120 const unrestricted_type = ip.indexToKey(restricted_ty).restricted_type.unrestricted_type;
2110 const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_ptr_type), &dg.ctype_deps, dg.arena, zcu);2121 const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_type), &dg.ctype_deps, dg.arena, zcu);
2111 const restricted_ty_name = Type.fromInterned(restricted_ty).containerTypeName(ip).toSlice(ip);2122 const restricted_ty_name = ip.loadRestrictedType(restricted_ty).name.toSlice(ip);
2112 try w.print(2123 try w.print(
2113 \\#define zig_restricted_len_{f}__{d} {d}u2124 \\#define zig_restricted_len_{f}__{d} {d}u
2114 \\static {f}const zig_restricted_{f}__{d}[zig_restricted_len_{f}__{d}]{f} = {{2125 \\static {f}const zig_restricted_{f}__{d}[zig_restricted_len_{f}__{d}]{f} = {{
...@@ -2138,7 +2149,7 @@ pub fn genRestricted(...@@ -2138,7 +2149,7 @@ pub fn genRestricted(
2138 restricted_val,2149 restricted_val,
2139 });2150 });
2140 try dg.renderValue(w, .fromInterned(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 ), .static_initializer);2153 ), .static_initializer);
2143 try w.writeAll(",\n");2154 try w.writeAll(",\n");
2144 }2155 }
...@@ -3194,21 +3205,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3194,21 +3205,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3194 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3205 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3195 try f.allocs.put(zcu.gpa, local.new_local, true);3206 try f.allocs.put(zcu.gpa, local.new_local, true);
31963207
3197 switch (elem_ty.zigTypeTag(zcu)) {3208 if (elem_ty.isBitpack(zcu)) {
3198 .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) {3209 // For packed aggregates, we zero-initialize to try and work around a design flaw
3199 .@"packed" => {3210 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3200 // For packed aggregates, we zero-initialize to try and work around a design flaw3211 // for details.
3201 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`3212 const w = &f.code.writer;
3202 // for details.3213 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3203 const w = &f.code.writer;3214 try f.renderType(w, elem_ty);
3204 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});3215 try w.writeAll("));");
3205 try f.renderType(w, elem_ty);3216 try f.newline();
3206 try w.writeAll("));");
3207 try f.newline();
3208 },
3209 .auto, .@"extern" => {},
3210 },
3211 else => {},
3212 }3217 }
32133218
3214 return .{ .local_ref = local.new_local };3219 return .{ .local_ref = local.new_local };
...@@ -3228,21 +3233,15 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3228,21 +3233,15 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3228 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3233 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3229 try f.allocs.put(zcu.gpa, local.new_local, true);3234 try f.allocs.put(zcu.gpa, local.new_local, true);
32303235
3231 switch (elem_ty.zigTypeTag(zcu)) {3236 if (elem_ty.isBitpack(zcu)) {
3232 .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) {3237 // For packed aggregates, we zero-initialize to try and work around a design flaw
3233 .@"packed" => {3238 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3234 // For packed aggregates, we zero-initialize to try and work around a design flaw3239 // for details.
3235 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`3240 const w = &f.code.writer;
3236 // for details.3241 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3237 const w = &f.code.writer;3242 try f.renderType(w, elem_ty);
3238 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});3243 try w.writeAll("));");
3239 try f.renderType(w, elem_ty);3244 try f.newline();
3240 try w.writeAll("));");
3241 try f.newline();
3242 },
3243 .auto, .@"extern" => {},
3244 },
3245 else => {},
3246 }3245 }
32473246
3248 return .{ .local_ref = local.new_local };3247 return .{ .local_ref = local.new_local };
...@@ -5639,6 +5638,7 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue...@@ -5639,6 +5638,7 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
5639 try reap(f, inst, &.{ty_op.operand});5638 try reap(f, inst, &.{ty_op.operand});
56405639
5641 const w = &f.code.writer;5640 const w = &f.code.writer;
5641 // Implicitly adds the restricted decl dependency on the unrestricted type
5642 const local = try f.allocLocal(inst, unrestricted_ty);5642 const local = try f.allocLocal(inst, unrestricted_ty);
56435643
5644 switch (restricted_ty.restrictedRepr(zcu)) {5644 switch (restricted_ty.restrictedRepr(zcu)) {
...@@ -5647,8 +5647,13 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue...@@ -5647,8 +5647,13 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
5647 const target = &f.dg.mod.resolved_target.result;5647 const target = &f.dg.mod.resolved_target.result;
5648 const ptr_bits = target.ptrBitWidth();5648 const ptr_bits = target.ptrBitWidth();
56495649
5650 const int_from_ptr = try f.allocLocal(inst, .usize);5650 try f.dg.need_restricted.put(zcu.gpa, restricted_ty.toIntern(), {});
5651 try f.writeCValue(w, int_from_ptr, .other);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 try w.print(" = zig_subw_u{d}(({f})", .{5657 try w.print(" = zig_subw_u{d}(({f})", .{
5653 ptr_bits,5658 ptr_bits,
5654 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),5659 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
...@@ -5656,29 +5661,46 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue...@@ -5656,29 +5661,46 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
5656 try f.writeCValue(w, operand, .other);5661 try f.writeCValue(w, operand, .other);
5657 try w.print(", ({f})zig_restricted_{f}__{d}, {f});", .{5662 try w.print(", ({f})zig_restricted_{f}__{d}, {f});", .{
5658 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),5663 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
5659 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),5664 fmtIdentUnsolo(restricted_ty_name),
5660 restricted_ty.toIntern(),5665 restricted_ty.toIntern(),
5661 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),5666 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
5662 });5667 });
5663 try f.newline();5668 try f.newline();
56645669
5665 const rotate_amount = std.math.log2_int(u16, @divExact(ptr_bits, 8));5670 try w.writeAll("if (");
5666 try w.print("if ((zig_shr_u{d}(", .{ptr_bits});5671 if (unrestricted_size == 1) {
5667 try f.writeCValue(w, int_from_ptr, .other);5672 try f.writeCValue(w, ptr_diff, .other);
5668 try w.print(", {f}) | zig_shlw_u{d}(", .{5673 } else if (std.math.isPowerOfTwo(unrestricted_size)) {
5669 fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower),5674 const rotate_amount = std.math.log2_int(u64, unrestricted_size);
5670 ptr_bits,5675 try w.print("(zig_shr_u{d}(", .{ptr_bits});
5671 });5676 try f.writeCValue(w, ptr_diff, .other);
5672 try f.writeCValue(w, int_from_ptr, .other);5677 try w.print(", {f}) | zig_shlw_u{d}(", .{
5673 try w.print(", {f}, {f})) >= zig_restricted_len_{f}__{d}) {{", .{5678 fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower),
5674 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower),5679 ptr_bits,
5675 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),5680 });
5676 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),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 restricted_ty.toIntern(),5699 restricted_ty.toIntern(),
5678 });5700 });
5679 f.indent();5701 f.indent();
5680 try f.newline();5702 try f.newline();
5681 try f.writePanic(.corrupt_restricted_pointer, w);5703 try f.writePanic(.corrupt_restricted_value, w);
5682 try f.outdent();5704 try f.outdent();
5683 try w.writeByte('}');5705 try w.writeByte('}');
5684 try f.newline();5706 try f.newline();
...@@ -6484,7 +6506,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6484,7 +6506,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6484 try f.writeCValue(w, local, .other);6506 try f.writeCValue(w, local, .other);
6485 try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {});6507 try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {});
6486 try w.print(" = zig_tagName_{f}__{d}(", .{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 @intFromEnum(enum_ty.toIntern()),6510 @intFromEnum(enum_ty.toIntern()),
6489 });6511 });
6490 try f.writeCValue(w, operand, .other);6512 try f.writeCValue(w, operand, .other);
src/codegen/c/type.zig+30-25
...@@ -239,7 +239,20 @@ pub const CType = union(enum) {...@@ -239,7 +239,20 @@ pub const CType = union(enum) {
239 ) Allocator.Error!CType {239 ) Allocator.Error!CType {
240 const gpa = zcu.comp.gpa;240 const gpa = zcu.comp.gpa;
241 const ip = &zcu.intern_pool;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 while (true) {256 while (true) {
244 switch (cur_ty.zigTypeTag(zcu)) {257 switch (cur_ty.zigTypeTag(zcu)) {
245 .type,258 .type,
...@@ -284,20 +297,6 @@ pub const CType = union(enum) {...@@ -284,20 +297,6 @@ pub const CType = union(enum) {
284297
285 .pointer => {298 .pointer => {
286 const ptr = cur_ty.ptrInfo(zcu);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 switch (ptr.flags.size) {300 switch (ptr.flags.size) {
302 .slice => {301 .slice => {
303 try deps.addType(gpa, cur_ty, allow_incomplete);302 try deps.addType(gpa, cur_ty, allow_incomplete);
...@@ -305,7 +304,7 @@ pub const CType = union(enum) {...@@ -305,7 +304,7 @@ pub const CType = union(enum) {
305 },304 },
306 .one, .many, .c => {305 .one, .many, .c => {
307 const elem_ty: Type = .fromInterned(ptr.child);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 const elem_cty: CType = elem_cty: {308 const elem_cty: CType = elem_cty: {
310 if (ptr.packed_offset.host_size > 0 and ptr.flags.vector_index == .none) {309 if (ptr.packed_offset.host_size > 0 and ptr.flags.vector_index == .none) {
311 switch (classifyBitInt(.unsigned, ptr.packed_offset.host_size * 8, zcu)) {310 switch (classifyBitInt(.unsigned, ptr.packed_offset.host_size * 8, zcu)) {
...@@ -876,6 +875,10 @@ pub const CType = union(enum) {...@@ -876,6 +875,10 @@ pub const CType = union(enum) {
876 const ty = ctx.ty;875 const ty = ctx.ty;
877 const zcu = ctx.zcu;876 const zcu = ctx.zcu;
878 const ip = &zcu.intern_pool;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 switch (ty.zigTypeTag(zcu)) {882 switch (ty.zigTypeTag(zcu)) {
880 .frame => unreachable,883 .frame => unreachable,
881 .@"anyframe" => unreachable,884 .@"anyframe" => unreachable,
...@@ -926,10 +929,7 @@ pub const CType = union(enum) {...@@ -926,10 +929,7 @@ pub const CType = union(enum) {
926 .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}),929 .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}),
927 .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}),930 .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}),
928931
929 .pointer => if (ty.unrestrictedType(zcu)) |_| {932 .pointer => switch (ty.ptrSize(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)) {
933 .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),933 .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
934 .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),934 .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
935 },935 },
...@@ -971,6 +971,10 @@ pub const CType = union(enum) {...@@ -971,6 +971,10 @@ pub const CType = union(enum) {
971 fmtZigType(ty.childType(zcu), zcu),971 fmtZigType(ty.childType(zcu), zcu),
972 }),972 }),
973973
974 .@"enum" => {
975 const name = ip.loadEnumType(ty.toIntern()).name.toSlice(ip);
976 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
977 },
974 .@"struct" => if (ty.isTuple(zcu)) {978 .@"struct" => if (ty.isTuple(zcu)) {
975 const len = ty.structFieldCount(zcu);979 const len = ty.structFieldCount(zcu);
976 try w.print("tuple_{d}", .{len});980 try w.print("tuple_{d}", .{len});
...@@ -979,17 +983,17 @@ pub const CType = union(enum) {...@@ -979,17 +983,17 @@ pub const CType = union(enum) {
979 try w.print("_{f}", .{fmtZigType(field_ty, zcu)});983 try w.print("_{f}", .{fmtZigType(field_ty, zcu)});
980 }984 }
981 } else {985 } else {
982 const name = ty.containerTypeName(ip).toSlice(ip);986 const name = ip.loadStructType(ty.toIntern()).name.toSlice(ip);
983 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});987 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
984 },988 },
985 .@"opaque" => if (ty.toIntern() == .anyopaque_type) {989 .@"opaque" => if (ty.toIntern() == .anyopaque_type) {
986 try w.writeAll("anyopaque");990 try w.writeAll("anyopaque");
987 } else {991 } else {
988 const name = ty.containerTypeName(ip).toSlice(ip);992 const name = ip.loadOpaqueType(ty.toIntern()).name.toSlice(ip);
989 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});993 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
990 },994 },
991 .@"union", .@"enum" => {995 .@"union" => {
992 const name = ty.containerTypeName(ip).toSlice(ip);996 const name = ip.loadUnionType(ty.toIntern()).name.toSlice(ip);
993 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});997 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
994 },998 },
995 }999 }
...@@ -1002,7 +1006,6 @@ pub const CType = union(enum) {...@@ -1002,7 +1006,6 @@ pub const CType = union(enum) {
1002 return switch (ip.indexToKey(ty.toIntern())) {1006 return switch (ip.indexToKey(ty.toIntern())) {
1003 .int_type,1007 .int_type,
1004 .ptr_type,1008 .ptr_type,
1005 .restricted_ptr_type,
1006 .anyframe_type,1009 .anyframe_type,
1007 .simple_type,1010 .simple_type,
1008 .opaque_type,1011 .opaque_type,
...@@ -1010,6 +1013,7 @@ pub const CType = union(enum) {...@@ -1010,6 +1013,7 @@ pub const CType = union(enum) {
1010 .inferred_error_set_type,1013 .inferred_error_set_type,
1011 => true,1014 => true,
10121015
1016 .restricted_type,
1013 .struct_type,1017 .struct_type,
1014 .union_type,1018 .union_type,
1015 .enum_type,1019 .enum_type,
...@@ -1045,6 +1049,7 @@ pub const CType = union(enum) {...@@ -1045,6 +1049,7 @@ pub const CType = union(enum) {
1045 .aggregate,1049 .aggregate,
1046 .un,1050 .un,
1047 .bitpack,1051 .bitpack,
1052 .restricted_value,
1048 // memoization, not types1053 // memoization, not types
1049 .memoized_call,1054 .memoized_call,
1050 => unreachable,1055 => unreachable,
src/codegen/llvm.zig+93-87
...@@ -708,16 +708,17 @@ pub const Object = struct {...@@ -708,16 +708,17 @@ pub const Object = struct {
708 rd.* = undefined;708 rd.* = undefined;
709 }709 }
710 };710 };
711 pub fn getRestrictedDecls(o: *Object, ty: Type) Allocator.Error!*RestrictedDecls {711 pub fn getRestrictedDecls(o: *Object, restricted_ty: Type) Allocator.Error!*RestrictedDecls {
712 const gop = try o.restricted_map.getOrPut(o.gpa, ty.toIntern());712 const gop = try o.restricted_map.getOrPut(o.gpa, restricted_ty.toIntern());
713 if (gop.found_existing) return gop.value_ptr;713 if (gop.found_existing) return gop.value_ptr;
714 errdefer _ = o.restricted_map.pop().?;714 errdefer _ = o.restricted_map.pop().?;
715715
716 const target = o.zcu.getTarget();716 const zcu = o.zcu;
717 const ip = &o.zcu.intern_pool;717 const target = zcu.getTarget();
718 const ptr_align = Type.ptrAbiAlignment(target).toLlvm();718 const ip = &zcu.intern_pool;
719 const unrestricted_ty = restricted_ty.unrestrictedType(zcu).?;
719720
720 const ty_name = ty.containerTypeName(ip).toSlice(ip);721 const ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip);
721 gop.value_ptr.* = .{722 gop.value_ptr.* = .{
722 .len = try o.builder.addVariable(723 .len = try o.builder.addVariable(
723 try o.builder.strtabStringFmt("{s}.len", .{ty_name}),724 try o.builder.strtabStringFmt("{s}.len", .{ty_name}),
...@@ -733,11 +734,11 @@ pub const Object = struct {...@@ -733,11 +734,11 @@ pub const Object = struct {
733 };734 };
734 gop.value_ptr.len.setLinkage(.private, &o.builder);735 gop.value_ptr.len.setLinkage(.private, &o.builder);
735 gop.value_ptr.len.setMutability(.constant, &o.builder);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 gop.value_ptr.len.setUnnamedAddr(.unnamed_addr, &o.builder);738 gop.value_ptr.len.setUnnamedAddr(.unnamed_addr, &o.builder);
738 gop.value_ptr.array.setLinkage(.private, &o.builder);739 gop.value_ptr.array.setLinkage(.private, &o.builder);
739 gop.value_ptr.array.setMutability(.constant, &o.builder);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 // Setting unnamed_addr here would reduce safety, and the module emitting the safety checks may not be the same module742 // Setting unnamed_addr here would reduce safety, and the module emitting the safety checks may not be the same module
742 // that defined the restricted type. In any case, llvm will add unnamed_addr itself if no safety checks end up being emitted.743 // that defined the restricted type. In any case, llvm will add unnamed_addr itself if no safety checks end up being emitted.
743 gop.value_ptr.array.setUnnamedAddr(.default, &o.builder);744 gop.value_ptr.array.setUnnamedAddr(.default, &o.builder);
...@@ -750,10 +751,13 @@ pub const Object = struct {...@@ -750,10 +751,13 @@ pub const Object = struct {
750 try o.builder.intConst(restricted_decls.len.typeOf(&o.builder), len),751 try o.builder.intConst(restricted_decls.len.typeOf(&o.builder), len),
751 &o.builder,752 &o.builder,
752 );753 );
753 try restricted_decls.array.setInitializer(try o.builder.arrayConst(754 try restricted_decls.array.setInitializer(switch (len) {
754 try o.builder.arrayType(len, .ptr),755 0 => try o.builder.structConst(try o.builder.structType(.normal, &.{}), &.{}),
755 restricted_decls.values.values(),756 else => try o.builder.arrayConst(
756 ), &o.builder);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 }
759763
...@@ -2023,7 +2027,7 @@ pub const Object = struct {...@@ -2023,7 +2027,7 @@ pub const Object = struct {
2023 fn lowerDebugType(2027 fn lowerDebugType(
2024 o: *Object,2028 o: *Object,
2025 pt: Zcu.PerThread,2029 pt: Zcu.PerThread,
2026 ty: Type,2030 start_ty: Type,
2027 ty_fwd_ref: Builder.Metadata,2031 ty_fwd_ref: Builder.Metadata,
2028 ) Allocator.Error!Builder.Metadata {2032 ) Allocator.Error!Builder.Metadata {
2029 assert(!o.builder.strip);2033 assert(!o.builder.strip);
...@@ -2033,7 +2037,7 @@ pub const Object = struct {...@@ -2033,7 +2037,7 @@ pub const Object = struct {
2033 const target = zcu.getTarget();2037 const target = zcu.getTarget();
2034 const ip = &zcu.intern_pool;2038 const ip = &zcu.intern_pool;
20352039
2036 const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)});2040 const name = try o.builder.metadataStringFmt("{f}", .{start_ty.fmt(pt)});
20372041
2038 // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up.2042 // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up.
2039 // For instance, `bool` is considered to be 8 bits, and `u60` is considered to be 64 bits.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,6 +2048,24 @@ pub const Object = struct {
2044 // handling for variants at all, and will never print fields in them, so I opted not to use2048 // handling for variants at all, and will never print fields in them, so I opted not to use
2045 // them for now.2049 // them for now.
20462050
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 switch (ty.zigTypeTag(zcu)) {2069 switch (ty.zigTypeTag(zcu)) {
2048 .void,2070 .void,
2049 .noreturn,2071 .noreturn,
...@@ -2071,64 +2093,52 @@ pub const Object = struct {...@@ -2071,64 +2093,52 @@ pub const Object = struct {
2071 .pointer => {2093 .pointer => {
2072 const ptr_size = Type.ptrAbiSize(zcu.getTarget());2094 const ptr_size = Type.ptrAbiSize(zcu.getTarget());
2073 const ptr_align = Type.ptrAbiAlignment(zcu.getTarget());2095 const ptr_align = Type.ptrAbiAlignment(zcu.getTarget());
2074 switch (ty.restrictedRepr(zcu)) {2096 if (ty.isSlice(zcu)) {
2075 .indirect => return o.builder.debugPointerType(2097 const debug_ptr_type = try o.builder.debugMemberType(
2076 name,2098 try o.builder.metadataString("ptr"),
2077 null, // file2099 null, // file
2078 o.debug_compile_unit.unwrap().?, // scope2100 ty_fwd_ref,
2079 0, // line2101 0, // line
2080 try o.getDebugType(pt, ty.unrestrictedType(zcu).?),2102 try o.getDebugType(pt, ty.slicePtrFieldType(zcu)),
2081 ptr_size * 8,2103 ptr_size * 8,
2082 ptr_align.toByteUnits().? * 8,2104 ptr_align.toByteUnits().? * 8,
2083 0, // offset2105 0, // offset
2084 ),2106 );
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 );
20962107
2097 const debug_len_type = try o.builder.debugMemberType(2108 const debug_len_type = try o.builder.debugMemberType(
2098 try o.builder.metadataString("len"),2109 try o.builder.metadataString("len"),
2099 null, // file2110 null, // file
2100 ty_fwd_ref,2111 ty_fwd_ref,
2101 0, // line2112 0, // line
2102 try o.getDebugType(pt, .usize),2113 try o.getDebugType(pt, .usize),
2103 ptr_size * 8,2114 ptr_size * 8,
2104 ptr_align.toByteUnits().? * 8,2115 ptr_align.toByteUnits().? * 8,
2105 ptr_size * 8,2116 ptr_size * 8,
2106 );2117 );
21072118
2108 return o.builder.debugStructType(2119 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(
2122 name,2120 name,
2123 null, // file2121 null, // file
2124 o.debug_compile_unit.unwrap().?, // scope2122 o.debug_compile_unit.unwrap().?, // scope
2125 0, // line2123 0, // line
2126 try o.getDebugType(pt, ty.childType(zcu)),2124 null, // underlying type
2127 ptr_size * 8,2125 ptr_size * 2 * 8,
2128 ptr_align.toByteUnits().? * 8,2126 ptr_align.toByteUnits().? * 8,
2129 0, // offset2127 try o.builder.metadataTuple(&.{
2130 ),2128 debug_ptr_type,
2131 }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 .array => return o.builder.debugArrayType(2143 .array => return o.builder.debugArrayType(
2134 name,2144 name,
...@@ -3121,7 +3131,7 @@ pub const Object = struct {...@@ -3121,7 +3131,7 @@ pub const Object = struct {
3121 .empty_tuple,3131 .empty_tuple,
3122 .none,3132 .none,
3123 => unreachable,3133 => unreachable,
3124 else => t: switch (ip.indexToKey(t.toIntern())) {3134 else => switch (ip.indexToKey(t.toIntern())) {
3125 .int_type => |int_type| try o.builder.intType(int_type.bits),3135 .int_type => |int_type| try o.builder.intType(int_type.bits),
3126 .ptr_type => |ptr_type| type: {3136 .ptr_type => |ptr_type| type: {
3127 const ptr_ty = try o.builder.ptrType(3137 const ptr_ty = try o.builder.ptrType(
...@@ -3135,10 +3145,6 @@ pub const Object = struct {...@@ -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 .array_type => |array_type| o.builder.arrayType(3148 .array_type => |array_type| o.builder.arrayType(
3143 array_type.lenIncludingSentinel(),3149 array_type.lenIncludingSentinel(),
3144 try o.lowerType(.fromInterned(array_type.child)),3150 try o.lowerType(.fromInterned(array_type.child)),
...@@ -3217,6 +3223,10 @@ pub const Object = struct {...@@ -3217,6 +3223,10 @@ pub const Object = struct {
3217 return o.builder.structType(.normal, fields[0..fields_len]);3223 return o.builder.structType(.normal, fields[0..fields_len]);
3218 },3224 },
3219 .simple_type => unreachable,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 .struct_type => {3230 .struct_type => {
3221 if (o.type_map.get(t.toIntern())) |value| return value;3231 if (o.type_map.get(t.toIntern())) |value| return value;
32223232
...@@ -3430,6 +3440,7 @@ pub const Object = struct {...@@ -3430,6 +3440,7 @@ pub const Object = struct {
3430 .aggregate,3440 .aggregate,
3431 .un,3441 .un,
3432 .bitpack,3442 .bitpack,
3443 .restricted_value,
3433 // memoization, not types3444 // memoization, not types
3434 .memoized_call,3445 .memoized_call,
3435 => unreachable,3446 => unreachable,
...@@ -3521,13 +3532,13 @@ pub const Object = struct {...@@ -3521,13 +3532,13 @@ pub const Object = struct {
3521 return switch (val_key) {3532 return switch (val_key) {
3522 .int_type,3533 .int_type,
3523 .ptr_type,3534 .ptr_type,
3524 .restricted_ptr_type,
3525 .array_type,3535 .array_type,
3526 .vector_type,3536 .vector_type,
3527 .opt_type,3537 .opt_type,
3528 .anyframe_type,3538 .anyframe_type,
3529 .error_union_type,3539 .error_union_type,
3530 .simple_type,3540 .simple_type,
3541 .restricted_type,
3531 .struct_type,3542 .struct_type,
3532 .tuple_type,3543 .tuple_type,
3533 .union_type,3544 .union_type,
...@@ -3622,27 +3633,7 @@ pub const Object = struct {...@@ -3622,27 +3633,7 @@ pub const Object = struct {
3622 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)),3633 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)),
3623 else => unreachable,3634 else => unreachable,
3624 },3635 },
3625 .ptr => switch (ty.restrictedRepr(zcu)) {3636 .ptr => try o.lowerPtr(arg_val, 0),
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 },
3646 .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{3637 .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{
3647 try o.lowerValue(slice.ptr),3638 try o.lowerValue(slice.ptr),
3648 try o.lowerValue(slice.len),3639 try o.lowerValue(slice.len),
...@@ -4006,6 +3997,21 @@ pub const Object = struct {...@@ -4006,6 +3997,21 @@ pub const Object = struct {
4006 else3997 else
4007 union_ty, vals[0..len]);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 .memoized_call => unreachable,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,6 +3266,8 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
3266 if (safety) {3266 if (safety) {
3267 const restricted_decls = try o.getRestrictedDecls(restricted_ty);3267 const restricted_decls = try o.getRestrictedDecls(restricted_ty);
3268 const llvm_usize_ty = restricted_decls.len.typeOf(&o.builder);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 const array = try o.builder.castConst(.ptrtoint, restricted_decls.array.toConst(&o.builder), llvm_usize_ty);3271 const array = try o.builder.castConst(.ptrtoint, restricted_decls.array.toConst(&o.builder), llvm_usize_ty);
3270 const ptr_diff = try fg.wip.bin(3272 const ptr_diff = try fg.wip.bin(
3271 .sub,3273 .sub,
...@@ -3273,11 +3275,6 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat...@@ -3273,11 +3275,6 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
3273 array.toValue(),3275 array.toValue(),
3274 "unwrap_restricted.ptr_diff",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 const len = try fg.wip.load(3278 const len = try fg.wip.load(
3282 .normal,3279 .normal,
3283 llvm_usize_ty,3280 llvm_usize_ty,
...@@ -3285,18 +3282,38 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat...@@ -3285,18 +3282,38 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
3285 Type.ptrAbiAlignment(target).toLlvm(),3282 Type.ptrAbiAlignment(target).toLlvm(),
3286 "unwrap_restricted.len",3283 "unwrap_restricted.len",
3287 );3284 );
3288 const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok");3285 const is_po2_unrestricted_size = std.math.isPowerOfTwo(unrestricted_size);
32893286 const check_block = if (is_po2_unrestricted_size) undefined else try fg.wip.block(1, "unwrap_restricted.check");
3290 const invalid_block = try fg.wip.block(1, "unwrap_restricted.invalid");3287 const invalid_block = try fg.wip.block(if (is_po2_unrestricted_size) 1 else 2, "unwrap_restricted.invalid");
3291 const valid_block = try fg.wip.block(1, "unwrap_restricted.valid");3288 const valid_block = try fg.wip.block(1, "unwrap_restricted.valid");
3292 _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none);3289 if (is_po2_unrestricted_size) {
32933290 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 fg.wip.cursor = .{ .block = invalid_block };3311 fg.wip.cursor = .{ .block = invalid_block };
3295 try fg.buildSimplePanic(.corrupt_restricted_pointer);3312 try fg.buildSimplePanic(.corrupt_restricted_value);
32963313
3297 fg.wip.cursor = .{ .block = valid_block };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 .direct => return operand,3318 .direct => return operand,
3302 }3319 }
...@@ -7275,7 +7292,11 @@ pub fn buildAllocaInner(...@@ -7275,7 +7292,11 @@ pub fn buildAllocaInner(
7275/// This is the one source of truth for whether a type is passed around as an LLVM pointer,7292/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
7276/// or as an LLVM value.7293/// or as an LLVM value.
7277pub fn isByRef(ty: Type, zcu: *const Zcu) bool {7294pub 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 .type,7300 .type,
7280 .comptime_int,7301 .comptime_int,
7281 .comptime_float,7302 .comptime_float,
...@@ -7300,19 +7321,19 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {...@@ -7300,19 +7321,19 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {
73007321
7301 .array,7322 .array,
7302 .frame,7323 .frame,
7303 => ty.hasRuntimeBits(zcu),7324 => unrestricted_ty.hasRuntimeBits(zcu),
73047325
7305 .error_union => ty.errorUnionPayload(zcu).hasRuntimeBits(zcu),7326 .error_union => unrestricted_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu),
73067327
7307 .optional => !ty.optionalReprIsPayload(zcu) and ty.optionalChild(zcu).hasRuntimeBits(zcu),7328 .optional => !unrestricted_ty.optionalReprIsPayload(zcu) and unrestricted_ty.optionalChild(zcu).hasRuntimeBits(zcu),
73087329
7309 .@"struct" => switch (ty.containerLayout(zcu)) {7330 .@"struct" => switch (unrestricted_ty.containerLayout(zcu)) {
7310 .@"packed" => false,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 .@"packed" => false,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,13 +774,13 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
774 switch (ip.indexToKey(val.toIntern())) {774 switch (ip.indexToKey(val.toIntern())) {
775 .int_type,775 .int_type,
776 .ptr_type,776 .ptr_type,
777 .restricted_ptr_type,
778 .array_type,777 .array_type,
779 .vector_type,778 .vector_type,
780 .opt_type,779 .opt_type,
781 .anyframe_type,780 .anyframe_type,
782 .error_union_type,781 .error_union_type,
783 .simple_type,782 .simple_type,
783 .restricted_type,
784 .struct_type,784 .struct_type,
785 .tuple_type,785 .tuple_type,
786 .union_type,786 .union_type,
...@@ -990,6 +990,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -990,6 +990,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
990 break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr);990 break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr);
991 },991 },
992992
993 .restricted_value => return cg.todo("implement restricted values", .{}),
993 .memoized_call => unreachable,994 .memoized_call => unreachable,
994 }995 }
995 };996 };
...@@ -2777,7 +2778,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void {...@@ -2777,7 +2778,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void {
2777 .wrap_errunion_err => try cg.airWrapErrUnionErr(inst),2778 .wrap_errunion_err => try cg.airWrapErrUnionErr(inst),
2778 .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst),2779 .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst),
27792780
2780 .unwrap_restricted => return cg.fail("TODO implement restricted pointers", .{}),2781 .unwrap_restricted => return cg.todo("implement restricted values", .{}),
27812782
2782 .is_null => try cg.airIsNull(inst, false, .is_null),2783 .is_null => try cg.airIsNull(inst, false, .is_null),
2783 .is_non_null => try cg.airIsNull(inst, false, .is_non_null),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,13 +4679,13 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
4679 switch (ip.indexToKey(val.ip_index)) {4679 switch (ip.indexToKey(val.ip_index)) {
4680 .int_type,4680 .int_type,
4681 .ptr_type,4681 .ptr_type,
4682 .restricted_ptr_type,
4683 .array_type,4682 .array_type,
4684 .vector_type,4683 .vector_type,
4685 .opt_type,4684 .opt_type,
4686 .anyframe_type,4685 .anyframe_type,
4687 .error_union_type,4686 .error_union_type,
4688 .simple_type,4687 .simple_type,
4688 .restricted_type,
4689 .struct_type,4689 .struct_type,
4690 .tuple_type,4690 .tuple_type,
4691 .union_type,4691 .union_type,
...@@ -4779,6 +4779,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {...@@ -4779,6 +4779,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
4779 },4779 },
4780 .un => unreachable, // packed unions use `bitpack`4780 .un => unreachable, // packed unions use `bitpack`
4781 .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),4781 .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),
4782 .restricted_value => return cg.fail("Wasm TODO: LowerConstant for restricted value", .{}),
4782 .memoized_call => unreachable,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,14 +103826,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103826 const ty_op = air_datas[@intFromEnum(inst)].ty_op;103826 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
103827 const unrestricted_ty = ty_op.ty.toType();103827 const unrestricted_ty = ty_op.ty.toType();
103828 const restricted_ty = cg.typeOf(ty_op.operand);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 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {103830 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {
103831 .indirect => {103831 .indirect => {
103832 if (zcu.comp.config.use_new_linker) switch (air_tag) {103832 if (zcu.comp.config.use_new_linker) switch (air_tag) {
103833 else => unreachable,103833 else => unreachable,
103834 .unwrap_restricted => {},103834 .unwrap_restricted => {},
103835 .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{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 .required_features = .{ .avx, null, null, null },103867 .required_features = .{ .avx, null, null, null },
103868 .src_constraints = .{ .any, .po2_any, .any },
103837 .patterns = &.{103869 .patterns = &.{
103838 .{ .src = .{ .mem, .none, .none } },103870 .{ .src = .{ .mem, .none, .none } },
103839 .{ .src = .{ .to_gpr, .none, .none } },103871 .{ .src = .{ .to_gpr, .none, .none } },
...@@ -103843,7 +103875,72 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103843,7 +103875,72 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103843 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103875 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103844 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },103876 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103845 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },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 .unused,103944 .unused,
103848 .unused,103945 .unused,
103849 .unused,103946 .unused,
...@@ -103857,13 +103954,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103857,13 +103954,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103857 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },103954 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103858 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },103955 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103859 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },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 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },103958 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103862 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },103959 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103863 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },103960 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103864 } },103961 } },
103865 }, .{103962 }, .{
103866 .required_features = .{ .sse, null, null, null },103963 .required_features = .{ .sse, null, null, null },
103964 .src_constraints = .{ .any, .po2_any, .any },
103867 .patterns = &.{103965 .patterns = &.{
103868 .{ .src = .{ .mem, .none, .none } },103966 .{ .src = .{ .mem, .none, .none } },
103869 .{ .src = .{ .to_gpr, .none, .none } },103967 .{ .src = .{ .to_gpr, .none, .none } },
...@@ -103873,7 +103971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103873,7 +103971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103873 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103971 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103874 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },103972 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103875 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },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 .unused,103975 .unused,
103878 .unused,103976 .unused,
103879 .unused,103977 .unused,
...@@ -103887,12 +103985,48 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103887,12 +103985,48 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103887 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },103985 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103888 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },103986 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103889 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },103987 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },
103890 .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ },103988 .{ ._, ._r, .ro, .tmp2p, .sa(.src1, .add_log2_size), ._, ._ },
103891 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },103989 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103892 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },103990 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103893 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },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 .patterns = &.{104030 .patterns = &.{
103897 .{ .src = .{ .mem, .none, .none } },104031 .{ .src = .{ .mem, .none, .none } },
103898 .{ .src = .{ .to_gpr, .none, .none } },104032 .{ .src = .{ .to_gpr, .none, .none } },
...@@ -103902,7 +104036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103902,7 +104036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103902 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },104036 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103903 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },104037 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103904 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },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 .unused,104040 .unused,
103907 .unused,104041 .unused,
103908 .unused,104042 .unused,
...@@ -103916,11 +104050,74 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103916,11 +104050,74 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103916 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },104050 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103917 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },104051 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103918 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },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 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },104054 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103921 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },104055 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103922 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },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 } }) catch |err| switch (err) {104121 } }) catch |err| switch (err) {
103925 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{104122 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103926 air_tag,104123 air_tag,
...@@ -103935,7 +104132,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103935,7 +104132,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103935 },104132 },
103936 .direct => ops[0],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 .struct_field_ptr => {104138 .struct_field_ptr => {
103941 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;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,7 +174388,12 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok
174190 };174388 };
174191174389
174192 if (reg_ok) need_mem: {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 .float => switch (ty.floatBits(self.target)) {174397 .float => switch (ty.floatBits(self.target)) {
174195 16, 32, 64, 128 => 16,174398 16, 32, 64, 128 => 16,
174196 80 => break :need_mem,174399 80 => break :need_mem,
...@@ -189139,9 +189342,9 @@ const Select = struct {...@@ -189139,9 +189342,9 @@ const Select = struct {
189139 lhs: enum(u6) {189342 lhs: enum(u6) {
189140 none,189343 none,
189141 ptr_size,189344 ptr_size,
189142 log2_ptr_size,
189143 ptr_bit_size,189345 ptr_bit_size,
189144 size,189346 size,
189347 log2_size,
189145 src0_size,189348 src0_size,
189146 dst0_size,189349 dst0_size,
189147 delta_size,189350 delta_size,
...@@ -189178,7 +189381,6 @@ const Select = struct {...@@ -189178,7 +189381,6 @@ const Select = struct {
189178 const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" };189381 const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" };
189179 const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" };189382 const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" };
189180 const sub_ptr_size: Adjust = .{ .sign = .neg, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" };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 const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" };189384 const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" };
189183 const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" };189385 const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" };
189184 const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" };189386 const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" };
...@@ -189186,6 +189388,7 @@ const Select = struct {...@@ -189186,6 +189388,7 @@ const Select = struct {
189186 const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" };189388 const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" };
189187 const sub_size_div_4: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"4" };189389 const sub_size_div_4: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"4" };
189188 const sub_size: Adjust = .{ .sign = .neg, .lhs = .size, .op = .mul, .rhs = .@"1" };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 const sub_src0_size_div_8: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .div, .rhs = .@"8" };189392 const sub_src0_size_div_8: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .div, .rhs = .@"8" };
189190 const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };189393 const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
189191 const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };189394 const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
...@@ -190119,8 +190322,8 @@ const Select = struct {...@@ -190119,8 +190322,8 @@ const Select = struct {
190119 const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) {190322 const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) {
190120 .none => 0,190323 .none => 0,
190121 .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8),190324 .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8),
190122 .log2_ptr_size => std.math.log2(@divExact(s.cg.target.ptrBitWidth(), 8)),
190123 .ptr_bit_size => s.cg.target.ptrBitWidth(),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 .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)),190327 .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)),
190125 .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)),190328 .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)),
190126 .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)),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,8 +1385,8 @@ fn mergeNeededRestricted(
1385 for (new.keys()) |restricted_key| {1385 for (new.keys()) |restricted_key| {
1386 const restricted_ty = switch (ip.indexToKey(restricted_key)) {1386 const restricted_ty = switch (ip.indexToKey(restricted_key)) {
1387 else => unreachable,1387 else => unreachable,
1388 .restricted_ptr_type => restricted_key,1388 .restricted_type => restricted_key,
1389 .ptr => |ptr| ptr.ty,1389 .restricted_value => |restricted_value| restricted_value.ty,
1390 };1390 };
1391 const gop = global.getOrPutAssumeCapacity(restricted_ty);1391 const gop = global.getOrPutAssumeCapacity(restricted_ty);
1392 if (!gop.found_existing) gop.value_ptr.* = .empty;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,7 +2173,14 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
21732173
2174 if (structure.modify) |modification| modification.operation.apply(2174 if (structure.modify) |modification| modification.operation.apply(
2175 coff.lazySymbolIfExists(modification.lazy_sym).?.node(coff).slice(&coff.mf),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}
21792186
src/link/ConstPool.zig+23-21
...@@ -181,8 +181,9 @@ fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Inde...@@ -181,8 +181,9 @@ fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Inde
181 }181 }
182}182}
183fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {183fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {
184 if (ty.isGenericPoison()) return true;184 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
185 return switch (ty.zigTypeTag(zcu)) {185 if (unrestricted_ty.isGenericPoison()) return true;
186 return switch (unrestricted_ty.zigTypeTag(zcu)) {
186 .type,187 .type,
187 .void,188 .void,
188 .bool,189 .bool,
...@@ -201,33 +202,34 @@ fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {...@@ -201,33 +202,34 @@ fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {
201 .enum_literal,202 .enum_literal,
202 => true,203 => true,
203204
204 .array, .vector => pool.checkType(ty.childType(zcu), zcu),205 .array, .vector => pool.checkType(unrestricted_ty.childType(zcu), zcu),
205 .optional => pool.checkType(ty.optionalChild(zcu), zcu),206 .optional => pool.checkType(unrestricted_ty.optionalChild(zcu), zcu),
206 .error_union => pool.checkType(ty.errorUnionPayload(zcu), zcu),207 .error_union => pool.checkType(unrestricted_ty.errorUnionPayload(zcu), zcu),
207 .@"fn" => {208 .@"fn" => {
208 const ip = &zcu.intern_pool;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 for (func.param_types.get(ip)) |param_ty_ip| {211 for (func.param_types.get(ip)) |param_ty_ip| {
211 if (!pool.checkType(.fromInterned(param_ty_ip), zcu)) return false;212 if (!pool.checkType(.fromInterned(param_ty_ip), zcu)) return false;
212 }213 }
213 return pool.checkType(.fromInterned(func.return_type), zcu);214 return pool.checkType(.fromInterned(func.return_type), zcu);
214 },215 },
215 .@"struct" => if (ty.isTuple(zcu)) {216 .@"struct" => if (unrestricted_ty.isTuple(zcu)) {
216 for (0..ty.structFieldCount(zcu)) |field_index| {217 for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| {
217 if (!pool.checkType(ty.fieldType(field_index, zcu), zcu)) return false;218 if (!pool.checkType(unrestricted_ty.fieldType(field_index, zcu), zcu)) return false;
218 }219 }
219 return true;220 return true;
220 } else {221 } else {
221 return pool.complete_containers.contains(ty.toIntern());222 return pool.complete_containers.contains(unrestricted_ty.toIntern());
222 },223 },
223 .@"union", .@"enum" => {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}
228fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Allocator.Error!void {229fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Allocator.Error!void {
229 if (ty.isGenericPoison()) return;230 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
230 switch (ty.zigTypeTag(zcu)) {231 if (unrestricted_ty.isGenericPoison()) return;
232 switch (unrestricted_ty.zigTypeTag(zcu)) {
231 .type,233 .type,
232 .void,234 .void,
233 .bool,235 .bool,
...@@ -246,20 +248,20 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al...@@ -246,20 +248,20 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al
246 .enum_literal,248 .enum_literal,
247 => {},249 => {},
248250
249 .array, .vector => try pool.registerTypeDeps(root, ty.childType(zcu), zcu),251 .array, .vector => try pool.registerTypeDeps(root, unrestricted_ty.childType(zcu), zcu),
250 .optional => try pool.registerTypeDeps(root, ty.optionalChild(zcu), zcu),252 .optional => try pool.registerTypeDeps(root, unrestricted_ty.optionalChild(zcu), zcu),
251 .error_union => try pool.registerTypeDeps(root, ty.errorUnionPayload(zcu), zcu),253 .error_union => try pool.registerTypeDeps(root, unrestricted_ty.errorUnionPayload(zcu), zcu),
252 .@"fn" => {254 .@"fn" => {
253 const ip = &zcu.intern_pool;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 for (func.param_types.get(ip)) |param_ty_ip| {257 for (func.param_types.get(ip)) |param_ty_ip| {
256 try pool.registerTypeDeps(root, .fromInterned(param_ty_ip), zcu);258 try pool.registerTypeDeps(root, .fromInterned(param_ty_ip), zcu);
257 }259 }
258 try pool.registerTypeDeps(root, .fromInterned(func.return_type), zcu);260 try pool.registerTypeDeps(root, .fromInterned(func.return_type), zcu);
259 },261 },
260 .@"struct", .@"union", .@"enum" => if (ty.isTuple(zcu)) {262 .@"struct", .@"union", .@"enum" => if (unrestricted_ty.isTuple(zcu)) {
261 for (0..ty.structFieldCount(zcu)) |field_index| {263 for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| {
262 try pool.registerTypeDeps(root, ty.fieldType(field_index, zcu), zcu);264 try pool.registerTypeDeps(root, unrestricted_ty.fieldType(field_index, zcu), zcu);
263 }265 }
264 } else {266 } else {
265 // `ty` is a container; register the dependency.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,7 +271,7 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al
269 try pool.container_dep_entries.ensureUnusedCapacity(gpa, 1);271 try pool.container_dep_entries.ensureUnusedCapacity(gpa, 1);
270 errdefer comptime unreachable;272 errdefer comptime unreachable;
271273
272 const gop = pool.container_deps.getOrPutAssumeCapacity(ty.toIntern());274 const gop = pool.container_deps.getOrPutAssumeCapacity(unrestricted_ty.toIntern());
273 const entry: ContainerDepEntry.Index = @enumFromInt(pool.container_dep_entries.items.len);275 const entry: ContainerDepEntry.Index = @enumFromInt(pool.container_dep_entries.items.len);
274 pool.container_dep_entries.appendAssumeCapacity(.{276 pool.container_dep_entries.appendAssumeCapacity(.{
275 .next = if (gop.found_existing) gop.value_ptr.toOptional() else .none,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,7 +1176,7 @@ pub const Loc = union(enum) {
1176 implicit_pointer: struct {1176 implicit_pointer: struct {
1177 unit: Unit.Index,1177 unit: Unit.Index,
1178 entry: Entry.Index,1178 entry: Entry.Index,
1179 offset: i65,1179 offset: i65 = 0,
1180 },1180 },
1181 wasm_ext: union(enum) {1181 wasm_ext: union(enum) {
1182 local: u32,1182 local: u32,
...@@ -3060,13 +3060,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3060,13 +3060,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3060 } = switch (ip.indexToKey(nav_val.toIntern())) {3060 } = switch (ip.indexToKey(nav_val.toIntern())) {
3061 .int_type,3061 .int_type,
3062 .ptr_type,3062 .ptr_type,
3063 .restricted_ptr_type,
3064 .array_type,3063 .array_type,
3065 .vector_type,3064 .vector_type,
3066 .opt_type,3065 .opt_type,
3067 .error_union_type,3066 .error_union_type,
3068 .anyframe_type,3067 .anyframe_type,
3069 .simple_type,3068 .simple_type,
3069 .restricted_type,
3070 .tuple_type,3070 .tuple_type,
3071 .func_type,3071 .func_type,
3072 .error_set_type,3072 .error_set_type,
...@@ -3128,6 +3128,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3128,6 +3128,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3128 .aggregate,3128 .aggregate,
3129 .un,3129 .un,
3130 .bitpack,3130 .bitpack,
3131 .restricted_value,
3131 => if (nav.resolved.?.@"const") .@"const" else .@"var",3132 => if (nav.resolved.?.@"const") .@"const" else .@"var",
31323133
3133 .@"extern" => unreachable,3134 .@"extern" => unreachable,
...@@ -3509,12 +3510,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3509,12 +3510,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35093510
3510 if (value_index == .anyerror_type) return; // handled in `flush` instead3511 if (value_index == .anyerror_type) return; // handled in `flush` instead
35113512
3512 const value_ip_key = ip.indexToKey(value_index);3513 const value_ip_key: InternPool.Key = switch (ip.indexToKey(value_index)) {
3513 switch (value_ip_key) {
3514 .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`)3514 .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`)
3515 .@"extern" => return, // populated by the Nav instead (`initWipNav`)3515 .@"extern" => return, // populated by the Nav instead (`initWipNav`)
3516 else => {},3516 .restricted_value => |restricted_value| switch (Type.restrictedRepr(.fromInterned(restricted_value.ty), zcu)) {
3517 }3517 .indirect => .{ .restricted_value = restricted_value },
3518 .direct => ip.indexToKey(restricted_value.unrestricted_value),
3519 },
3520 else => |key| key,
3521 };
35183522
3519 switch (value_index) {3523 switch (value_index) {
3520 .generic_poison_type => log.debug("updateValue(anytype)", .{}),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,7 +3571,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35673571
3568 const diw = &wip_nav.debug_info.writer;3572 const diw = &wip_nav.debug_info.writer;
3569 var big_int_space: Value.BigIntSpace = undefined;3573 var big_int_space: Value.BigIntSpace = undefined;
3570 key: switch (value_ip_key) {3574 switch (value_ip_key) {
3571 .func => unreachable, // handled above3575 .func => unreachable, // handled above
3572 .@"extern" => unreachable, // handled above3576 .@"extern" => unreachable, // handled above
35733577
...@@ -3630,13 +3634,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3630,13 +3634,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3630 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));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 .array_type => |array_type| {3637 .array_type => |array_type| {
3641 const array_child_type: Type = .fromInterned(array_type.child);3638 const array_child_type: Type = .fromInterned(array_type.child);
3642 try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);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,6 +3844,28 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3847 .anyerror => unreachable, // already did early return above3844 .anyerror => unreachable, // already did early return above
3848 .adhoc_inferred_error_set => unreachable,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 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {3869 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
3851 try wip_nav.abbrevCode(.generated_empty_struct_type);3870 try wip_nav.abbrevCode(.generated_empty_struct_type);
3852 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});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,7 +4284,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4265 if (error_set_type.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));4284 if (error_set_type.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4266 },4285 },
4267 .inferred_error_set_type => |func| {4286 .inferred_error_set_type => |func| {
4268 try wip_nav.abbrevCode(.inferred_error_set_type);4287 try wip_nav.abbrevCode(.alias_type);
4269 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});4288 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
4270 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {4289 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {
4271 .none => .anyerror_type,4290 .none => .anyerror_type,
...@@ -4648,6 +4667,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -4648,6 +4667,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4648 }4667 }
4649 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));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 .memoized_call => unreachable, // not a value4679 .memoized_call => unreachable, // not a value
4652 }4680 }
4653 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());4681 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
...@@ -5209,7 +5237,7 @@ const AbbrevCode = enum {...@@ -5209,7 +5237,7 @@ const AbbrevCode = enum {
5209 tagged_union_default_field,5237 tagged_union_default_field,
5210 void_type,5238 void_type,
5211 numeric_type,5239 numeric_type,
5212 inferred_error_set_type,5240 alias_type,
5213 ptr_type,5241 ptr_type,
5214 ptr_sentinel_type,5242 ptr_sentinel_type,
5215 ptr_aligned_type,5243 ptr_aligned_type,
...@@ -5839,7 +5867,7 @@ const AbbrevCode = enum {...@@ -5839,7 +5867,7 @@ const AbbrevCode = enum {
5839 .{ .alignment, .udata },5867 .{ .alignment, .udata },
5840 },5868 },
5841 },5869 },
5842 .inferred_error_set_type = .{5870 .alias_type = .{
5843 .tag = .typedef,5871 .tag = .typedef,
5844 .attrs = &.{5872 .attrs = &.{
5845 .{ .name, .strp },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,7 +3349,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
33493349
3350 if (structure.modify) |modification| modification.operation.apply(3350 if (structure.modify) |modification| modification.operation.apply(
3351 elf.lazySymbolIfExists(modification.lazy_sym).?.node(elf).slice(&elf.mf),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}
33553362
src/print_value.zig+10-9
...@@ -49,7 +49,6 @@ pub fn print(...@@ -49,7 +49,6 @@ pub fn print(
49 switch (ip.indexToKey(val.toIntern())) {49 switch (ip.indexToKey(val.toIntern())) {
50 .int_type,50 .int_type,
51 .ptr_type,51 .ptr_type,
52 .restricted_ptr_type,
53 .array_type,52 .array_type,
54 .vector_type,53 .vector_type,
55 .opt_type,54 .opt_type,
...@@ -64,6 +63,7 @@ pub fn print(...@@ -64,6 +63,7 @@ pub fn print(
64 .func_type,63 .func_type,
65 .error_set_type,64 .error_set_type,
66 .inferred_error_set_type,65 .inferred_error_set_type,
66 .restricted_type,
67 => try Type.print(val.toType(), writer, pt, null),67 => try Type.print(val.toType(), writer, pt, null),
68 .undef => try writer.writeAll("undefined"),68 .undef => try writer.writeAll("undefined"),
69 .simple_value => |simple_value| switch (simple_value) {69 .simple_value => |simple_value| switch (simple_value) {
...@@ -88,7 +88,7 @@ pub fn print(...@@ -88,7 +88,7 @@ pub fn print(
88 .err_name => |err_name| try writer.print("error.{f}", .{88 .err_name => |err_name| try writer.print("error.{f}", .{
89 err_name.fmt(ip),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 .enum_literal => |enum_literal| try writer.print(".{f}", .{93 .enum_literal => |enum_literal| try writer.print(".{f}", .{
94 enum_literal.fmt(ip),94 enum_literal.fmt(ip),
...@@ -102,7 +102,7 @@ pub fn print(...@@ -102,7 +102,7 @@ pub fn print(
102 return writer.writeAll("@enumFromInt(...)");102 return writer.writeAll("@enumFromInt(...)");
103 }103 }
104 try writer.writeAll("@enumFromInt(");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 try writer.writeAll(")");106 try writer.writeAll(")");
107 },107 },
108 .float => |float| switch (float.storage) {108 .float => |float| switch (float.storage) {
...@@ -130,7 +130,7 @@ pub fn print(...@@ -130,7 +130,7 @@ pub fn print(
130 if (level == 0) {130 if (level == 0) {
131 try writer.writeAll("(...)");131 try writer.writeAll("(...)");
132 } else {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 try writer.writeAll("]");135 try writer.writeAll("]");
136 },136 },
...@@ -148,7 +148,7 @@ pub fn print(...@@ -148,7 +148,7 @@ pub fn print(
148 },148 },
149 .opt => |opt| switch (opt.val) {149 .opt => |opt| switch (opt.val) {
150 .none => try writer.writeAll("null"),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 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),153 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),
154 .un => |un| {154 .un => |un| {
...@@ -159,13 +159,13 @@ pub fn print(...@@ -159,13 +159,13 @@ pub fn print(
159 if (un.tag == .none) {159 if (un.tag == .none) {
160 const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt);160 const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt);
161 try writer.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)});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 try writer.writeAll("))");163 try writer.writeAll("))");
164 } else {164 } else {
165 try writer.writeAll(".{ ");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 try writer.writeAll(" = ");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 try writer.writeAll(" }");169 try writer.writeAll(" }");
170 }170 }
171 },171 },
...@@ -198,6 +198,7 @@ pub fn print(...@@ -198,6 +198,7 @@ pub fn print(
198 else => unreachable,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 .memoized_call => unreachable,202 .memoized_call => unreachable,
202 }203 }
203}204}
...@@ -470,7 +471,7 @@ pub fn printPtrDerivation(...@@ -470,7 +471,7 @@ pub fn printPtrDerivation(
470 if (x.level == 0) {471 if (x.level == 0) {
471 try writer.writeAll("...");472 try writer.writeAll("...");
472 } else {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 try writer.writeByte(')');476 try writer.writeByte(')');
476 },477 },
src/print_zir.zig+11-8
...@@ -622,14 +622,6 @@ const Writer = struct {...@@ -622,14 +622,6 @@ const Writer = struct {
622 try stream.writeAll(")) ");622 try stream.writeAll(")) ");
623 try self.writeSrcNode(stream, extra.node);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 .reify_fn => {625 .reify_fn => {
634 const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;626 const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;
635 try self.writeInstRef(stream, extra.param_types);627 try self.writeInstRef(stream, extra.param_types);
...@@ -642,6 +634,17 @@ const Writer = struct {...@@ -642,6 +634,17 @@ const Writer = struct {
642 try stream.writeAll(")) ");634 try stream.writeAll(")) ");
643 try self.writeSrcNode(stream, extra.node);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 .reify_struct => {648 .reify_struct => {
646 const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;649 const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
647 const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);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,7 +908,7 @@ pub fn zigBackend(target: *const std.Target, use_llvm: bool) std.builtin.Compile
908 };908 };
909}909}
910910
911pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, comptime feature: Feature) bool {911pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, incremental: bool, comptime feature: Feature) bool {
912 return switch (feature) {912 return switch (feature) {
913 .panic_fn => switch (backend) {913 .panic_fn => switch (backend) {
914 .stage2_aarch64,914 .stage2_aarch64,
...@@ -949,7 +949,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt...@@ -949,7 +949,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
949 else => true,949 else => true,
950 },950 },
951 .restricted_types => switch (backend) {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 else => false,954 else => false,
954 },955 },
955 };956 };