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
57715771
57725772 {#header_open|@Restricted#}
57735773 <pre>{#syntax#}@Restricted(
5774 comptime Pointer: type,
5774 comptime Underlying: type,
57755775) 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>
57775777 {#header_close#}
57785778
57795779 {#header_open|@Fn#}
lib/std/debug.zig+2-2
......@@ -201,9 +201,9 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type {
201201 @branchHint(.cold);
202202 call("'noreturn' function returned", @returnAddress());
203203 }
204 pub fn corruptRestrictedPointer() noreturn {
204 pub fn corruptRestrictedValue() noreturn {
205205 @branchHint(.cold);
206 call("corrupt restricted pointer value", @returnAddress());
206 call("corrupt restricted value", @returnAddress());
207207 }
208208 };
209209}
lib/std/debug/no_panic.zig+1-1
......@@ -135,7 +135,7 @@ pub fn noreturnReturned() noreturn {
135135 @trap();
136136}
137137
138pub fn corruptRestrictedPointer() noreturn {
138pub fn corruptRestrictedValue() noreturn {
139139 @branchHint(.cold);
140140 @trap();
141141}
lib/std/debug/simple_panic.zig+2-2
......@@ -127,6 +127,6 @@ pub fn noreturnReturned() noreturn {
127127 call("'noreturn' function returned", null);
128128}
129129
130pub fn corruptRestrictedPointer() noreturn {
131 call("corrupt restricted pointer value", null);
130pub fn corruptRestrictedValue() noreturn {
131 call("corrupt restricted value", null);
132132}
lib/std/zig/AstGen.zig+9-9
......@@ -9320,15 +9320,6 @@ fn builtinCall(
93209320 });
93219321 return rvalue(gz, ri, result, node);
93229322 },
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 },
93329323 .Fn => {
93339324 const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes);
93349325 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(
93499340 });
93509341 return rvalue(gz, ri, result, node);
93519342 },
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 },
93529352 .Struct => {
93539353 const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
93549354 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 {
20622062 /// Implements builtin `@Pointer`.
20632063 /// `operand` is payload index to `ReifyPointer`.
20642064 reify_pointer,
2065 /// Implements builtin `@Restricted`.
2066 /// `operand` is payload index to `UnNode`.
2067 /// `small` contains `NameStrategy`.
2068 reify_restricted,
20692065 /// Implements builtin `@Fn`.
20702066 /// `operand` is payload index to `ReifyFn`.
20712067 reify_fn,
2068 /// Implements builtin `@Restricted`.
2069 /// `operand` is payload index to `ReifyRestricted`.
2070 /// `small` contains `NameStrategy`.
2071 reify_restricted,
20722072 /// Implements builtin `@Struct`.
20732073 /// `operand` is payload index to `ReifyStruct`.
20742074 /// `small` contains `NameStrategy`.
......@@ -3266,6 +3266,13 @@ pub const Inst = struct {
32663266 fn_attrs: Ref,
32673267 };
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
32693276 pub const ReifyStruct = struct {
32703277 src_line: u32,
32713278 /// 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 {
501501 };
502502 };
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
506506 const root_error_tracing = b: {
507507 if (options.root_error_tracing) |x| break :b x;
src/InternPool.zig+191-109
......@@ -1969,7 +1969,6 @@ pub const CaptureValue = packed struct(u32) {
19691969pub const Key = union(enum) {
19701970 int_type: IntType,
19711971 ptr_type: PtrType,
1972 restricted_ptr_type: RestrictedPtrType,
19731972 array_type: ArrayType,
19741973 vector_type: VectorType,
19751974 opt_type: Index,
......@@ -1978,6 +1977,7 @@ pub const Key = union(enum) {
19781977 anyframe_type: Index,
19791978 error_union_type: ErrorUnionType,
19801979 simple_type: SimpleType,
1980 restricted_type: RestrictedType,
19811981 /// This represents a struct that has been explicitly declared in source code,
19821982 /// or was created with `@Struct`. It is unique and based on a declaration.
19831983 struct_type: ContainerType,
......@@ -2021,6 +2021,8 @@ pub const Key = union(enum) {
20212021 un: Union,
20222022 /// An instance of a `packed struct` or `packed union`.
20232023 bitpack: Bitpack,
2024 /// An instance of a restricted type.
2025 restricted_value: RestrictedValue,
20242026
20252027 /// A comptime function call with a memoized result.
20262028 memoized_call: Key.MemoizedCall,
......@@ -2095,14 +2097,6 @@ pub const Key = union(enum) {
20952097 pub const AddressSpace = std.builtin.AddressSpace;
20962098 };
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
21062100 /// Extern so that hashing can be done via memory reinterpreting.
21072101 pub const ArrayType = extern struct {
21082102 len: u64,
......@@ -2206,6 +2200,13 @@ pub const Key = union(enum) {
22062200 }
22072201 };
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
22092210 pub const Extern = struct {
22102211 /// The name of the extern symbol.
22112212 name: NullTerminatedString,
......@@ -2581,6 +2582,12 @@ pub const Key = union(enum) {
25812582 backing_int_val: Index,
25822583 };
25832584
2585 pub const RestrictedValue = extern struct {
2586 /// The restricted type.
2587 ty: Index,
2588 unrestricted_value: Index,
2589 };
2590
25842591 pub const MemoizedCall = struct {
25852592 func: Index,
25862593 arg_values: []const Index,
......@@ -2599,13 +2606,13 @@ pub const Key = union(enum) {
25992606 return switch (key) {
26002607 // TODO: assert no padding in these types
26012608 inline .ptr_type,
2602 .restricted_ptr_type,
26032609 .array_type,
26042610 .vector_type,
26052611 .opt_type,
26062612 .anyframe_type,
26072613 .error_union_type,
26082614 .simple_type,
2615 .restricted_type,
26092616 .simple_value,
26102617 .opt,
26112618 .undef,
......@@ -2614,6 +2621,7 @@ pub const Key = union(enum) {
26142621 .enum_tag,
26152622 .inferred_error_set_type,
26162623 .un,
2624 .restricted_value,
26172625 => |x| Hash.hash(seed, asBytes(&x)),
26182626
26192627 .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) {
28932901 const b_info = b.bitpack;
28942902 return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val;
28952903 },
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
28972909 .@"extern" => |a_info| {
28982910 const b_info = b.@"extern";
......@@ -3027,7 +3039,7 @@ pub const Key = union(enum) {
30273039 }
30283040 },
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
30323044 inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| {
30333045 const b_info = @field(b, @tagName(a_tag_ct));
......@@ -3130,7 +3142,6 @@ pub const Key = union(enum) {
31303142 return switch (key) {
31313143 .int_type,
31323144 .ptr_type,
3133 .restricted_ptr_type,
31343145 .array_type,
31353146 .vector_type,
31363147 .opt_type,
......@@ -3139,6 +3150,7 @@ pub const Key = union(enum) {
31393150 .error_set_type,
31403151 .inferred_error_set_type,
31413152 .simple_type,
3153 .restricted_type,
31423154 .struct_type,
31433155 .union_type,
31443156 .opaque_type,
......@@ -3160,6 +3172,7 @@ pub const Key = union(enum) {
31603172 .aggregate,
31613173 .un,
31623174 .bitpack,
3175 .restricted_value,
31633176 => |x| x.ty,
31643177
31653178 .enum_literal => .enum_literal_type,
......@@ -4187,7 +4200,6 @@ pub const Index = enum(u32) {
41874200 type_array_small: struct { data: *Vector },
41884201 type_vector: struct { data: *Vector },
41894202 type_pointer: struct { data: *Tag.TypePointer },
4190 type_restricted: struct { data: *Tag.TypeRestricted },
41914203 type_slice: DataIsIndex,
41924204 type_optional: DataIsIndex,
41934205 type_anyframe: DataIsIndex,
......@@ -4222,6 +4234,7 @@ pub const Index = enum(u32) {
42224234 },
42234235 },
42244236
4237 type_restricted: struct { data: *Tag.TypeRestricted },
42254238 type_struct: struct { data: *Tag.TypeStruct },
42264239 type_struct_packed_auto: struct { data: *Tag.TypeStructPacked },
42274240 type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked },
......@@ -4302,6 +4315,7 @@ pub const Index = enum(u32) {
43024315 },
43034316 repeated: struct { data: *Repeated },
43044317 bitpack: struct { data: *Key.Bitpack },
4318 restricted_value: struct { data: *Key.RestrictedValue },
43054319
43064320 memoized_call: struct {
43074321 const @"data.args_len" = opaque {};
......@@ -4786,9 +4800,6 @@ pub const Tag = enum(u8) {
47864800 /// A slice type.
47874801 /// data is Index of underlying pointer type.
47884802 type_slice,
4789 /// A restricted pointer type.
4790 /// data is payload to `TypeRestricted`.
4791 type_restricted,
47924803 /// An optional type.
47934804 /// data is the child type.
47944805 type_optional,
......@@ -4815,6 +4826,9 @@ pub const Tag = enum(u8) {
48154826 /// data is extra index of `TypeTuple`.
48164827 type_tuple,
48174828
4829 /// A restricted pointer type.
4830 /// data is payload to `TypeRestricted`.
4831 type_restricted,
48184832 /// A non-packed struct type.
48194833 /// data is extra index of `TypeStruct`.
48204834 type_struct,
......@@ -5037,6 +5051,9 @@ pub const Tag = enum(u8) {
50375051 /// An instance of a `packed struct` or `packed union`.
50385052 /// data is extra index to `Key.Bitpack`.
50395053 bitpack,
5054 /// An instance of a restricted type.
5055 /// data is extra index to `Key.RestrictedValue`.
5056 restricted_value,
50405057
50415058 /// A memoized comptime function call result.
50425059 /// data is extra index to `MemoizedCall`
......@@ -5127,7 +5144,6 @@ pub const Tag = enum(u8) {
51275144 .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector },
51285145 .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector },
51295146 .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer },
5130 .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted },
51315147 .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index },
51325148 .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index },
51335149 .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index },
......@@ -5171,6 +5187,7 @@ pub const Tag = enum(u8) {
51715187 },
51725188 },
51735189
5190 .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted },
51745191 .type_struct = .{
51755192 .summary = .@"{.payload.name%summary#\"}",
51765193 .payload = TypeStruct,
......@@ -5363,6 +5380,7 @@ pub const Tag = enum(u8) {
53635380 },
53645381 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },
53655382 .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack },
5383 .restricted_value = .{ .summary = .@"@as({.payload.unrestricted_value%summary}, {})", .payload = Key.RestrictedValue },
53665384
53675385 .memoized_call = .{
53685386 .summary = .@"@memoize({.payload.func%summary})",
......@@ -5390,8 +5408,8 @@ pub const Tag = enum(u8) {
53905408 /// The name of this restricted type.
53915409 name: NullTerminatedString,
53925410
5393 /// The pointer type this restricted type is based on.
5394 unrestricted_ptr_type: Index,
5411 /// The underlying unrestricted type.
5412 unrestricted_type: Index,
53955413 };
53965414
53975415 pub const Extern = struct {
......@@ -6486,14 +6504,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
64866504 return .{ .ptr_type = ptr_info };
64876505 },
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
64976507 .type_optional => .{ .opt_type = @enumFromInt(data) },
64986508 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },
64996509
......@@ -6509,6 +6519,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
65096519 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
65106520 .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 },
65126529 .type_struct => .{ .struct_type = ns: {
65136530 const extra_list = unwrapped_index.getExtra(ip);
65146531 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
......@@ -6903,6 +6920,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
69036920 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
69046921 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
69056922 .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) },
6923 .restricted_value => .{ .restricted_value = extraData(unwrapped_index.getExtra(ip), Key.RestrictedValue, data) },
69066924
69076925 .memoized_call => {
69086926 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:
72767294 .data = try addExtra(extra, ptr_type_adjusted),
72777295 });
72787296 },
7279 .restricted_ptr_type => unreachable, // instead getReifiedRestrictedType
72807297 .array_type => |array_type| {
72817298 assert(array_type.child != .none);
72827299 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:
73827399 });
73837400 },
73847401
7402 .restricted_type => unreachable, // instead use: getReifiedRestrictedType
73857403 .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType
73867404 .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType
73877405 .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:
74077425 },
74087426
74097427 .ptr => |ptr| {
7410 const ptr_type = switch (ip.indexToKey(ptr.ty)) {
7411 .ptr_type => |ptr_type| ptr_type,
7412 .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
7413 else => unreachable,
7414 };
7428 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
74157429 assert(ptr_type.flags.size != .slice);
74167430 items.appendAssumeCapacity(switch (ptr.base_addr) {
74177431 .nav => |nav| .{
......@@ -7983,6 +7997,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
79837997 .data = try addExtra(extra, bitpack),
79847998 });
79857999 },
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
79878009 .memoized_call => |memoized_call| {
79888010 for (memoized_call.arg_values) |arg| assert(arg != .none);
......@@ -8009,11 +8031,11 @@ pub fn getReifiedRestrictedType(
80098031 io: Io,
80108032 tid: Zcu.PerThread.Id,
80118033 zir_index: TrackedInst.Index,
8012 unrestricted_ptr_type: Index,
8034 unrestricted_type: Index,
80138035) 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 = .{
80158037 .zir_index = zir_index,
8016 .unrestricted_ptr_type = unrestricted_ptr_type,
8038 .unrestricted_type = unrestricted_type,
80178039 } });
80188040 defer gop.deinit();
80198041 if (gop == .existing) return .{ .existing = gop.existing };
......@@ -8028,7 +8050,7 @@ pub fn getReifiedRestrictedType(
80288050 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{
80298051 .zir_index = zir_index,
80308052 .name = undefined,
8031 .unrestricted_ptr_type = unrestricted_ptr_type,
8053 .unrestricted_type = unrestricted_type,
80328054 });
80338055 items.appendAssumeCapacity(.{
80348056 .tag = .type_restricted,
......@@ -10028,7 +10050,6 @@ test "basic usage" {
1002810050pub fn childType(ip: *const InternPool, i: Index) Index {
1002910051 return switch (ip.indexToKey(i)) {
1003010052 .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,
1003210053 .vector_type => |vector_type| vector_type.child,
1003310054 .array_type => |array_type| array_type.child,
1003410055 .opt_type, .anyframe_type => |child| child,
......@@ -10111,28 +10132,22 @@ pub fn getCoerced(
1011110132 .val = .none,
1011210133 } });
1011310134
10114 new_ty: switch (ip.indexToKey(new_ty)) {
10115 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
10116 .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{
10117 .ty = new_ty,
10135 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
10136 .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{
10137 .ty = new_ty,
10138 .base_addr = .int,
10139 .byte_offset = 0,
10140 } }),
10141 .slice => return ip.get(gpa, io, tid, .{ .slice = .{
10142 .ty = new_ty,
10143 .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{
10144 .ty = ip.slicePtrType(new_ty),
1011810145 .base_addr = .int,
1011910146 .byte_offset = 0,
1012010147 } }),
10121 .slice => return ip.get(gpa, io, tid, .{ .slice = .{
10122 .ty = new_ty,
10123 .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{
10124 .ty = ip.slicePtrType(new_ty),
10125 .base_addr = .int,
10126 .byte_offset = 0,
10127 } }),
10128 .len = .undef_usize,
10129 } }),
10130 },
10131 .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{
10132 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
10133 },
10134 else => {},
10135 }
10148 .len = .undef_usize,
10149 } }),
10150 };
1013610151 },
1013710152 else => {
1013810153 const unwrapped_val = val.unwrap(ip);
......@@ -10211,40 +10226,28 @@ pub fn getCoerced(
1021110226 },
1021210227 else => {},
1021310228 },
10214 .slice => |slice| new_ty: switch (ip.indexToKey(new_ty)) {
10215 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
10216 .one, .many, .c => {},
10217 .slice => return ip.get(gpa, io, tid, .{ .slice = .{
10218 .ty = new_ty,
10219 .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)),
10220 .len = slice.len,
10221 } }),
10222 },
10223 .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{
10224 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
10225 },
10226 else => if (ip.isIntegerType(new_ty)) return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty),
10227 },
10228 .ptr => |ptr| new_ty: switch (ip.indexToKey(new_ty)) {
10229 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
10230 .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{
10231 .ty = new_ty,
10232 .base_addr = ptr.base_addr,
10233 .byte_offset = ptr.byte_offset,
10234 } }),
10235 .slice => {},
10236 },
10237 .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{
10238 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
10239 },
10240 else => if (ip.isIntegerType(new_ty)) switch (ptr.base_addr) {
10229 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .slice)
10230 return ip.get(gpa, io, tid, .{ .slice = .{
10231 .ty = new_ty,
10232 .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)),
10233 .len = slice.len,
10234 } })
10235 else if (ip.isIntegerType(new_ty))
10236 return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty),
10237 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .slice)
10238 return ip.get(gpa, io, tid, .{ .ptr = .{
10239 .ty = new_ty,
10240 .base_addr = ptr.base_addr,
10241 .byte_offset = ptr.byte_offset,
10242 } })
10243 else if (ip.isIntegerType(new_ty))
10244 switch (ptr.base_addr) {
1024110245 .int => return ip.get(gpa, io, tid, .{ .int = .{
1024210246 .ty = .usize_type,
1024310247 .storage = .{ .u64 = @intCast(ptr.byte_offset) },
1024410248 } }),
1024510249 else => {},
1024610250 },
10247 },
1024810251 .opt => |opt| switch (ip.indexToKey(new_ty)) {
1024910252 .ptr_type => |ptr_type| return switch (opt.val) {
1025010253 .none => switch (ptr_type.flags.size) {
......@@ -10484,6 +10487,22 @@ pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
1048410487/// includes .comptime_int_type
1048510488pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
1048610489 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,
1048710506 .usize_type,
1048810507 .isize_type,
1048910508 .c_char_type,
......@@ -10497,7 +10516,8 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
1049710516 .c_ulonglong_type,
1049810517 .comptime_int_type,
1049910518 => true,
10500 else => switch (ty.unwrap(ip).getTag(ip)) {
10519 else => false,
10520 _ => switch (ty.unwrap(ip).getTag(ip)) {
1050110521 .type_int_signed,
1050210522 .type_int_unsigned,
1050310523 => true,
......@@ -10508,53 +10528,114 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
1050810528
1050910529/// does not include .enum_literal_type
1051010530pub 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 };
1051210542}
1051310543
1051410544pub 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 };
1051610549}
1051710550
1051810551pub 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 };
1052010560}
1052110561
1052210562pub fn isOptionalType(ip: *const InternPool, ty: Index) bool {
10523 return ip.indexToKey(ty) == .opt_type;
10563 return ty.unwrap(ip).getTag(ip) == .type_optional;
1052410564}
1052510565
1052610566/// includes .inferred_error_set_type
1052710567pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {
1052810568 return switch (ty) {
1052910569 .anyerror_type, .adhoc_inferred_error_set_type => true,
10530 else => switch (ip.indexToKey(ty)) {
10531 .error_set_type, .inferred_error_set_type => true,
10570 else => false,
10571 _ => switch (ty.unwrap(ip).getTag(ip)) {
10572 .type_error_set, .type_inferred_error_set => true,
1053210573 else => false,
1053310574 },
1053410575 };
1053510576}
1053610577
1053710578pub 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;
1053910580}
1054010581
1054110582pub 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 };
1054310591}
1054410592
1054510593pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {
10546 return switch (ip.indexToKey(ty)) {
10547 .array_type, .vector_type, .tuple_type, .struct_type => true,
10594 return switch (ty.unwrap(ip).getTag(ip)) {
10595 .type_array_big,
10596 .type_array_small,
10597 .type_vector,
10598 .type_tuple,
10599 .type_struct,
10600 .type_struct_packed_auto,
10601 .type_struct_packed_explicit,
10602 .type_struct_packed_auto_defaults,
10603 .type_struct_packed_explicit_defaults,
10604 => true,
1054810605 else => false,
1054910606 };
1055010607}
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
1055210617pub 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 };
1055410627}
1055510628
1055610629pub 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 });
1055810639}
1055910640
1056010641pub fn dump(ip: *const InternPool) void {
......@@ -10695,7 +10776,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1069510776 .type_array_big => @sizeOf(Array),
1069610777 .type_vector => @sizeOf(Vector),
1069710778 .type_pointer => @sizeOf(Tag.TypePointer),
10698 .type_restricted => @sizeOf(Tag.TypeRestricted),
1069910779 .type_slice => 0,
1070010780 .type_optional => 0,
1070110781 .type_anyframe => 0,
......@@ -10718,6 +10798,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1071810798 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
1071910799 },
1072010800
10801 .type_restricted => @sizeOf(Tag.TypeRestricted),
1072110802 .type_struct => b: {
1072210803 var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
1072310804 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
......@@ -10908,7 +10989,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1090810989 .func_coerced => @sizeOf(Tag.FuncCoerced),
1090910990 .only_possible_value => 0,
1091010991 .union_value => @sizeOf(Key.Union),
10911 .bitpack => 2 * @sizeOf(u32),
10992 .bitpack => @sizeOf(Key.Bitpack),
10993 .restricted_value => @sizeOf(Key.RestrictedValue),
1091210994
1091310995 .memoized_call => b: {
1091410996 const info = extraData(extra_list, MemoizedCall, data);
......@@ -10957,7 +11039,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1095711039 .type_array_big,
1095811040 .type_vector,
1095911041 .type_pointer,
10960 .type_restricted,
1096111042 .type_optional,
1096211043 .type_anyframe,
1096311044 .type_error_union,
......@@ -10966,6 +11047,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1096611047 .type_inferred_error_set,
1096711048 .type_tuple,
1096811049 .type_function,
11050 .type_restricted,
1096911051 .type_struct,
1097011052 .type_struct_packed_auto,
1097111053 .type_struct_packed_explicit,
......@@ -11023,6 +11105,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1102311105 .func_coerced,
1102411106 .union_value,
1102511107 .bitpack,
11108 .restricted_value,
1102611109 .memoized_call,
1102711110 => try w.print("{d}", .{data}),
1102811111
......@@ -11696,7 +11779,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1169611779 .type_array_small,
1169711780 .type_vector,
1169811781 .type_pointer,
11699 .type_restricted,
1170011782 .type_slice,
1170111783 .type_optional,
1170211784 .type_anyframe,
......@@ -11706,6 +11788,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1170611788 .type_inferred_error_set,
1170711789 .type_tuple,
1170811790 .type_function,
11791 .type_restricted,
1170911792 .type_struct,
1171011793 .type_struct_packed_auto,
1171111794 .type_struct_packed_explicit,
......@@ -11753,6 +11836,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1175311836 .aggregate,
1175411837 .repeated,
1175511838 .bitpack,
11839 .restricted_value,
1175611840 => |t| {
1175711841 const extra_list = unwrapped_index.getExtra(ip);
1175811842 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 {
1202712111 .bool_false => unreachable,
1202812112 .empty_tuple => unreachable,
1202912113
12030 _ => switch (index.unwrap(ip).getTag(ip)) {
12114 _ => return switch (index.unwrap(ip).getTag(ip)) {
1203112115 .removed => unreachable,
1203212116
1203312117 .type_int_signed,
......@@ -12042,7 +12126,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1204212126
1204312127 .type_pointer,
1204412128 .type_slice,
12045 .type_restricted,
1204612129 => .pointer,
1204712130
1204812131 .type_optional => .optional,
......@@ -12079,6 +12162,8 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1207912162
1208012163 .type_function => .@"fn",
1208112164
12165 .type_restricted => unreachable,
12166
1208212167 // values, not types
1208312168 .undef,
1208412169 .simple_value,
......@@ -12128,6 +12213,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1212812213 .aggregate,
1212912214 .repeated,
1213012215 .bitpack,
12216 .restricted_value,
1213112217 // memoization, not types
1213212218 .memoized_call,
1213312219 => unreachable,
......@@ -12358,11 +12444,7 @@ pub fn addFieldTagValue(
1235812444/// encoding instead of `Tag.ptr_uav_aligned` when possible.
1235912445fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
1236012446 if (a_ty == b_ty) return true;
12361 const b_info = switch (ip.indexToKey(b_ty)) {
12362 else => unreachable,
12363 .ptr_type => |ptr_type| ptr_type,
12364 .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
12365 };
12447 const b_info = ip.indexToKey(b_ty).ptr_type;
1236612448 return a_info.flags.alignment == b_info.flags.alignment and
1236712449 (a_info.child == b_info.child or a_info.flags.alignment != .none);
1236812450}
src/Sema.zig+191-177
......@@ -1435,8 +1435,8 @@ fn analyzeBodyInner(
14351435 .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended),
14361436 .reify_tuple => try sema.zirReifyTuple( block, extended),
14371437 .reify_pointer => try sema.zirReifyPointer( block, extended),
1438 .reify_restricted => try sema.zirReifyRestricted( block, extended, inst),
14391438 .reify_fn => try sema.zirReifyFn( block, extended),
1439 .reify_restricted => try sema.zirReifyRestricted( block, extended, inst),
14401440 .reify_struct => try sema.zirReifyStruct( block, extended, inst),
14411441 .reify_union => try sema.zirReifyUnion( block, extended, inst),
14421442 .reify_enum => try sema.zirReifyEnum( block, extended, inst),
......@@ -4641,10 +4641,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
46414641 const src = block.nodeOffset(inst_data.src_node);
46424642 const operand = sema.resolveInst(inst_data.operand);
46434643 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) {
46464647 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)) {
46484649 .one, .c => {},
46494650 .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{operand_ty.fmt(pt)}),
46504651 .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
46524653
46534654 if (sema.resolveValue(operand)) |val| {
46544655 // 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) {
46564657 return sema.fail(block, src, "cannot dereference undefined value", .{});
46574658 }
46584659 }
......@@ -7815,23 +7816,22 @@ fn analyzeDeclLiteral(
78157816 block: *Block,
78167817 src: LazySrcLoc,
78177818 name: InternPool.NullTerminatedString,
7818 orig_ty: Type,
7819 ty: Type,
78197820 do_coerce: bool,
78207821) CompileError!Air.Inst.Ref {
78217822 const pt = sema.pt;
78227823 const zcu = pt.zcu;
78237824
78247825 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) {
78267828 // Treat this as a normal enum literal.
78277829 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
78287830 }
7829
7830 var ty = orig_ty;
7831 while (true) switch (ty.zigTypeTag(zcu)) {
7832 .error_union => ty = ty.errorUnionPayload(zcu),
7833 .optional => ty = ty.optionalChild(zcu),
7834 .pointer => ty = if (ty.isSinglePointer(zcu)) ty.childType(zcu) else break,
7831 while (true) switch (unrestricted_ty.zigTypeTag(zcu)) {
7832 .error_union => unrestricted_ty = unrestricted_ty.errorUnionPayload(zcu),
7833 .optional => unrestricted_ty = unrestricted_ty.optionalChild(zcu),
7834 .pointer => unrestricted_ty = if (unrestricted_ty.isSinglePointer(zcu)) unrestricted_ty.childType(zcu) else break,
78357835 .enum_literal, .error_set => {
78367836 // Treat this as a normal enum literal.
78377837 break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
......@@ -7839,7 +7839,7 @@ fn analyzeDeclLiteral(
78397839 else => break,
78407840 };
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);
78437843 };
78447844
78457845 // Decl literals cannot lookup runtime `var`s.
......@@ -7848,7 +7848,7 @@ fn analyzeDeclLiteral(
78487848 }
78497849
78507850 if (do_coerce) {
7851 return sema.coerce(block, orig_ty, uncoerced_result, src);
7851 return sema.coerce(block, ty, uncoerced_result, src);
78527852 } else {
78537853 return uncoerced_result;
78547854 }
......@@ -16170,16 +16170,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1617016170 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1617116171 const src = block.nodeOffset(inst_data.src_node);
1617216172 const ty = try sema.resolveType(block, src, inst_data.operand);
16173 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
1617316174 const type_info_ty = try sema.getBuiltinType(src, .Type);
1617416175 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| {
1617916180 try sema.declareDependency(.{ .namespace = type_decl_inst });
1618016181 }
1618116182
16182 switch (ty.zigTypeTag(zcu)) {
16183 switch (unrestricted_ty.zigTypeTag(zcu)) {
1618316184 .type,
1618416185 .void,
1618516186 .bool,
......@@ -16202,7 +16203,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1620216203 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");
1620316204 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).?;
1620616207 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
1620716208 var func_is_generic = false;
1620816209
......@@ -16308,7 +16309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1630816309 .int => {
1630916310 const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int");
1631016311 const signedness_ty = try sema.getBuiltinType(src, .Signedness);
16311 const info = ty.intInfo(zcu);
16312 const info = unrestricted_ty.intInfo(zcu);
1631216313 const field_values = .{
1631316314 // signedness: Signedness,
1631416315 (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
1632616327
1632716328 const field_vals = .{
1632816329 // bits: u16,
16329 (try pt.intValue(.u16, ty.floatBits(zcu.getTarget()))).toIntern(),
16330 (try pt.intValue(.u16, unrestricted_ty.floatBits(zcu.getTarget()))).toIntern(),
1633016331 };
1633116332 return Air.internedToRef((try pt.internUnion(.{
1633216333 .ty = type_info_ty.toIntern(),
......@@ -16335,7 +16336,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1633516336 })));
1633616337 },
1633716338 .pointer => {
16338 const info = ty.ptrInfo(zcu);
16339 const info = unrestricted_ty.ptrInfo(zcu);
1633916340 const alignment_ty = try pt.optionalType(.usize_type);
1634016341 const alignment_val: Value = val: {
1634116342 const bytes = info.flags.alignment.toByteUnits() orelse {
......@@ -16382,7 +16383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1638216383 .array => {
1638316384 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");
1638416385
16385 const info = ty.arrayInfo(zcu);
16386 const info = unrestricted_ty.arrayInfo(zcu);
1638616387 const field_values = .{
1638716388 // len: comptime_int,
1638816389 (try pt.intValue(.comptime_int, info.len)).toIntern(),
......@@ -16400,7 +16401,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1640016401 .vector => {
1640116402 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");
1640216403
16403 const info = ty.arrayInfo(zcu);
16404 const info = unrestricted_ty.arrayInfo(zcu);
1640416405 const field_values = .{
1640516406 // len: comptime_int,
1640616407 (try pt.intValue(.comptime_int, info.len)).toIntern(),
......@@ -16418,7 +16419,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1641816419
1641916420 const field_values = .{
1642016421 // child: type,
16421 ty.optionalChild(zcu).toIntern(),
16422 unrestricted_ty.optionalChild(zcu).toIntern(),
1642216423 };
1642316424 return Air.internedToRef((try pt.internUnion(.{
1642416425 .ty = type_info_ty.toIntern(),
......@@ -16433,7 +16434,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1643316434 // Build our list of Error values
1643416435 // Optional value is only null if anyerror
1643516436 // 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())) {
1643716438 .anyerror_type => null,
1643816439 else => |err_set_ty_index| blk: {
1643916440 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
1652216523
1652316524 const field_values = .{
1652416525 // error_set: type,
16525 ty.errorUnionSet(zcu).toIntern(),
16526 unrestricted_ty.errorUnionSet(zcu).toIntern(),
1652616527 // payload: type,
16527 ty.errorUnionPayload(zcu).toIntern(),
16528 unrestricted_ty.errorUnionPayload(zcu).toIntern(),
1652816529 };
1652916530 return Air.internedToRef((try pt.internUnion(.{
1653016531 .ty = type_info_ty.toIntern(),
......@@ -16533,7 +16534,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1653316534 })));
1653416535 },
1653516536 .@"enum" => {
16536 const enum_obj = ip.loadEnumType(ty.toIntern());
16537 const enum_obj = ip.loadEnumType(unrestricted_ty.toIntern());
1653716538 const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive);
1653816539
1653916540 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
1661516616 } });
1661616617 };
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
1662016621 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1662116622
1662216623 const field_values = .{
1662316624 // tag_type: type,
16624 ip.loadEnumType(ty.toIntern()).int_tag_type,
16625 ip.loadEnumType(unrestricted_ty.toIntern()).int_tag_type,
1662516626 // fields: []const EnumField,
1662616627 fields_val,
1662716628 // decls: []const Declaration,
......@@ -16639,7 +16640,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1663916640 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
1664016641 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());
1664316644 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
1664416645 const layout = union_obj.layout;
1664516646
......@@ -16678,7 +16679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1667816679 const alignment_ty = try pt.optionalType(.usize_type);
1667916680 const alignment_val: Value = val: {
1668016681 const a: Alignment = switch (layout) {
16681 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),
16682 .auto, .@"extern" => unrestricted_ty.explicitFieldAlignment(field_index, zcu),
1668216683 .@"packed" => .none,
1668316684 };
1668416685 const bytes = a.toByteUnits() orelse {
......@@ -16730,11 +16731,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1673016731 } });
1673116732 };
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
1673516736 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
1673616737 .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,
1673816739 } });
1673916740
1674016741 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
1676316764 var struct_field_vals: []InternPool.Index = &.{};
1676416765 defer gpa.free(struct_field_vals);
1676516766 fv: {
16766 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
16767 const struct_type = switch (ip.indexToKey(unrestricted_ty.toIntern())) {
1676716768 .tuple_type => |tuple_type| {
1676816769 struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len);
1676916770 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
1681516816 }
1681616817 break :fv;
1681716818 },
16818 .struct_type => ip.loadStructType(ty.toIntern()),
16819 .struct_type => ip.loadStructType(unrestricted_ty.toIntern()),
1681916820 else => unreachable,
1682016821 };
16821 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples
16822 try sema.ensureStructDefaultsResolved(unrestricted_ty, src); // can't do this sooner, since it's not allowed on tuples
1682216823 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1682316824
1682416825 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
1685916860 const alignment_ty = try pt.optionalType(.usize_type);
1686016861 const alignment_val: Value = val: {
1686116862 const a: Alignment = switch (struct_type.layout) {
16862 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),
16863 .auto, .@"extern" => unrestricted_ty.explicitFieldAlignment(field_index, zcu),
1686316864 .@"packed" => .none,
1686416865 };
1686516866 const bytes = a.toByteUnits() orelse {
......@@ -16916,11 +16917,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1691616917 } });
1691716918 };
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
1692116922 const backing_integer_val = try pt.intern(.{ .opt = .{
1692216923 .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: {
1692416925 assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu));
1692516926 break :val struct_obj.packed_backing_int_type;
1692616927 } else .none,
......@@ -16928,7 +16929,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1692816929
1692916930 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
1693316934 const field_values = [_]InternPool.Index{
1693416935 // layout: ContainerLayout,
......@@ -16940,7 +16941,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1694016941 // decls: []const Declaration,
1694116942 decls_val,
1694216943 // is_tuple: bool,
16943 Value.makeBool(ty.isTuple(zcu)).toIntern(),
16944 Value.makeBool(unrestricted_ty.isTuple(zcu)).toIntern(),
1694416945 };
1694516946 return Air.internedToRef((try pt.internUnion(.{
1694616947 .ty = type_info_ty.toIntern(),
......@@ -16951,7 +16952,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1695116952 .@"opaque" => {
1695216953 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
1695616957 const field_values = .{
1695716958 // decls: []const Declaration,
......@@ -19212,7 +19213,7 @@ fn arrayInitAnon(
1921219213 } });
1921319214 const elem = sema.resolveInst(operand);
1921419215 types[i] = sema.typeOf(elem).toIntern();
19215 if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {
19216 if (ip.isOpaqueType(types[i])) {
1921619217 const msg = msg: {
1921719218 const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
1921819219 errdefer msg.destroy(gpa);
......@@ -19599,22 +19600,24 @@ fn zirUnaryMath(
1959919600}
1960019601
1960119602fn 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
1960219607 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1960319608 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1960419609 const src = block.nodeOffset(inst_data.src_node);
1960519610 const operand = sema.resolveInst(inst_data.operand);
1960619611 const operand_ty = sema.typeOf(operand);
19607 const pt = sema.pt;
19608 const zcu = pt.zcu;
19609 const ip = &zcu.intern_pool;
19610 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
19612 const unrestricted_operand_ty = operand_ty.unrestrictedType(zcu) orelse operand_ty;
19613 const enum_ty = switch (unrestricted_operand_ty.zigTypeTag(zcu)) {
1961119614 .enum_literal => {
1961219615 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;
1961319616 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
1961419617 return sema.addNullTerminatedStrLit(tag_name);
1961519618 },
19616 .@"enum" => operand_ty,
19617 .@"union" => operand_ty.unionTagType(zcu) orelse
19619 .@"enum" => unrestricted_operand_ty,
19620 .@"union" => unrestricted_operand_ty.unionTagType(zcu) orelse
1961819621 return sema.fail(block, src, "union '{f}' is untagged", .{operand_ty.fmt(pt)}),
1961919622 else => return sema.fail(block, operand_src, "expected enum or union; found '{f}'", .{
1962019623 operand_ty.fmt(pt),
......@@ -19881,62 +19884,6 @@ fn zirReifyPointer(
1988119884 }));
1988219885}
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
1994019887fn zirReifyFn(
1994119888 sema: *Sema,
1994219889 block: *Block,
......@@ -20035,6 +19982,58 @@ fn zirReifyFn(
2003519982 }));
2003619983}
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
2003820037fn zirReifyStruct(
2003920038 sema: *Sema,
2004020039 block: *Block,
......@@ -25149,7 +25148,7 @@ pub fn validateVarType(
2514925148 return sema.failWithOwnedErrorMsg(block, msg);
2515025149 }
2515125150 } else {
25152 if (var_ty.zigTypeTag(zcu) == .@"opaque") {
25151 if (zcu.intern_pool.isOpaqueType(var_ty.toIntern())) {
2515325152 return sema.fail(
2515425153 block,
2515525154 src,
......@@ -25166,8 +25165,11 @@ pub fn validateVarType(
2516625165 errdefer msg.destroy(sema.gpa);
2516725166
2516825167 try sema.explainWhyTypeIsComptime(msg, src, var_ty);
25169 if (var_ty.zigTypeTag(zcu) == .comptime_int or var_ty.zigTypeTag(zcu) == .comptime_float) {
25170 try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
25168 switch (var_ty.toIntern()) {
25169 else => {},
25170 .comptime_int_type,
25171 .comptime_float_type,
25172 => try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{}),
2517125173 }
2517225174
2517325175 break :msg msg;
......@@ -25756,23 +25758,24 @@ fn fieldVal(
2575625758 const ip = &zcu.intern_pool;
2575725759 const object_src = src; // TODO better source location
2575825760 const object_ty = sema.typeOf(object);
25761 const unrestricted_object_ty = object_ty.unrestrictedType(zcu) orelse object_ty;
2575925762
2576025763 // Zig allows dereferencing a single pointer during field lookup. Note that
2576125764 // we don't actually need to generate the dereference some field lookups, like the
2576225765 // 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
2576525768 const inner_ty = if (is_pointer_to)
25766 object_ty.childType(zcu)
25769 unrestricted_object_ty.childType(zcu)
2576725770 else
25768 object_ty;
25771 unrestricted_object_ty;
2576925772
2577025773 switch (inner_ty.zigTypeTag(zcu)) {
2577125774 .array => {
2577225775 if (field_name.eqlSlice("len", ip)) {
2577325776 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());
2577425777 } 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);
2577625779 const result_ty = try pt.ptrType(.{
2577725780 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
2577825781 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
......@@ -25829,11 +25832,12 @@ fn fieldVal(
2582925832 object;
2583025833
2583125834 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)) {
2583525839 .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())) {
2583725841 .inferred_error_set_type => |func_index| {
2583825842 try sema.ensureFuncIesResolved(block, src, func_index);
2583925843 const resolved_ies = ip.funcIesResolvedUnordered(func_index);
......@@ -25841,9 +25845,9 @@ fn fieldVal(
2584125845 },
2584225846 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {
2584325847 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),
2584525849 });
25846 } else child_type,
25850 } else unrestricted_child_ty,
2584725851 .simple_type => |t| {
2584825852 assert(t == .anyerror);
2584925853 _ = try pt.getErrorValue(field_name);
......@@ -25857,42 +25861,42 @@ fn fieldVal(
2585725861 } }));
2585825862 },
2585925863 .@"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| {
2586125865 return inst;
2586225866 }
25863 try sema.ensureLayoutResolved(child_type, src, .field_used);
25864 if (child_type.unionTagType(zcu)) |enum_ty| {
25867 try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used);
25868 if (unrestricted_child_ty.unionTagType(zcu)) |enum_ty| {
2586525869 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
2586625870 const field_index: u32 = @intCast(field_index_usize);
2586725871 return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern());
2586825872 }
2586925873 }
25870 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
25874 return sema.failWithBadMemberAccess(block, child_ty, field_name_src, field_name);
2587125875 },
2587225876 .@"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| {
2587425878 return inst;
2587525879 }
25876 try sema.ensureLayoutResolved(child_type, src, .field_used);
25877 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse
25878 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
25880 try sema.ensureLayoutResolved(unrestricted_child_ty, src, .field_used);
25881 const field_index_usize = unrestricted_child_ty.enumFieldIndex(field_name, zcu) orelse
25882 return sema.failWithBadMemberAccess(block, child_ty, field_name_src, field_name);
2587925883 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);
2588125885 return Air.internedToRef(enum_val.toIntern());
2588225886 },
2588325887 .@"struct", .@"opaque" => {
25884 if (!child_type.isTuple(zcu) and child_type.toIntern() != .anyopaque_type) {
25885 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
25888 if (!unrestricted_child_ty.isTuple(zcu) and unrestricted_child_ty.toIntern() != .anyopaque_type) {
25889 if (try sema.namespaceLookupVal(block, src, unrestricted_child_ty.getNamespaceIndex(zcu), field_name)) |inst| {
2588625890 return inst;
2588725891 }
2588825892 }
25889 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
25893 return sema.failWithBadMemberAccess(block, child_ty, src, field_name);
2589025894 },
2589125895 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)});
2589325897 errdefer msg.destroy(sema.gpa);
25894 if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
25895 if (child_type.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{});
25898 if (unrestricted_child_ty.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
25899 if (unrestricted_child_ty.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{});
2589625900 break :msg msg;
2589725901 }),
2589825902 }
......@@ -27471,6 +27475,29 @@ fn coerceExtra(
2747127475
2747227476 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
2747427501 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
2747527502 if (in_memory_result == .ok) {
2747627503 if (maybe_inst_val) |val| {
......@@ -27796,22 +27823,6 @@ fn coerceExtra(
2779627823 return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src);
2779727824 },
2779827825 }
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 }
2781527826 },
2781627827 .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) {
2781727828 .float, .comptime_float => float: {
......@@ -28126,6 +28137,7 @@ fn coerceInMemory(
2812628137
2812728138const InMemoryCoercionResult = union(enum) {
2812828139 ok,
28140 restricted: Pair,
2812928141 no_match: Pair,
2813028142 int_not_coercible: Int,
2813128143 comptime_int_not_coercible: TypeValuePair,
......@@ -28160,7 +28172,6 @@ const InMemoryCoercionResult = union(enum) {
2816028172 ptr_alignment: AlignPair,
2816128173 double_ptr_to_anyopaque: Pair,
2816228174 slice_to_anyopaque: Pair,
28163 ptr_restricted: Pair,
2816428175
2816528176 const Pair = struct {
2816628177 actual: Type,
......@@ -28247,6 +28258,16 @@ const InMemoryCoercionResult = union(enum) {
2824728258 var cur = res;
2824828259 while (true) switch (cur.*) {
2824928260 .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 },
2825028271 .no_match => |types| {
2825128272 try sema.addDeclaredHereNote(msg, types.wanted);
2825228273 try sema.addDeclaredHereNote(msg, types.actual);
......@@ -28492,15 +28513,6 @@ const InMemoryCoercionResult = union(enum) {
2849228513 try sema.errNote(src, msg, "consider using '.ptr'", .{});
2849328514 break;
2849428515 },
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 },
2850428516 };
2850528517 }
2850628518};
......@@ -28538,6 +28550,7 @@ pub fn coerceInMemoryAllowed(
2853828550) CompileError!InMemoryCoercionResult {
2853928551 const pt = sema.pt;
2854028552 const zcu = pt.zcu;
28553 const ip = &zcu.intern_pool;
2854128554
2854228555 if (src_val) |val| {
2854328556 assert(val.typeOf(zcu).toIntern() == src_ty.toIntern());
......@@ -28546,6 +28559,12 @@ pub fn coerceInMemoryAllowed(
2854628559 if (dest_ty.eql(src_ty, zcu))
2854728560 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
2854928568 const dest_tag = dest_ty.zigTypeTag(zcu);
2855028569 const src_tag = src_ty.zigTypeTag(zcu);
2855128570
......@@ -29142,12 +29161,6 @@ fn coerceInMemoryAllowedPtrs(
2914229161 }
2914329162 }
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
2915129164 return .ok;
2915229165}
2915329166
......@@ -29295,7 +29308,7 @@ fn storePtr2(
2929529308 try sema.requireRuntimeBlock(block, src, runtime_src);
2929629309
2929729310 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)
2929929312 else
2930029313 ptr;
2930129314
......@@ -30185,7 +30198,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde
3018530198
3018630199 const nav_index = nav: {
3018730200 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)) {
3018930202 // A pointer to this `Nav` might actually be encoded as a pointer to a different `Nav`
3019030203 // because this is either an `extern` definition or an `extern` alias. (The latter case
3019130204 // 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
3026630279
3026730280 try sema.ensureNavResolved(block, src, nav_index, .type);
3026830281 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;
3027030283 if (!nav_ty.fnHasRuntimeBits(zcu)) return;
3027130284
3027230285 try sema.ensureNavResolved(block, src, nav_index, .fully);
......@@ -30349,8 +30362,9 @@ fn analyzeLoad(
3034930362 const pt = sema.pt;
3035030363 const zcu = pt.zcu;
3035130364 const ptr_ty = sema.typeOf(ptr);
30352 const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) {
30353 .pointer => ptr_ty.childType(zcu),
30365 const unrestricted_ptr_ty = ptr_ty.unrestrictedType(zcu) orelse ptr_ty;
30366 const elem_ty = switch (unrestricted_ptr_ty.zigTypeTag(zcu)) {
30367 .pointer => unrestricted_ptr_ty.childType(zcu),
3035430368 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),
3035530369 };
3035630370
......@@ -30379,8 +30393,8 @@ fn analyzeLoad(
3037930393 break :msg msg;
3038030394 });
3038130395
30382 const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty|
30383 try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src)
30396 const unrestricted_ptr = if (unrestricted_ptr_ty.toIntern() != ptr_ty.toIntern())
30397 try sema.unwrapRestricted(block, unrestricted_ptr_ty, ptr, ptr_src)
3038430398 else
3038530399 ptr;
3038630400
......@@ -31596,17 +31610,17 @@ fn wrapErrorUnionSet(
3159631610 }
3159731611}
3159831612
31599fn unwrapRestrictedPtr(
31613fn unwrapRestricted(
3160031614 sema: *Sema,
3160131615 block: *Block,
31602 unrestricted_ptr_ty: Type,
31616 unrestricted_ty: Type,
3160331617 ptr: Air.Inst.Ref,
3160431618 ptr_src: LazySrcLoc,
3160531619) !Air.Inst.Ref {
3160631620 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);
3160831622 break :tag .unwrap_restricted_safe;
31609 } else .unwrap_restricted, unrestricted_ptr_ty, ptr);
31623 } else .unwrap_restricted, unrestricted_ty, ptr);
3161031624}
3161131625
3161231626/// 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
3443134445 .@"panic.copyLenMismatch",
3443234446 .@"panic.memcpyAlias",
3443334447 .@"panic.noreturnReturned",
34434 .@"panic.corruptRestrictedPointer",
34448 .@"panic.corruptRestrictedValue",
3443534449 => try pt.funcType(.{
3443634450 .param_types = &.{},
3443734451 .return_type = .noreturn_type,
src/Sema/bitcast.zig+3-1
......@@ -239,13 +239,13 @@ const UnpackValueBits = struct {
239239 switch (ip.indexToKey(val.toIntern())) {
240240 .int_type,
241241 .ptr_type,
242 .restricted_ptr_type,
243242 .array_type,
244243 .vector_type,
245244 .opt_type,
246245 .anyframe_type,
247246 .error_union_type,
248247 .simple_type,
248 .restricted_type,
249249 .struct_type,
250250 .tuple_type,
251251 .union_type,
......@@ -274,6 +274,8 @@ const UnpackValueBits = struct {
274274
275275 .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
277279 .aggregate => switch (ty.zigTypeTag(zcu)) {
278280 .vector => {
279281 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
8484 switch (ip.indexToKey(ty.toIntern())) {
8585 .int_type,
8686 .ptr_type,
87 .restricted_ptr_type,
8887 .anyframe_type,
8988 .simple_type,
9089 .opaque_type,
......@@ -106,6 +105,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons
106105 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {
107106 try ensureLayoutResolvedInner(sema, .fromInterned(field_ty), orig_ty, reason);
108107 },
108 .restricted_type => |restricted_type| return ensureLayoutResolvedInner(sema, .fromInterned(restricted_type.unrestricted_type), orig_ty, reason),
109109 .struct_type, .union_type, .enum_type => {
110110 try sema.declareDependency(.{ .type_layout = ty.toIntern() });
111111 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
132132 .aggregate,
133133 .un,
134134 .bitpack,
135 .restricted_value,
135136 // memoization, not types
136137 .memoized_call,
137138 => unreachable,
src/Type.zig+167-122
......@@ -165,7 +165,6 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
165165 .error_set_type,
166166 .inferred_error_set_type,
167167 .ptr_type,
168 .restricted_ptr_type,
169168 .anyframe_type,
170169 => .runtime,
171170
......@@ -201,6 +200,10 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
201200 cur_ty = .fromInterned(child_ty_ip);
202201 continue;
203202 },
203 .restricted_type => |restricted_type| {
204 cur_ty = .fromInterned(restricted_type.unrestricted_type);
205 continue;
206 },
204207 .tuple_type => |tuple| {
205208 @branchHint(.unlikely);
206209 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 {
254257 .aggregate,
255258 .un,
256259 .bitpack,
260 .restricted_value,
257261 // memoization, not types
258262 .memoized_call,
259263 => unreachable,
......@@ -374,28 +378,13 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo {
374378}
375379
376380pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType {
377 return ty.ptrInfoOrNull(&zcu.intern_pool, .{}).?;
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())) {
381 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
385382 .ptr_type => |p| p,
386 .restricted_ptr_type => |rp| if (opts.allow_restricted)
387 ip.indexToKey(rp.unrestricted_ptr_type).ptr_type
388 else
389 null,
390 .opt_type => |child| if (opts.allow_optional) switch (ip.indexToKey(child)) {
383 .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) {
391384 .ptr_type => |p| p,
392 .restricted_ptr_type => |rp| if (opts.allow_restricted)
393 ip.indexToKey(rp.unrestricted_ptr_type).ptr_type
394 else
395 null,
396 else => null, // not a pointer type
397 } else null,
398 else => null, // not a pointer type
385 else => unreachable,
386 },
387 else => unreachable,
399388 };
400389}
401390
......@@ -504,10 +493,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
504493 try print(Type.fromInterned(info.child), writer, pt, ctx);
505494 return;
506495 },
507 .restricted_ptr_type => {
508 const name = ip.loadRestrictedType(ty.toIntern()).name;
509 try writer.print("{f}", .{name.fmt(ip)});
510 },
511496 .array_type => |array_type| {
512497 if (array_type.sentinel == .none) {
513498 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
607592
608593 .generic_poison => unreachable,
609594 },
595 .restricted_type => {
596 const name = ip.loadRestrictedType(ty.toIntern()).name;
597 try writer.print("{f}", .{name.fmt(ip)});
598 },
610599 .struct_type => {
611600 const name = ip.loadStructType(ty.toIntern()).name;
612601 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
708697 .aggregate,
709698 .un,
710699 .bitpack,
700 .restricted_value,
711701 // memoization, not types
712702 .memoized_call,
713703 => unreachable,
......@@ -767,13 +757,13 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
767757 .vector_type,
768758 => true,
769759
770 .restricted_ptr_type,
771760 .error_union_type,
772761 .error_set_type,
773762 .inferred_error_set_type,
774763 .tuple_type,
775764 .opaque_type,
776765 .anyframe_type,
766 .restricted_type,
777767 // These are function bodies, not function pointers.
778768 .func_type,
779769 => false,
......@@ -847,6 +837,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
847837 .aggregate,
848838 .un,
849839 .bitpack,
840 .restricted_value,
850841 // memoization, not types
851842 .memoized_call,
852843 => unreachable,
......@@ -898,10 +889,7 @@ pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool {
898889
899890/// Like `hasRuntimeBits`, but also returns `true` for runtime functions.
900891pub fn isRuntimeFnOrHasRuntimeBits(ty: Type, zcu: *const Zcu) bool {
901 switch (ty.zigTypeTag(zcu)) {
902 .@"fn" => return ty.fnHasRuntimeBits(zcu),
903 else => return ty.hasRuntimeBits(zcu),
904 }
892 return if (zcu.intern_pool.isFunctionType(ty.toIntern())) ty.fnHasRuntimeBits(zcu) else ty.hasRuntimeBits(zcu);
905893}
906894
907895/// 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 {
914902
915903/// Never returns `none`. Asserts that all necessary type resolution is already done.
916904pub 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 };
918911 if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment;
919912 return Type.fromInterned(ptr_key.child).abiAlignment(zcu);
920913}
921914
922915pub 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 };
924921}
925922
926923/// Never returns `.none`. Asserts that the layout of `ty` is resolved.
......@@ -936,7 +933,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
936933 if (int_type.bits == 0) return .@"1";
937934 return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits));
938935 },
939 .ptr_type, .restricted_ptr_type, .anyframe_type => ptrAbiAlignment(target),
936 .ptr_type, .anyframe_type => ptrAbiAlignment(target),
940937 .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu),
941938 .vector_type => |vector_type| {
942939 if (vector_type.len == 0) return .@"1";
......@@ -1020,6 +1017,10 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
10201017
10211018 .generic_poison => unreachable,
10221019 },
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 },
10231024 .tuple_type => |tuple| {
10241025 var big_align: Alignment = .@"1";
10251026 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 {
10691070 .aggregate,
10701071 .un,
10711072 .bitpack,
1073 .restricted_value,
10721074 // memoization, not types
10731075 .memoized_call,
10741076 => unreachable,
......@@ -1090,7 +1092,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
10901092 .slice => ptrAbiSize(target) * 2,
10911093 .one, .many, .c => ptrAbiSize(target),
10921094 },
1093 .restricted_ptr_type, .anyframe_type => ptrAbiSize(target),
1095 .anyframe_type => ptrAbiSize(target),
10941096 .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu),
10951097 .vector_type => |vec| {
10961098 const elem_ty: Type = .fromInterned(vec.child);
......@@ -1169,6 +1171,10 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
11691171 .anyopaque => unreachable,
11701172 .generic_poison => unreachable,
11711173 },
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 },
11721178 .tuple_type => |tuple| switch (ty.classify(zcu)) {
11731179 // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with
11741180 // non-zero size.
......@@ -1209,6 +1215,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
12091215 .aggregate,
12101216 .un,
12111217 .bitpack,
1218 .restricted_value,
12121219 // memoization, not types
12131220 .memoized_call,
12141221 => unreachable,
......@@ -1243,7 +1250,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
12431250 .slice => target.ptrBitWidth() * 2,
12441251 else => target.ptrBitWidth(),
12451252 },
1246 .restricted_ptr_type, .anyframe_type => target.ptrBitWidth(),
1253 .anyframe_type => target.ptrBitWidth(),
12471254 .array_type => |array_type| {
12481255 const elem_ty: Type = .fromInterned(array_type.child);
12491256 const len = array_type.lenIncludingSentinel();
......@@ -1294,6 +1301,10 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
12941301 .generic_poison => unreachable,
12951302 },
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 },
12971308 .struct_type => {
12981309 const struct_obj = ip.loadStructType(ty.toIntern());
12991310 switch (struct_obj.layout) {
......@@ -1335,29 +1346,27 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
13351346 .aggregate,
13361347 .un,
13371348 .bitpack,
1349 .restricted_value,
13381350 // memoization, not types
13391351 .memoized_call,
13401352 => unreachable,
13411353 };
13421354}
13431355
1344/// Returns `null` if `ty` is not a restricted pointer.
1356/// Returns `null` if `ty` is not a restricted type.
13451357pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {
13461358 const ip = &zcu.intern_pool;
13471359 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),
13491361 else => null,
13501362 };
13511363}
13521364
13531365const RestrictedRepr = enum { indirect, direct };
13541366pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr {
1355 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1356 .restricted_ptr_type => |restricted_ptr_type| restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu),
1357 else => .direct,
1358 };
1367 return restrictedReprByTrackedInst(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_type.zir_index, zcu);
13591368}
1360pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {
1369pub fn restrictedReprByTrackedInst(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {
13611370 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {
13621371 .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct,
13631372 .ReleaseFast, .ReleaseSmall => .direct,
......@@ -1365,8 +1374,10 @@ pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *c
13651374}
13661375
13671376pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool {
1368 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;
1369 return ptr_info.flags.size == .one;
1377 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1378 .ptr_type => |ptr_info| ptr_info.flags.size == .one,
1379 else => false,
1380 };
13701381}
13711382
13721383/// Asserts `ty` is a pointer.
......@@ -1376,27 +1387,24 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size {
13761387
13771388/// Returns `null` if `ty` is not a pointer.
13781389pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size {
1379 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return null;
1380 return ptr_info.flags.size;
1390 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1391 .ptr_type => |ptr_info| ptr_info.flags.size,
1392 else => null,
1393 };
13811394}
13821395
13831396pub fn isSlice(ty: Type, zcu: *const Zcu) bool {
1384 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;
1385 return ptr_info.flags.size == .slice;
1397 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1398 .ptr_type => |ptr_type| ptr_type.flags.size == .slice,
1399 else => false,
1400 };
13861401}
13871402
13881403pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {
1389 const ip = &zcu.intern_pool;
1390 return ty: switch (ip.indexToKey(ty.toIntern())) {
1404 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
13911405 .ptr_type => |ptr_type| ptr_type.flags.size == .slice,
1392 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1393 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1394 },
1395 .opt_type => |child| opt_child: switch (zcu.intern_pool.indexToKey(child)) {
1406 .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) {
13961407 .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 },
14001408 else => false,
14011409 },
14021410 else => false,
......@@ -1408,8 +1416,10 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type {
14081416}
14091417
14101418pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {
1411 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;
1412 return ptr_info.flags.is_const;
1419 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1420 .ptr_type => |ptr_type| ptr_type.flags.is_const,
1421 else => false,
1422 };
14131423}
14141424
14151425pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {
......@@ -1417,25 +1427,25 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool {
14171427}
14181428
14191429pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool {
1420 const ptr_info = ty.ptrInfoOrNull(ip, .{ .allow_optional = false }) orelse return false;
1421 return ptr_info.flags.is_volatile;
1430 return switch (ip.indexToKey(ty.toIntern())) {
1431 .ptr_type => |ptr_type| ptr_type.flags.is_volatile,
1432 else => false,
1433 };
14221434}
14231435
14241436pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool {
1425 const ip = &zcu.intern_pool;
1426 return ty: switch (ip.indexToKey(ty.toIntern())) {
1437 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
14271438 .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 },
14311439 .opt_type => true,
14321440 else => false,
14331441 };
14341442}
14351443
14361444pub fn isCPtr(ty: Type, zcu: *const Zcu) bool {
1437 const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false;
1438 return ptr_info.flags.size == .c;
1445 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1446 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1447 else => false,
1448 };
14391449}
14401450
14411451pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
......@@ -1445,16 +1455,18 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
14451455 .slice => false,
14461456 .one, .many, .c => true,
14471457 },
1448 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1449 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1458 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1459 .indirect => true,
1460 .direct => continue :ty ip.indexToKey(restricted_type.unrestricted_type),
14501461 },
14511462 .opt_type => |child| opt_child: switch (ip.indexToKey(child)) {
14521463 .ptr_type => |p| switch (p.flags.size) {
14531464 .slice, .c => false,
14541465 .many, .one => !p.flags.is_allowzero,
14551466 },
1456 .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{
1457 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1467 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1468 .indirect => true,
1469 .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type),
14581470 },
14591471 else => false,
14601472 },
......@@ -1473,17 +1485,19 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {
14731485 const ip = &zcu.intern_pool;
14741486 return ty: switch (ip.indexToKey(ty.toIntern())) {
14751487 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1476 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1477 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1478 },
1479 .opt_type => |child_type| child_type == .anyerror_type or opt_child: switch (ip.indexToKey(child_type)) {
1488 .opt_type => |opt_child_type| opt_child_type == .anyerror_type or opt_child: switch (ip.indexToKey(opt_child_type)) {
14801489 .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 },
14841490 .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 },
14851495 else => false,
14861496 },
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 },
14871501 else => false,
14881502 };
14891503}
......@@ -1494,19 +1508,21 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
14941508 const ip = &zcu.intern_pool;
14951509 return ty: switch (ip.indexToKey(ty.toIntern())) {
14961510 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
1497 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1498 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1499 },
1500 .opt_type => |child| opt_child: switch (ip.indexToKey(child)) {
1511 .opt_type => |opt_child_type| opt_child: switch (ip.indexToKey(opt_child_type)) {
15011512 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
15021513 .slice, .c => false,
15031514 .many, .one => !ptr_type.flags.is_allowzero,
15041515 },
1505 .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{
1506 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1516 .restricted_type => |restricted_type| switch (restrictedReprByTrackedInst(restricted_type.zir_index, zcu)) {
1517 .indirect => true,
1518 .direct => continue :opt_child ip.indexToKey(restricted_type.unrestricted_type),
15071519 },
15081520 else => false,
15091521 },
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 },
15101526 else => false,
15111527 };
15121528}
......@@ -1541,7 +1557,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
15411557 .pointer => return ty.childType(zcu),
15421558 .optional => {
15431559 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;
15451561 assert(ptr_info.flags.size != .c);
15461562 assert(!ptr_info.flags.is_allowzero);
15471563 return .fromInterned(ptr_info.child);
......@@ -1563,7 +1579,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
15631579/// * `[*c]T`
15641580pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {
15651581 const ip = &zcu.intern_pool;
1566 return ty: switch (ip.indexToKey(ty.toIntern())) {
1582 return switch (ip.indexToKey(ty.toIntern())) {
15671583 inline .array_type, .vector_type => |arr| .fromInterned(arr.child),
15681584 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
15691585 .many, .slice, .c => .fromInterned(ptr_type.child),
......@@ -1572,9 +1588,6 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {
15721588 else => unreachable,
15731589 },
15741590 },
1575 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1576 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1577 },
15781591 else => unreachable,
15791592 };
15801593}
......@@ -1590,16 +1603,12 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {
15901603/// Asserts that the type is an optional, or a C pointer.
15911604/// For C pointers this returns the type unmodified.
15921605pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {
1593 const ip = &zcu.intern_pool;
1594 ty: switch (ip.indexToKey(ty.toIntern())) {
1606 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
15951607 .opt_type => |child| return .fromInterned(child),
15961608 .ptr_type => |ptr_type| {
15971609 assert(ptr_type.flags.size == .c);
15981610 return ty;
15991611 },
1600 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1601 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1602 },
16031612 else => unreachable,
16041613 }
16051614}
......@@ -1699,6 +1708,15 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo
16991708 };
17001709}
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
17021720pub fn bitpackBackingInt(ty: Type, zcu: *const Zcu) Type {
17031721 const ip = &zcu.intern_pool;
17041722 return switch (ip.indexToKey(ty.toIntern())) {
......@@ -1728,7 +1746,7 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
17281746 const ip = &zcu.intern_pool;
17291747 return switch (ty.toIntern()) {
17301748 .anyerror_type, .adhoc_inferred_error_set_type => false,
1731 else => switch (ip.indexToKey(ty.toIntern())) {
1749 else => |index| switch (ip.indexToKey(index)) {
17321750 .error_set_type => |error_set_type| error_set_type.names.len == 0,
17331751 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
17341752 .none, .anyerror_type => false,
......@@ -1752,7 +1770,7 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
17521770 return switch (ty.toIntern()) {
17531771 .anyerror_type => true,
17541772 .adhoc_inferred_error_set_type => false,
1755 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1773 else => |index| switch (zcu.intern_pool.indexToKey(index)) {
17561774 .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type,
17571775 else => false,
17581776 },
......@@ -1760,9 +1778,13 @@ pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
17601778}
17611779
17621780pub fn isError(ty: Type, zcu: *const Zcu) bool {
1763 return switch (ty.zigTypeTag(zcu)) {
1764 .error_union, .error_set => true,
1781 return switch (ty.toIntern()) {
1782 .anyerror_type, .adhoc_inferred_error_set_type, .anyerror_void_error_union_type => true,
17651783 else => false,
1784 _ => |index| switch (zcu.intern_pool.indexToKey(index)) {
1785 .error_union_type, .error_set_type => true,
1786 else => false,
1787 },
17661788 };
17671789}
17681790
......@@ -1782,7 +1804,7 @@ pub fn errorSetHasField(
17821804 const ip = &zcu.intern_pool;
17831805 return switch (ty.toIntern()) {
17841806 .anyerror_type => true,
1785 else => switch (ip.indexToKey(ty.toIntern())) {
1807 else => |index| switch (ip.indexToKey(index)) {
17861808 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
17871809 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
17881810 .anyerror_type => true,
......@@ -1817,8 +1839,7 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {
18171839
18181840/// Asserts the type is an array, pointer or vector.
18191841pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
1820 const ip = &zcu.intern_pool;
1821 return ty: switch (ip.indexToKey(ty.toIntern())) {
1842 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
18221843 .vector_type,
18231844 .struct_type,
18241845 .tuple_type,
......@@ -1826,9 +1847,6 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
18261847
18271848 .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,
18281849 .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
18331851 else => unreachable,
18341852 };
......@@ -1867,10 +1885,27 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {
18671885/// Returns true for integers, enums, error sets, and packed structs/unions.
18681886/// If this function returns true, then intInfo() can be called on the type.
18691887pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {
1870 return switch (ty.zigTypeTag(zcu)) {
1871 .int, .@"enum", .error_set => true,
1872 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",
1873 else => false,
1888 const ip = &zcu.intern_pool;
1889 return switch (ty.toIntern()) {
1890 .usize_type,
1891 .isize_type,
1892 .c_char_type,
1893 .c_short_type,
1894 .c_ushort_type,
1895 .c_int_type,
1896 .c_uint_type,
1897 .c_long_type,
1898 .c_ulong_type,
1899 .c_longlong_type,
1900 .c_ulonglong_type,
1901 .anyerror_type,
1902 => true,
1903 else => switch (ip.indexToKey(ty.toIntern())) {
1904 .int_type, .enum_type, .error_set_type => true,
1905 .struct_type => ip.loadStructType(ty.toIntern()).layout == .@"packed",
1906 .union_type => ip.loadUnionType(ty.toIntern()).layout == .@"packed",
1907 else => false,
1908 },
18741909 };
18751910}
18761911
......@@ -1914,10 +1949,10 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
19141949 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };
19151950 },
19161951
1952 .restricted_type => unreachable,
19171953 .tuple_type => unreachable,
19181954
19191955 .ptr_type => unreachable,
1920 .restricted_ptr_type => unreachable,
19211956 .anyframe_type => unreachable,
19221957 .array_type => unreachable,
19231958
......@@ -1945,6 +1980,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
19451980 .aggregate,
19461981 .un,
19471982 .bitpack,
1983 .restricted_value,
19481984 // memoization, not types
19491985 .memoized_call,
19501986 => unreachable,
......@@ -2070,7 +2106,6 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {
20702106 .c_longlong_type,
20712107 .c_ulonglong_type,
20722108 => true,
2073
20742109 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
20752110 .int_type => true,
20762111 else => false,
......@@ -2088,7 +2123,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
20882123 assertHasLayout(ty, zcu);
20892124 return switch (ip.indexToKey(ty.toIntern())) {
20902125 .ptr_type,
2091 .restricted_ptr_type, // number of possible values is not known until the end of compilation, so never treated as NPV/OPV
20922126 .error_union_type,
20932127 .func_type,
20942128 .anyframe_type,
......@@ -2152,6 +2186,13 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
21522186 .no_possible_value => try pt.nullValue(ty),
21532187 else => null,
21542188 },
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,
21552196 .tuple_type => |tuple| {
21562197 // Check *whether* the OPV exists first, because constructing it is a little more expensive.
21572198 if (ty.classify(zcu) != .one_possible_value) return null;
......@@ -2240,6 +2281,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
22402281 .aggregate,
22412282 .un,
22422283 .bitpack,
2284 .restricted_value,
22432285 // memoization, not types
22442286 .memoized_call,
22452287 => unreachable,
......@@ -2249,7 +2291,8 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
22492291/// Asserts that `ty` has its layout resolved. `generic_poison` will return `false`.
22502292pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
22512293 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;
22532296 return switch (ty.classify(zcu)) {
22542297 .no_possible_value, .one_possible_value, .runtime => false,
22552298 .partially_comptime, .fully_comptime => true,
......@@ -2257,7 +2300,7 @@ pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
22572300}
22582301
22592302pub fn isVector(ty: Type, zcu: *const Zcu) bool {
2260 return ty.zigTypeTag(zcu) == .vector;
2303 return zcu.intern_pool.isVectorType(ty.toIntern());
22612304}
22622305
22632306/// 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 {
26732716 const ip = &zcu.intern_pool;
26742717 return .{
26752718 .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,
26772720 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
26782721 .declared => |d| d.zir_index,
26792722 .reified => |r| r.zir_index,
......@@ -2898,7 +2941,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
28982941pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type {
28992942 const zcu = pt.zcu;
29002943 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;
29022945 const elem_ty: Type = switch (ptr_info.flags.size) {
29032946 .slice, .many, .c => .fromInterned(ptr_info.child),
29042947 .one => switch (ip.indexToKey(ptr_info.child)) {
......@@ -2952,7 +2995,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error
29522995pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type {
29532996 const zcu = pt.zcu;
29542997 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;
29562999 assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c);
29573000 const aggregate_ty: Type = .fromInterned(ptr_info.child);
29583001 aggregate_ty.assertHasLayout(zcu);
......@@ -3080,7 +3123,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator
30803123 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {
30813124 .tuple_type, .union_type => field_ty.abiAlignment(zcu),
30823125 .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu),
3083 .ptr_type, .restricted_ptr_type => ptrAbiAlignment(zcu.getTarget()),
3126 .ptr_type => ptrAbiAlignment(zcu.getTarget()),
30843127 else => unreachable,
30853128 },
30863129 else => |a| a,
......@@ -3109,7 +3152,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator
31093152
31103153pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
31113154 return switch (ip.indexToKey(ty.toIntern())) {
3112 .restricted_ptr_type => ip.loadRestrictedType(ty.toIntern()).name,
3155 .restricted_type => ip.loadRestrictedType(ty.toIntern()).name,
31133156 .struct_type => ip.loadStructType(ty.toIntern()).name,
31143157 .union_type => ip.loadUnionType(ty.toIntern()).name,
31153158 .enum_type => ip.loadEnumType(ty.toIntern()).name,
......@@ -3317,7 +3360,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
33173360 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
33183361 .int_type,
33193362 .ptr_type,
3320 .restricted_ptr_type,
33213363 .anyframe_type,
33223364 .simple_type,
33233365 .opaque_type,
......@@ -3337,6 +3379,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
33373379 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {
33383380 assertHasLayout(.fromInterned(field_ty), zcu);
33393381 },
3382 .restricted_type => |restricted_type| assertHasLayout(.fromInterned(restricted_type.unrestricted_type), zcu),
33403383 .struct_type => {
33413384 assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout);
33423385 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));
......@@ -3351,6 +3394,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
33513394 },
33523395
33533396 // values, not types
3397 .undef,
33543398 .simple_value,
33553399 .@"extern",
33563400 .func,
......@@ -3366,7 +3410,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
33663410 .aggregate,
33673411 .un,
33683412 .bitpack,
3369 .undef,
3413 .restricted_value,
33703414 // memoization, not types
33713415 .memoized_call,
33723416 => unreachable,
......@@ -3419,13 +3463,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
34193463 .undef,
34203464 .inferred_error_set_type,
34213465 .error_set_type,
3466 .restricted_type,
34223467 .struct_type,
34233468 .union_type,
34243469 .opaque_type,
34253470 .enum_type,
34263471 .simple_type,
34273472 .int_type,
3428 .restricted_ptr_type,
34293473 => {},
34303474
34313475 // values, not types
......@@ -3444,6 +3488,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
34443488 .aggregate,
34453489 .un,
34463490 .bitpack,
3491 .restricted_value,
34473492 // memoization, not types
34483493 .memoized_call,
34493494 => unreachable,
src/Zcu.zig+8-7
......@@ -501,7 +501,7 @@ pub const BuiltinDecl = enum {
501501 @"panic.copyLenMismatch",
502502 @"panic.memcpyAlias",
503503 @"panic.noreturnReturned",
504 @"panic.corruptRestrictedPointer",
504 @"panic.corruptRestrictedValue",
505505
506506 VaList,
507507
......@@ -589,7 +589,7 @@ pub const BuiltinDecl = enum {
589589 .@"panic.copyLenMismatch",
590590 .@"panic.memcpyAlias",
591591 .@"panic.noreturnReturned",
592 .@"panic.corruptRestrictedPointer",
592 .@"panic.corruptRestrictedValue",
593593 => .func,
594594 };
595595 }
......@@ -663,7 +663,7 @@ pub const SimplePanicId = enum {
663663 copy_len_mismatch,
664664 memcpy_alias,
665665 noreturn_returned,
666 corrupt_restricted_pointer,
666 corrupt_restricted_value,
667667
668668 pub fn toBuiltin(id: SimplePanicId) BuiltinDecl {
669669 return switch (id) {
......@@ -687,7 +687,7 @@ pub const SimplePanicId = enum {
687687 .copy_len_mismatch => .@"panic.copyLenMismatch",
688688 .memcpy_alias => .@"panic.memcpyAlias",
689689 .noreturn_returned => .@"panic.noreturnReturned",
690 .corrupt_restricted_pointer => .@"panic.corruptRestrictedPointer",
690 .corrupt_restricted_value => .@"panic.corruptRestrictedValue",
691691 // zig fmt: on
692692 };
693693 }
......@@ -2748,12 +2748,13 @@ pub const LazySrcLoc = struct {
27482748 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
27492749 .extended => switch (inst.data.extended.opcode) {
27502750 .struct_decl => zir.getStructDecl(zir_inst).src_node,
2751 .union_decl => zir.getUnionDecl(zir_inst).src_node,
27522751 .enum_decl => zir.getEnumDecl(zir_inst).src_node,
2752 .union_decl => zir.getUnionDecl(zir_inst).src_node,
27532753 .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,
27552755 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
27562756 .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,
27572758 else => unreachable,
27582759 },
27592760 else => unreachable,
......@@ -4000,7 +4001,7 @@ pub const Feature = enum {
40004001
40014002pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {
40024003 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);
40044005}
40054006
40064007pub const AtomicPtrAlignmentError = error{
src/codegen.zig+89-89
......@@ -232,15 +232,26 @@ const LazySymbolStructure = struct {
232232 operation: Operation,
233233
234234 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 {
238241 switch (operation) {
239 .ptr_inc => switch (slice.len) {
242 .end_ptr_inc => switch (target_opts.ptr_bit_width) {
240243 else => unreachable,
241 2 => std.mem.writeInt(u16, slice[0..2], std.mem.readInt(u16, slice[0..2], endian) + 1, endian),
242 4 => std.mem.writeInt(u32, slice[0..4], std.mem.readInt(u32, slice[0..4], endian) + 1, endian),
243 8 => std.mem.writeInt(u64, slice[0..8], std.mem.readInt(u64, slice[0..8], endian) + 1, endian),
244 inline 16, 32, 64 => |ptr_bit_width| {
245 const ptr_size = @divExact(ptr_bit_width, 8);
246 const TargetPtrInt = @Int(.unsigned, ptr_bit_width);
247 const end_slice = slice[slice.len - ptr_size ..][0..ptr_size];
248 std.mem.writeInt(
249 TargetPtrInt,
250 end_slice,
251 std.mem.readInt(TargetPtrInt, end_slice, target_opts.endian) + 1,
252 target_opts.endian,
253 );
254 },
244255 },
245256 }
246257 }
......@@ -279,14 +290,14 @@ pub fn getLazySymbolInfo(
279290 .structure => .{},
280291 .attributes => .{ .required_alignment = .@"1" },
281292 },
282 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {
293 .restricted_type => |restricted_type| switch (kind) {
283294 .structure => .{},
284295 .attributes => {
285 const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key);
286 const unrestricted_ptr_ty: Type =
287 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);
288 return .{ .required_alignment = restricted_ptr_ty.abiAlignment(zcu)
289 .maxStrict(unrestricted_ptr_ty.abiAlignment(zcu)) };
296 const restricted_ty: Type = .fromInterned(lazy_sym.key);
297 const unrestricted_ty: Type =
298 .fromInterned(restricted_type.unrestricted_type);
299 return .{ .required_alignment = restricted_ty.abiAlignment(zcu)
300 .maxStrict(unrestricted_ty.abiAlignment(zcu)) };
290301 },
291302 },
292303 },
......@@ -298,31 +309,32 @@ pub fn getLazySymbolInfo(
298309 },
299310 _ => switch (ip.indexToKey(lazy_sym.key)) {
300311 else => unreachable,
301 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {
302 else => unreachable,
303 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {
304 .structure => .{ .parent = .{ .kind = .const_data, .key = ptr.ty }, .modify = .{
305 .lazy_sym = .{ .kind = .deferred_const_data, .key = ptr.ty },
306 .operation = .ptr_inc,
307 } },
308 .attributes => {
309 const unrestricted_ptr_ty: Type =
310 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);
311 return .{
312 .required_alignment = unrestricted_ptr_ty.abiAlignment(zcu),
313 .size = unrestricted_ptr_ty.abiSize(zcu),
314 };
315 },
312 .restricted_value => |restricted_value| switch (kind) {
313 .structure => .{ .parent = .{ .kind = .const_data, .key = restricted_value.ty }, .modify = .{
314 .lazy_sym = .{ .kind = .deferred_const_data, .key = restricted_value.ty },
315 .operation = .end_ptr_inc,
316 } },
317 .attributes => {
318 const unrestricted_ty: Type = .fromInterned(
319 ip.indexToKey(restricted_value.ty).restricted_type.unrestricted_type,
320 );
321 return .{
322 .required_alignment = unrestricted_ty.abiAlignment(zcu),
323 .size = unrestricted_ty.abiSize(zcu),
324 };
316325 },
317326 },
318 .restricted_ptr_type => switch (kind) {
327 .restricted_type => switch (kind) {
319328 .structure => .{ .parent = .{ .kind = .const_data, .key = lazy_sym.key } },
320329 .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 );
322334 return .{
323335 .header = true,
324 .required_alignment = restricted_ptr_ty.abiAlignment(zcu),
325 .size = restricted_ptr_ty.abiSize(zcu),
336 .required_alignment = restricted_ty.abiAlignment(zcu),
337 .size = unrestricted_ty.abiAlignment(zcu).forward(restricted_ty.abiSize(zcu)),
326338 };
327339 },
328340 },
......@@ -367,7 +379,7 @@ pub fn generateLazySymbol(
367379 }
368380 return;
369381 },
370 .restricted_ptr_type => return,
382 .restricted_type => return,
371383 else => {},
372384 },
373385 .deferred_const_data => switch (lazy_sym.key) {
......@@ -392,25 +404,10 @@ pub fn generateLazySymbol(
392404 return;
393405 },
394406 _ => switch (ip.indexToKey(lazy_sym.key)) {
395 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {
396 .restricted_ptr_type => |restricted_ptr_type| return lowerPtr(
397 bin_file,
398 pt,
399 src_loc,
400 try ip.getCoerced(
401 comp.gpa,
402 comp.io,
403 pt.tid,
404 lazy_sym.key,
405 restricted_ptr_type.unrestricted_ptr_type,
406 ),
407 w,
408 reloc_parent,
409 0,
410 ),
411 else => {},
412 },
413 .restricted_ptr_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)),
407 .restricted_value => |restricted_value| return generateSymbol(bin_file, pt, src_loc, .fromInterned(
408 restricted_value.unrestricted_value,
409 ), w, reloc_parent),
410 .restricted_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)),
414411 else => {},
415412 },
416413 else => {},
......@@ -463,13 +460,13 @@ pub fn generateSymbol(
463460 switch (ip.indexToKey(val.toIntern())) {
464461 .int_type,
465462 .ptr_type,
466 .restricted_ptr_type,
467463 .array_type,
468464 .vector_type,
469465 .opt_type,
470466 .anyframe_type,
471467 .error_union_type,
472468 .simple_type,
469 .restricted_type,
473470 .struct_type,
474471 .tuple_type,
475472 .union_type,
......@@ -576,10 +573,7 @@ pub fn generateSymbol(
576573 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
577574 },
578575 },
579 .ptr => switch (ty.restrictedRepr(zcu)) {
580 .indirect => try lowerLazySymbolRef(bin_file, pt, .{ .kind = .deferred_const_data, .key = val.toIntern() }, w, reloc_parent, 0),
581 .direct => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
582 },
576 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
583577 .slice => |slice| {
584578 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
585579 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
......@@ -788,6 +782,10 @@ pub fn generateSymbol(
788782 }
789783 },
790784 .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 },
791789 .memoized_call => unreachable,
792790 }
793791}
......@@ -1185,55 +1183,57 @@ const LowerResult = union(enum) {
11851183 lea_lazy_sym: link.File.LazySymbol,
11861184};
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 {
11891187 const zcu = pt.zcu;
11901188 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
11971200 switch (ty.zigTypeTag(zcu)) {
11981201 .void => return .none,
11991202 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
12001203 .pointer => switch (ty.ptrSize(zcu)) {
12011204 .slice => {},
1202 .one, .many, .c => switch (ty.restrictedRepr(zcu)) {
1203 .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = val.toIntern() } },
1204 .direct => {
1205 const ptr = ip.indexToKey(val.toIntern()).ptr;
1206 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1207 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1208 .int => unreachable, // handled above
1209
1210 .nav => |nav_index| {
1211 const nav = ip.getNav(nav_index);
1212 const nav_ty: Type = .fromInterned(nav.resolved.?.type);
1213 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1214 return .{ .lea_nav = nav_index };
1215 } else {
1216 // Create the 0xaa bit pattern...
1217 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1218 // ...but align the pointer
1219 const alignment = zcu.navAlignment(nav_index);
1220 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1221 }
1222 },
1223
1224 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1225 return .{ .lea_uav = uav };
1205 .one, .many, .c => {
1206 const ptr = ip.indexToKey(val.toIntern()).ptr;
1207 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1208 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1209 .int => unreachable, // handled above
1210
1211 .nav => |nav_index| {
1212 const nav = ip.getNav(nav_index);
1213 const nav_ty: Type = .fromInterned(nav.resolved.?.type);
1214 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1215 return .{ .lea_nav = nav_index };
12261216 } else {
12271217 // Create the 0xaa bit pattern...
12281218 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
12291219 // ...but align the pointer
1230 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1220 const alignment = zcu.navAlignment(nav_index);
12311221 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1232 },
1222 }
1223 },
12331224
1234 else => {},
1235 };
1236 },
1225 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1226 return .{ .lea_uav = uav };
1227 } else {
1228 // Create the 0xaa bit pattern...
1229 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1230 // ...but align the pointer
1231 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1232 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1233 },
1234
1235 else => {},
1236 };
12371237 },
12381238 },
12391239 .int => {
src/codegen/c.zig+99-77
......@@ -767,7 +767,7 @@ pub const DeclGen = struct {
767767 // somewhere and we should let the C compiler tell us about it.
768768 const elem_ty = ptr_ty.childType(zcu);
769769 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());
771771 if (need_cast) {
772772 try w.writeAll("((");
773773 try dg.renderType(w, ptr_ty);
......@@ -919,13 +919,13 @@ pub const DeclGen = struct {
919919 // types, not values
920920 .int_type,
921921 .ptr_type,
922 .restricted_ptr_type,
923922 .array_type,
924923 .vector_type,
925924 .opt_type,
926925 .anyframe_type,
927926 .error_union_type,
928927 .simple_type,
928 .restricted_type,
929929 .struct_type,
930930 .tuple_type,
931931 .union_type,
......@@ -1078,24 +1078,11 @@ pub const DeclGen = struct {
10781078 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
10791079 try w.writeByte('}');
10801080 },
1081 .ptr => switch (ty.restrictedRepr(zcu)) {
1082 .indirect => {
1083 try dg.need_restricted.ensureUnusedCapacity(zcu.gpa, 2);
1084 dg.need_restricted.putAssumeCapacity(ty.toIntern(), {});
1085 dg.need_restricted.putAssumeCapacity(val.toIntern(), {});
1086
1087 const restricted_ty_name = ty.containerTypeName(ip).toSlice(ip);
1088 try w.print("&zig_restricted_{f}__{d}[zig_restricted_index_{f}__{d}]", .{
1089 fmtIdentUnsolo(restricted_ty_name), ty.toIntern(),
1090 fmtIdentUnsolo(restricted_ty_name), val.toIntern(),
1091 });
1092 },
1093 .direct => {
1094 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1095 try w.writeByte('(');
1096 try dg.renderPointer(w, derivation, location);
1097 try w.writeByte(')');
1098 },
1081 .ptr => {
1082 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1083 try w.writeByte('(');
1084 try dg.renderPointer(w, derivation, location);
1085 try w.writeByte(')');
10991086 },
11001087 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
11011088 .npv_payload => unreachable, // opv optional
......@@ -1319,13 +1306,28 @@ pub const DeclGen = struct {
13191306 if (loaded_union.layout == .auto) try w.writeByte('}');
13201307 }
13211308 },
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 },
13221324 }
13231325 }
13241326
13251327 fn renderUndefValue(
13261328 dg: *DeclGen,
13271329 w: *Writer,
1328 ty: Type,
1330 start_ty: Type,
13291331 location: ValueRenderLocation,
13301332 ) Error!void {
13311333 const pt = dg.pt;
......@@ -1343,7 +1345,8 @@ pub const DeclGen = struct {
13431345 .ReleaseFast, .ReleaseSmall => false,
13441346 };
13451347
1346 switch (ty.toIntern()) {
1348 var ty = start_ty;
1349 ty: switch (start_ty.toIntern()) {
13471350 .c_longdouble_type,
13481351 .f16_type,
13491352 .f32_type,
......@@ -1371,7 +1374,7 @@ pub const DeclGen = struct {
13711374 return w.writeByte(')');
13721375 },
13731376 .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())) {
13751378 .simple_type, // anyerror, c_char (etc), usize, isize
13761379 .int_type,
13771380 .enum_type,
......@@ -1442,9 +1445,6 @@ pub const DeclGen = struct {
14421445 try w.writeByte('}');
14431446 },
14441447 },
1445 .restricted_ptr_type => |restricted_ptr_type| continue :ty .{
1446 .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
1447 },
14481448 .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) {
14491449 .npv_payload => unreachable, // opv optional
14501450
......@@ -1475,6 +1475,16 @@ pub const DeclGen = struct {
14751475 try w.writeAll(" }");
14761476 },
14771477 },
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 },
14781488 .struct_type => {
14791489 const loaded_struct = ip.loadStructType(ty.toIntern());
14801490 switch (loaded_struct.layout) {
......@@ -1628,6 +1638,7 @@ pub const DeclGen = struct {
16281638 .aggregate,
16291639 .un,
16301640 .bitpack,
1641 .restricted_value,
16311642 .memoized_call,
16321643 => unreachable, // values, not types
16331644 },
......@@ -2106,9 +2117,9 @@ pub fn genRestricted(
21062117 const zcu = pt.zcu;
21072118 const ip = &zcu.intern_pool;
21082119 for (need_restricted.keys(), need_restricted.values()) |restricted_ty, *restricted_vals| {
2109 const unrestricted_ptr_type = ip.indexToKey(restricted_ty).restricted_ptr_type.unrestricted_ptr_type;
2110 const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_ptr_type), &dg.ctype_deps, dg.arena, zcu);
2111 const restricted_ty_name = Type.fromInterned(restricted_ty).containerTypeName(ip).toSlice(ip);
2120 const unrestricted_type = ip.indexToKey(restricted_ty).restricted_type.unrestricted_type;
2121 const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_type), &dg.ctype_deps, dg.arena, zcu);
2122 const restricted_ty_name = ip.loadRestrictedType(restricted_ty).name.toSlice(ip);
21122123 try w.print(
21132124 \\#define zig_restricted_len_{f}__{d} {d}u
21142125 \\static {f}const zig_restricted_{f}__{d}[zig_restricted_len_{f}__{d}]{f} = {{
......@@ -2138,7 +2149,7 @@ pub fn genRestricted(
21382149 restricted_val,
21392150 });
21402151 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,
21422153 ), .static_initializer);
21432154 try w.writeAll(",\n");
21442155 }
......@@ -3194,21 +3205,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
31943205 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
31953206 try f.allocs.put(zcu.gpa, local.new_local, true);
31963207
3197 switch (elem_ty.zigTypeTag(zcu)) {
3198 .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) {
3199 .@"packed" => {
3200 // For packed aggregates, we zero-initialize to try and work around a design flaw
3201 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3202 // for details.
3203 const w = &f.code.writer;
3204 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3205 try f.renderType(w, elem_ty);
3206 try w.writeAll("));");
3207 try f.newline();
3208 },
3209 .auto, .@"extern" => {},
3210 },
3211 else => {},
3208 if (elem_ty.isBitpack(zcu)) {
3209 // For packed aggregates, we zero-initialize to try and work around a design flaw
3210 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3211 // for details.
3212 const w = &f.code.writer;
3213 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3214 try f.renderType(w, elem_ty);
3215 try w.writeAll("));");
3216 try f.newline();
32123217 }
32133218
32143219 return .{ .local_ref = local.new_local };
......@@ -3228,21 +3233,15 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
32283233 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
32293234 try f.allocs.put(zcu.gpa, local.new_local, true);
32303235
3231 switch (elem_ty.zigTypeTag(zcu)) {
3232 .@"struct", .@"union" => switch (elem_ty.containerLayout(zcu)) {
3233 .@"packed" => {
3234 // For packed aggregates, we zero-initialize to try and work around a design flaw
3235 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3236 // for details.
3237 const w = &f.code.writer;
3238 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3239 try f.renderType(w, elem_ty);
3240 try w.writeAll("));");
3241 try f.newline();
3242 },
3243 .auto, .@"extern" => {},
3244 },
3245 else => {},
3236 if (elem_ty.isBitpack(zcu)) {
3237 // For packed aggregates, we zero-initialize to try and work around a design flaw
3238 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3239 // for details.
3240 const w = &f.code.writer;
3241 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3242 try f.renderType(w, elem_ty);
3243 try w.writeAll("));");
3244 try f.newline();
32463245 }
32473246
32483247 return .{ .local_ref = local.new_local };
......@@ -5639,6 +5638,7 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
56395638 try reap(f, inst, &.{ty_op.operand});
56405639
56415640 const w = &f.code.writer;
5641 // Implicitly adds the restricted decl dependency on the unrestricted type
56425642 const local = try f.allocLocal(inst, unrestricted_ty);
56435643
56445644 switch (restricted_ty.restrictedRepr(zcu)) {
......@@ -5647,8 +5647,13 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
56475647 const target = &f.dg.mod.resolved_target.result;
56485648 const ptr_bits = target.ptrBitWidth();
56495649
5650 const int_from_ptr = try f.allocLocal(inst, .usize);
5651 try f.writeCValue(w, int_from_ptr, .other);
5650 try f.dg.need_restricted.put(zcu.gpa, restricted_ty.toIntern(), {});
5651 const unrestricted_size = unrestricted_ty.abiSize(zcu);
5652 assert(unrestricted_size > 0);
5653 const restricted_ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip);
5654
5655 const ptr_diff = try f.allocLocal(inst, .usize);
5656 try f.writeCValue(w, ptr_diff, .other);
56525657 try w.print(" = zig_subw_u{d}(({f})", .{
56535658 ptr_bits,
56545659 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
......@@ -5656,29 +5661,46 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
56565661 try f.writeCValue(w, operand, .other);
56575662 try w.print(", ({f})zig_restricted_{f}__{d}, {f});", .{
56585663 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
5659 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),
5664 fmtIdentUnsolo(restricted_ty_name),
56605665 restricted_ty.toIntern(),
56615666 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
56625667 });
56635668 try f.newline();
56645669
5665 const rotate_amount = std.math.log2_int(u16, @divExact(ptr_bits, 8));
5666 try w.print("if ((zig_shr_u{d}(", .{ptr_bits});
5667 try f.writeCValue(w, int_from_ptr, .other);
5668 try w.print(", {f}) | zig_shlw_u{d}(", .{
5669 fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower),
5670 ptr_bits,
5671 });
5672 try f.writeCValue(w, int_from_ptr, .other);
5673 try w.print(", {f}, {f})) >= zig_restricted_len_{f}__{d}) {{", .{
5674 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower),
5675 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
5676 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),
5670 try w.writeAll("if (");
5671 if (unrestricted_size == 1) {
5672 try f.writeCValue(w, ptr_diff, .other);
5673 } else if (std.math.isPowerOfTwo(unrestricted_size)) {
5674 const rotate_amount = std.math.log2_int(u64, unrestricted_size);
5675 try w.print("(zig_shr_u{d}(", .{ptr_bits});
5676 try f.writeCValue(w, ptr_diff, .other);
5677 try w.print(", {f}) | zig_shlw_u{d}(", .{
5678 fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower),
5679 ptr_bits,
5680 });
5681 try f.writeCValue(w, ptr_diff, .other);
5682 try w.print(", {f}, {f}))", .{
5683 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower),
5684 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
5685 });
5686 } else {
5687 try f.writeCValue(w, ptr_diff, .other);
5688 try w.print(" % {f} != {f} || ", .{
5689 fmtUnsignedIntLiteralSmall(target, .uintptr_t, unrestricted_size, false, 10, .lower),
5690 fmtUnsignedIntLiteralSmall(target, .uintptr_t, 0, false, 10, .lower),
5691 });
5692 try f.writeCValue(w, ptr_diff, .other);
5693 try w.print(" / {f}", .{
5694 fmtUnsignedIntLiteralSmall(target, .uintptr_t, unrestricted_size, false, 10, .lower),
5695 });
5696 }
5697 try w.print(" >= zig_restricted_len_{f}__{d}) {{", .{
5698 fmtIdentUnsolo(restricted_ty_name),
56775699 restricted_ty.toIntern(),
56785700 });
56795701 f.indent();
56805702 try f.newline();
5681 try f.writePanic(.corrupt_restricted_pointer, w);
5703 try f.writePanic(.corrupt_restricted_value, w);
56825704 try f.outdent();
56835705 try w.writeByte('}');
56845706 try f.newline();
......@@ -6484,7 +6506,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
64846506 try f.writeCValue(w, local, .other);
64856507 try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {});
64866508 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)),
64886510 @intFromEnum(enum_ty.toIntern()),
64896511 });
64906512 try f.writeCValue(w, operand, .other);
src/codegen/c/type.zig+30-25
......@@ -239,7 +239,20 @@ pub const CType = union(enum) {
239239 ) Allocator.Error!CType {
240240 const gpa = zcu.comp.gpa;
241241 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;
243256 while (true) {
244257 switch (cur_ty.zigTypeTag(zcu)) {
245258 .type,
......@@ -284,20 +297,6 @@ pub const CType = union(enum) {
284297
285298 .pointer => {
286299 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 };
301300 switch (ptr.flags.size) {
302301 .slice => {
303302 try deps.addType(gpa, cur_ty, allow_incomplete);
......@@ -305,7 +304,7 @@ pub const CType = union(enum) {
305304 },
306305 .one, .many, .c => {
307306 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());
309308 const elem_cty: CType = elem_cty: {
310309 if (ptr.packed_offset.host_size > 0 and ptr.flags.vector_index == .none) {
311310 switch (classifyBitInt(.unsigned, ptr.packed_offset.host_size * 8, zcu)) {
......@@ -876,6 +875,10 @@ pub const CType = union(enum) {
876875 const ty = ctx.ty;
877876 const zcu = ctx.zcu;
878877 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 }
879882 switch (ty.zigTypeTag(zcu)) {
880883 .frame => unreachable,
881884 .@"anyframe" => unreachable,
......@@ -926,10 +929,7 @@ pub const CType = union(enum) {
926929 .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}),
927930 .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}),
928931
929 .pointer => if (ty.unrestrictedType(zcu)) |_| {
930 const name = ty.containerTypeName(ip).toSlice(ip);
931 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
932 } else switch (ty.ptrSize(zcu)) {
932 .pointer => switch (ty.ptrSize(zcu)) {
933933 .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
934934 .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
935935 },
......@@ -971,6 +971,10 @@ pub const CType = union(enum) {
971971 fmtZigType(ty.childType(zcu), zcu),
972972 }),
973973
974 .@"enum" => {
975 const name = ip.loadEnumType(ty.toIntern()).name.toSlice(ip);
976 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
977 },
974978 .@"struct" => if (ty.isTuple(zcu)) {
975979 const len = ty.structFieldCount(zcu);
976980 try w.print("tuple_{d}", .{len});
......@@ -979,17 +983,17 @@ pub const CType = union(enum) {
979983 try w.print("_{f}", .{fmtZigType(field_ty, zcu)});
980984 }
981985 } else {
982 const name = ty.containerTypeName(ip).toSlice(ip);
986 const name = ip.loadStructType(ty.toIntern()).name.toSlice(ip);
983987 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
984988 },
985989 .@"opaque" => if (ty.toIntern() == .anyopaque_type) {
986990 try w.writeAll("anyopaque");
987991 } else {
988 const name = ty.containerTypeName(ip).toSlice(ip);
992 const name = ip.loadOpaqueType(ty.toIntern()).name.toSlice(ip);
989993 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
990994 },
991 .@"union", .@"enum" => {
992 const name = ty.containerTypeName(ip).toSlice(ip);
995 .@"union" => {
996 const name = ip.loadUnionType(ty.toIntern()).name.toSlice(ip);
993997 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
994998 },
995999 }
......@@ -1002,7 +1006,6 @@ pub const CType = union(enum) {
10021006 return switch (ip.indexToKey(ty.toIntern())) {
10031007 .int_type,
10041008 .ptr_type,
1005 .restricted_ptr_type,
10061009 .anyframe_type,
10071010 .simple_type,
10081011 .opaque_type,
......@@ -1010,6 +1013,7 @@ pub const CType = union(enum) {
10101013 .inferred_error_set_type,
10111014 => true,
10121015
1016 .restricted_type,
10131017 .struct_type,
10141018 .union_type,
10151019 .enum_type,
......@@ -1045,6 +1049,7 @@ pub const CType = union(enum) {
10451049 .aggregate,
10461050 .un,
10471051 .bitpack,
1052 .restricted_value,
10481053 // memoization, not types
10491054 .memoized_call,
10501055 => unreachable,
src/codegen/llvm.zig+93-87
......@@ -708,16 +708,17 @@ pub const Object = struct {
708708 rd.* = undefined;
709709 }
710710 };
711 pub fn getRestrictedDecls(o: *Object, ty: Type) Allocator.Error!*RestrictedDecls {
712 const gop = try o.restricted_map.getOrPut(o.gpa, ty.toIntern());
711 pub fn getRestrictedDecls(o: *Object, restricted_ty: Type) Allocator.Error!*RestrictedDecls {
712 const gop = try o.restricted_map.getOrPut(o.gpa, restricted_ty.toIntern());
713713 if (gop.found_existing) return gop.value_ptr;
714714 errdefer _ = o.restricted_map.pop().?;
715715
716 const target = o.zcu.getTarget();
717 const ip = &o.zcu.intern_pool;
718 const ptr_align = Type.ptrAbiAlignment(target).toLlvm();
716 const zcu = o.zcu;
717 const target = zcu.getTarget();
718 const ip = &zcu.intern_pool;
719 const unrestricted_ty = restricted_ty.unrestrictedType(zcu).?;
719720
720 const ty_name = ty.containerTypeName(ip).toSlice(ip);
721 const ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip);
721722 gop.value_ptr.* = .{
722723 .len = try o.builder.addVariable(
723724 try o.builder.strtabStringFmt("{s}.len", .{ty_name}),
......@@ -733,11 +734,11 @@ pub const Object = struct {
733734 };
734735 gop.value_ptr.len.setLinkage(.private, &o.builder);
735736 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);
737738 gop.value_ptr.len.setUnnamedAddr(.unnamed_addr, &o.builder);
738739 gop.value_ptr.array.setLinkage(.private, &o.builder);
739740 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);
741742 // Setting unnamed_addr here would reduce safety, and the module emitting the safety checks may not be the same module
742743 // that defined the restricted type. In any case, llvm will add unnamed_addr itself if no safety checks end up being emitted.
743744 gop.value_ptr.array.setUnnamedAddr(.default, &o.builder);
......@@ -750,10 +751,13 @@ pub const Object = struct {
750751 try o.builder.intConst(restricted_decls.len.typeOf(&o.builder), len),
751752 &o.builder,
752753 );
753 try restricted_decls.array.setInitializer(try o.builder.arrayConst(
754 try o.builder.arrayType(len, .ptr),
755 restricted_decls.values.values(),
756 ), &o.builder);
754 try restricted_decls.array.setInitializer(switch (len) {
755 0 => try o.builder.structConst(try o.builder.structType(.normal, &.{}), &.{}),
756 else => try o.builder.arrayConst(
757 try o.builder.arrayType(len, restricted_decls.values.values()[0].typeOf(&o.builder)),
758 restricted_decls.values.values(),
759 ),
760 }, &o.builder);
757761 }
758762 }
759763
......@@ -2023,7 +2027,7 @@ pub const Object = struct {
20232027 fn lowerDebugType(
20242028 o: *Object,
20252029 pt: Zcu.PerThread,
2026 ty: Type,
2030 start_ty: Type,
20272031 ty_fwd_ref: Builder.Metadata,
20282032 ) Allocator.Error!Builder.Metadata {
20292033 assert(!o.builder.strip);
......@@ -2033,7 +2037,7 @@ pub const Object = struct {
20332037 const target = zcu.getTarget();
20342038 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
20382042 // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up.
20392043 // 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 {
20442048 // handling for variants at all, and will never print fields in them, so I opted not to use
20452049 // 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
20472069 switch (ty.zigTypeTag(zcu)) {
20482070 .void,
20492071 .noreturn,
......@@ -2071,64 +2093,52 @@ pub const Object = struct {
20712093 .pointer => {
20722094 const ptr_size = Type.ptrAbiSize(zcu.getTarget());
20732095 const ptr_align = Type.ptrAbiAlignment(zcu.getTarget());
2074 switch (ty.restrictedRepr(zcu)) {
2075 .indirect => return o.builder.debugPointerType(
2076 name,
2096 if (ty.isSlice(zcu)) {
2097 const debug_ptr_type = try o.builder.debugMemberType(
2098 try o.builder.metadataString("ptr"),
20772099 null, // file
2078 o.debug_compile_unit.unwrap().?, // scope
2100 ty_fwd_ref,
20792101 0, // line
2080 try o.getDebugType(pt, ty.unrestrictedType(zcu).?),
2102 try o.getDebugType(pt, ty.slicePtrFieldType(zcu)),
20812103 ptr_size * 8,
20822104 ptr_align.toByteUnits().? * 8,
20832105 0, // offset
2084 ),
2085 .direct => if (ty.isSlice(zcu)) {
2086 const debug_ptr_type = try o.builder.debugMemberType(
2087 try o.builder.metadataString("ptr"),
2088 null, // file
2089 ty_fwd_ref,
2090 0, // line
2091 try o.getDebugType(pt, ty.slicePtrFieldType(zcu)),
2092 ptr_size * 8,
2093 ptr_align.toByteUnits().? * 8,
2094 0, // offset
2095 );
2106 );
20962107
2097 const debug_len_type = try o.builder.debugMemberType(
2098 try o.builder.metadataString("len"),
2099 null, // file
2100 ty_fwd_ref,
2101 0, // line
2102 try o.getDebugType(pt, .usize),
2103 ptr_size * 8,
2104 ptr_align.toByteUnits().? * 8,
2105 ptr_size * 8,
2106 );
2108 const debug_len_type = try o.builder.debugMemberType(
2109 try o.builder.metadataString("len"),
2110 null, // file
2111 ty_fwd_ref,
2112 0, // line
2113 try o.getDebugType(pt, .usize),
2114 ptr_size * 8,
2115 ptr_align.toByteUnits().? * 8,
2116 ptr_size * 8,
2117 );
21072118
2108 return o.builder.debugStructType(
2109 name,
2110 null, // file
2111 o.debug_compile_unit.unwrap().?, // scope
2112 0, // line
2113 null, // underlying type
2114 ptr_size * 2 * 8,
2115 ptr_align.toByteUnits().? * 8,
2116 try o.builder.metadataTuple(&.{
2117 debug_ptr_type,
2118 debug_len_type,
2119 }),
2120 );
2121 } else return o.builder.debugPointerType(
2119 return o.builder.debugStructType(
21222120 name,
21232121 null, // file
21242122 o.debug_compile_unit.unwrap().?, // scope
21252123 0, // line
2126 try o.getDebugType(pt, ty.childType(zcu)),
2127 ptr_size * 8,
2124 null, // underlying type
2125 ptr_size * 2 * 8,
21282126 ptr_align.toByteUnits().? * 8,
2129 0, // offset
2130 ),
2131 }
2127 try o.builder.metadataTuple(&.{
2128 debug_ptr_type,
2129 debug_len_type,
2130 }),
2131 );
2132 } else return o.builder.debugPointerType(
2133 name,
2134 null, // file
2135 o.debug_compile_unit.unwrap().?, // scope
2136 0, // line
2137 try o.getDebugType(pt, ty.childType(zcu)),
2138 ptr_size * 8,
2139 ptr_align.toByteUnits().? * 8,
2140 0, // offset
2141 );
21322142 },
21332143 .array => return o.builder.debugArrayType(
21342144 name,
......@@ -3121,7 +3131,7 @@ pub const Object = struct {
31213131 .empty_tuple,
31223132 .none,
31233133 => unreachable,
3124 else => t: switch (ip.indexToKey(t.toIntern())) {
3134 else => switch (ip.indexToKey(t.toIntern())) {
31253135 .int_type => |int_type| try o.builder.intType(int_type.bits),
31263136 .ptr_type => |ptr_type| type: {
31273137 const ptr_ty = try o.builder.ptrType(
......@@ -3135,10 +3145,6 @@ pub const Object = struct {
31353145 }),
31363146 };
31373147 },
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 },
31423148 .array_type => |array_type| o.builder.arrayType(
31433149 array_type.lenIncludingSentinel(),
31443150 try o.lowerType(.fromInterned(array_type.child)),
......@@ -3217,6 +3223,10 @@ pub const Object = struct {
32173223 return o.builder.structType(.normal, fields[0..fields_len]);
32183224 },
32193225 .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 },
32203230 .struct_type => {
32213231 if (o.type_map.get(t.toIntern())) |value| return value;
32223232
......@@ -3430,6 +3440,7 @@ pub const Object = struct {
34303440 .aggregate,
34313441 .un,
34323442 .bitpack,
3443 .restricted_value,
34333444 // memoization, not types
34343445 .memoized_call,
34353446 => unreachable,
......@@ -3521,13 +3532,13 @@ pub const Object = struct {
35213532 return switch (val_key) {
35223533 .int_type,
35233534 .ptr_type,
3524 .restricted_ptr_type,
35253535 .array_type,
35263536 .vector_type,
35273537 .opt_type,
35283538 .anyframe_type,
35293539 .error_union_type,
35303540 .simple_type,
3541 .restricted_type,
35313542 .struct_type,
35323543 .tuple_type,
35333544 .union_type,
......@@ -3622,27 +3633,7 @@ pub const Object = struct {
36223633 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)),
36233634 else => unreachable,
36243635 },
3625 .ptr => switch (ty.restrictedRepr(zcu)) {
3626 .indirect => {
3627 const restricted_decls = try o.getRestrictedDecls(ty);
3628 const gop = try restricted_decls.values.getOrPut(o.gpa, arg_val);
3629 if (!gop.found_existing) gop.value_ptr.* = try o.lowerValue(try ip.getCoerced(
3630 zcu.gpa,
3631 zcu.comp.io,
3632 .main, // FIXME
3633 arg_val,
3634 ty.unrestrictedType(zcu).?.toIntern(),
3635 ));
3636 return o.builder.gepConst(
3637 .inbounds,
3638 .ptr,
3639 restricted_decls.array.toConst(&o.builder),
3640 null,
3641 &.{try o.builder.intConst(.i64, gop.index)},
3642 );
3643 },
3644 .direct => try o.lowerPtr(arg_val, 0),
3645 },
3636 .ptr => try o.lowerPtr(arg_val, 0),
36463637 .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{
36473638 try o.lowerValue(slice.ptr),
36483639 try o.lowerValue(slice.len),
......@@ -4006,6 +3997,21 @@ pub const Object = struct {
40063997 else
40073998 union_ty, vals[0..len]);
40083999 },
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 },
40094015 .memoized_call => unreachable,
40104016 };
40114017 }
src/codegen/llvm/FuncGen.zig+41-20
......@@ -3266,6 +3266,8 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
32663266 if (safety) {
32673267 const restricted_decls = try o.getRestrictedDecls(restricted_ty);
32683268 const llvm_usize_ty = restricted_decls.len.typeOf(&o.builder);
3269 const unrestricted_size = unrestricted_ty.abiSize(zcu);
3270 assert(unrestricted_size > 0);
32693271 const array = try o.builder.castConst(.ptrtoint, restricted_decls.array.toConst(&o.builder), llvm_usize_ty);
32703272 const ptr_diff = try fg.wip.bin(
32713273 .sub,
......@@ -3273,11 +3275,6 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
32733275 array.toValue(),
32743276 "unwrap_restricted.ptr_diff",
32753277 );
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");
32813278 const len = try fg.wip.load(
32823279 .normal,
32833280 llvm_usize_ty,
......@@ -3285,18 +3282,38 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat
32853282 Type.ptrAbiAlignment(target).toLlvm(),
32863283 "unwrap_restricted.len",
32873284 );
3288 const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok");
3289
3290 const invalid_block = try fg.wip.block(1, "unwrap_restricted.invalid");
3285 const is_po2_unrestricted_size = std.math.isPowerOfTwo(unrestricted_size);
3286 const check_block = if (is_po2_unrestricted_size) undefined else try fg.wip.block(1, "unwrap_restricted.check");
3287 const invalid_block = try fg.wip.block(if (is_po2_unrestricted_size) 1 else 2, "unwrap_restricted.invalid");
32913288 const valid_block = try fg.wip.block(1, "unwrap_restricted.valid");
3292 _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none);
3293
3289 if (is_po2_unrestricted_size) {
3290 const index = if (unrestricted_size == 1)
3291 ptr_diff
3292 else
3293 try fg.wip.callIntrinsic(.normal, .none, .fshr, &.{llvm_usize_ty}, &.{
3294 ptr_diff,
3295 ptr_diff,
3296 try o.builder.intValue(llvm_usize_ty, std.math.log2_int(u64, unrestricted_size)),
3297 }, "unwrap_restricted.index");
3298 const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok");
3299 _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none);
3300 } else {
3301 const unrestricted_size_value = try o.builder.intValue(llvm_usize_ty, unrestricted_size);
3302 const misalignment = try fg.wip.bin(.urem, ptr_diff, unrestricted_size_value, "unwrap_restricted.misalignment");
3303 const misaligned = try fg.wip.icmp(.ne, misalignment, try o.builder.intValue(llvm_usize_ty, 0), "unwrap_restricted.misaligned");
3304 _ = try fg.wip.brCond(misaligned, invalid_block, check_block, .none);
3305
3306 fg.wip.cursor = .{ .block = check_block };
3307 const index = try fg.wip.bin(.@"udiv exact", ptr_diff, unrestricted_size_value, "unwrap_restricted.index");
3308 const ok = try fg.wip.icmp(.ult, index, len, "unwrap_restricted.ok");
3309 _ = try fg.wip.brCond(ok, valid_block, invalid_block, .none);
3310 }
32943311 fg.wip.cursor = .{ .block = invalid_block };
3295 try fg.buildSimplePanic(.corrupt_restricted_pointer);
3312 try fg.buildSimplePanic(.corrupt_restricted_value);
32963313
32973314 fg.wip.cursor = .{ .block = valid_block };
32983315 }
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);
33003317 },
33013318 .direct => return operand,
33023319 }
......@@ -7275,7 +7292,11 @@ pub fn buildAllocaInner(
72757292/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
72767293/// or as an LLVM value.
72777294pub 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)) {
72797300 .type,
72807301 .comptime_int,
72817302 .comptime_float,
......@@ -7300,19 +7321,19 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {
73007321
73017322 .array,
73027323 .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)) {
73107331 .@"packed" => false,
7311 .auto, .@"extern" => ty.hasRuntimeBits(zcu),
7332 .auto, .@"extern" => unrestricted_ty.hasRuntimeBits(zcu),
73127333 },
7313 .@"union" => switch (ty.containerLayout(zcu)) {
7334 .@"union" => switch (unrestricted_ty.containerLayout(zcu)) {
73147335 .@"packed" => false,
7315 else => ty.hasRuntimeBits(zcu) and !ty.unionHasAllZeroBitFieldTypes(zcu),
7336 else => unrestricted_ty.hasRuntimeBits(zcu) and !unrestricted_ty.unionHasAllZeroBitFieldTypes(zcu),
73167337 },
73177338 };
73187339}
src/codegen/spirv/CodeGen.zig+3-2
......@@ -774,13 +774,13 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
774774 switch (ip.indexToKey(val.toIntern())) {
775775 .int_type,
776776 .ptr_type,
777 .restricted_ptr_type,
778777 .array_type,
779778 .vector_type,
780779 .opt_type,
781780 .anyframe_type,
782781 .error_union_type,
783782 .simple_type,
783 .restricted_type,
784784 .struct_type,
785785 .tuple_type,
786786 .union_type,
......@@ -990,6 +990,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
990990 break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr);
991991 },
992992
993 .restricted_value => return cg.todo("implement restricted values", .{}),
993994 .memoized_call => unreachable,
994995 }
995996 };
......@@ -2777,7 +2778,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void {
27772778 .wrap_errunion_err => try cg.airWrapErrUnionErr(inst),
27782779 .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
27822783 .is_null => try cg.airIsNull(inst, false, .is_null),
27832784 .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 {
46794679 switch (ip.indexToKey(val.ip_index)) {
46804680 .int_type,
46814681 .ptr_type,
4682 .restricted_ptr_type,
46834682 .array_type,
46844683 .vector_type,
46854684 .opt_type,
46864685 .anyframe_type,
46874686 .error_union_type,
46884687 .simple_type,
4688 .restricted_type,
46894689 .struct_type,
46904690 .tuple_type,
46914691 .union_type,
......@@ -4779,6 +4779,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
47794779 },
47804780 .un => unreachable, // packed unions use `bitpack`
47814781 .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),
4782 .restricted_value => return cg.fail("Wasm TODO: LowerConstant for restricted value", .{}),
47824783 .memoized_call => unreachable,
47834784 }
47844785}
src/codegen/x86_64/CodeGen.zig+215-12
......@@ -103826,14 +103826,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103826103826 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
103827103827 const unrestricted_ty = ty_op.ty.toType();
103828103828 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)};
103830103830 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {
103831103831 .indirect => {
103832103832 if (zcu.comp.config.use_new_linker) switch (air_tag) {
103833103833 else => unreachable,
103834103834 .unwrap_restricted => {},
103835103835 .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 }, .{
103836103867 .required_features = .{ .avx, null, null, null },
103868 .src_constraints = .{ .any, .po2_any, .any },
103837103869 .patterns = &.{
103838103870 .{ .src = .{ .mem, .none, .none } },
103839103871 .{ .src = .{ .to_gpr, .none, .none } },
......@@ -103843,7 +103875,72 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103843103875 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103844103876 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103845103877 .{ .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 } },
103847103944 .unused,
103848103945 .unused,
103849103946 .unused,
......@@ -103857,13 +103954,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103857103954 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103858103955 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103859103956 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },
103860 .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ },
103957 .{ ._, ._rx, .ro, .tmp2p, .tmp2p, .sa(.src1, .add_log2_size), ._ },
103861103958 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103862103959 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103863103960 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103864103961 } },
103865103962 }, .{
103866103963 .required_features = .{ .sse, null, null, null },
103964 .src_constraints = .{ .any, .po2_any, .any },
103867103965 .patterns = &.{
103868103966 .{ .src = .{ .mem, .none, .none } },
103869103967 .{ .src = .{ .to_gpr, .none, .none } },
......@@ -103873,7 +103971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103873103971 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103874103972 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103875103973 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103876 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103974 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } },
103877103975 .unused,
103878103976 .unused,
103879103977 .unused,
......@@ -103887,12 +103985,48 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103887103985 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103888103986 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103889103987 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },
103890 .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ },
103988 .{ ._, ._r, .ro, .tmp2p, .sa(.src1, .add_log2_size), ._, ._ },
103891103989 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103892103990 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103893103991 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103894103992 } },
103895103993 }, .{
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 },
103896104030 .patterns = &.{
103897104031 .{ .src = .{ .mem, .none, .none } },
103898104032 .{ .src = .{ .to_gpr, .none, .none } },
......@@ -103902,7 +104036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103902104036 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103903104037 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103904104038 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103905 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
104039 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_value } },
103906104040 .unused,
103907104041 .unused,
103908104042 .unused,
......@@ -103916,11 +104050,74 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103916104050 .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ },
103917104051 .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ },
103918104052 .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ },
103919 .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ },
104053 .{ ._, ._rx, .ro, .tmp2p, .tmp2p, .sa(.src1, .add_log2_size), ._ },
103920104054 .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ },
103921104055 .{ ._, ._b, .j, .@"0f", ._, ._, ._ },
103922104056 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103923104057 } },
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 } },
103924104121 } }) catch |err| switch (err) {
103925104122 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103926104123 air_tag,
......@@ -103935,7 +104132,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103935104132 },
103936104133 .direct => ops[0],
103937104134 };
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);
103939104137 },
103940104138 .struct_field_ptr => {
103941104139 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
174190174388 };
174191174389
174192174390 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)) {
174194174397 .float => switch (ty.floatBits(self.target)) {
174195174398 16, 32, 64, 128 => 16,
174196174399 80 => break :need_mem,
......@@ -189139,9 +189342,9 @@ const Select = struct {
189139189342 lhs: enum(u6) {
189140189343 none,
189141189344 ptr_size,
189142 log2_ptr_size,
189143189345 ptr_bit_size,
189144189346 size,
189347 log2_size,
189145189348 src0_size,
189146189349 dst0_size,
189147189350 delta_size,
......@@ -189178,7 +189381,6 @@ const Select = struct {
189178189381 const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" };
189179189382 const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" };
189180189383 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" };
189182189384 const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" };
189183189385 const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" };
189184189386 const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" };
......@@ -189186,6 +189388,7 @@ const Select = struct {
189186189388 const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" };
189187189389 const sub_size_div_4: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"4" };
189188189390 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" };
189189189392 const sub_src0_size_div_8: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .div, .rhs = .@"8" };
189190189393 const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
189191189394 const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
......@@ -190119,8 +190322,8 @@ const Select = struct {
190119190322 const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) {
190120190323 .none => 0,
190121190324 .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8),
190122 .log2_ptr_size => std.math.log2(@divExact(s.cg.target.ptrBitWidth(), 8)),
190123190325 .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)),
190124190327 .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)),
190125190328 .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)),
190126190329 .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(
13851385 for (new.keys()) |restricted_key| {
13861386 const restricted_ty = switch (ip.indexToKey(restricted_key)) {
13871387 else => unreachable,
1388 .restricted_ptr_type => restricted_key,
1389 .ptr => |ptr| ptr.ty,
1388 .restricted_type => restricted_key,
1389 .restricted_value => |restricted_value| restricted_value.ty,
13901390 };
13911391 const gop = global.getOrPutAssumeCapacity(restricted_ty);
13921392 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 {
21732173
21742174 if (structure.modify) |modification| modification.operation.apply(
21752175 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 },
21772184 );
21782185}
21792186
src/link/ConstPool.zig+23-21
......@@ -181,8 +181,9 @@ fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Inde
181181 }
182182}
183183fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {
184 if (ty.isGenericPoison()) return true;
185 return switch (ty.zigTypeTag(zcu)) {
184 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
185 if (unrestricted_ty.isGenericPoison()) return true;
186 return switch (unrestricted_ty.zigTypeTag(zcu)) {
186187 .type,
187188 .void,
188189 .bool,
......@@ -201,33 +202,34 @@ fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {
201202 .enum_literal,
202203 => true,
203204
204 .array, .vector => pool.checkType(ty.childType(zcu), zcu),
205 .optional => pool.checkType(ty.optionalChild(zcu), zcu),
206 .error_union => pool.checkType(ty.errorUnionPayload(zcu), zcu),
205 .array, .vector => pool.checkType(unrestricted_ty.childType(zcu), zcu),
206 .optional => pool.checkType(unrestricted_ty.optionalChild(zcu), zcu),
207 .error_union => pool.checkType(unrestricted_ty.errorUnionPayload(zcu), zcu),
207208 .@"fn" => {
208209 const ip = &zcu.intern_pool;
209 const func = ip.indexToKey(ty.toIntern()).func_type;
210 const func = ip.indexToKey(unrestricted_ty.toIntern()).func_type;
210211 for (func.param_types.get(ip)) |param_ty_ip| {
211212 if (!pool.checkType(.fromInterned(param_ty_ip), zcu)) return false;
212213 }
213214 return pool.checkType(.fromInterned(func.return_type), zcu);
214215 },
215 .@"struct" => if (ty.isTuple(zcu)) {
216 for (0..ty.structFieldCount(zcu)) |field_index| {
217 if (!pool.checkType(ty.fieldType(field_index, zcu), zcu)) return false;
216 .@"struct" => if (unrestricted_ty.isTuple(zcu)) {
217 for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| {
218 if (!pool.checkType(unrestricted_ty.fieldType(field_index, zcu), zcu)) return false;
218219 }
219220 return true;
220221 } else {
221 return pool.complete_containers.contains(ty.toIntern());
222 return pool.complete_containers.contains(unrestricted_ty.toIntern());
222223 },
223224 .@"union", .@"enum" => {
224 return pool.complete_containers.contains(ty.toIntern());
225 return pool.complete_containers.contains(unrestricted_ty.toIntern());
225226 },
226227 };
227228}
228229fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Allocator.Error!void {
229 if (ty.isGenericPoison()) return;
230 switch (ty.zigTypeTag(zcu)) {
230 const unrestricted_ty = ty.unrestrictedType(zcu) orelse ty;
231 if (unrestricted_ty.isGenericPoison()) return;
232 switch (unrestricted_ty.zigTypeTag(zcu)) {
231233 .type,
232234 .void,
233235 .bool,
......@@ -246,20 +248,20 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al
246248 .enum_literal,
247249 => {},
248250
249 .array, .vector => try pool.registerTypeDeps(root, ty.childType(zcu), zcu),
250 .optional => try pool.registerTypeDeps(root, ty.optionalChild(zcu), zcu),
251 .error_union => try pool.registerTypeDeps(root, ty.errorUnionPayload(zcu), zcu),
251 .array, .vector => try pool.registerTypeDeps(root, unrestricted_ty.childType(zcu), zcu),
252 .optional => try pool.registerTypeDeps(root, unrestricted_ty.optionalChild(zcu), zcu),
253 .error_union => try pool.registerTypeDeps(root, unrestricted_ty.errorUnionPayload(zcu), zcu),
252254 .@"fn" => {
253255 const ip = &zcu.intern_pool;
254 const func = ip.indexToKey(ty.toIntern()).func_type;
256 const func = ip.indexToKey(unrestricted_ty.toIntern()).func_type;
255257 for (func.param_types.get(ip)) |param_ty_ip| {
256258 try pool.registerTypeDeps(root, .fromInterned(param_ty_ip), zcu);
257259 }
258260 try pool.registerTypeDeps(root, .fromInterned(func.return_type), zcu);
259261 },
260 .@"struct", .@"union", .@"enum" => if (ty.isTuple(zcu)) {
261 for (0..ty.structFieldCount(zcu)) |field_index| {
262 try pool.registerTypeDeps(root, ty.fieldType(field_index, zcu), zcu);
262 .@"struct", .@"union", .@"enum" => if (unrestricted_ty.isTuple(zcu)) {
263 for (0..unrestricted_ty.structFieldCount(zcu)) |field_index| {
264 try pool.registerTypeDeps(root, unrestricted_ty.fieldType(field_index, zcu), zcu);
263265 }
264266 } else {
265267 // `ty` is a container; register the dependency.
......@@ -269,7 +271,7 @@ fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Al
269271 try pool.container_dep_entries.ensureUnusedCapacity(gpa, 1);
270272 errdefer comptime unreachable;
271273
272 const gop = pool.container_deps.getOrPutAssumeCapacity(ty.toIntern());
274 const gop = pool.container_deps.getOrPutAssumeCapacity(unrestricted_ty.toIntern());
273275 const entry: ContainerDepEntry.Index = @enumFromInt(pool.container_dep_entries.items.len);
274276 pool.container_dep_entries.appendAssumeCapacity(.{
275277 .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) {
11761176 implicit_pointer: struct {
11771177 unit: Unit.Index,
11781178 entry: Entry.Index,
1179 offset: i65,
1179 offset: i65 = 0,
11801180 },
11811181 wasm_ext: union(enum) {
11821182 local: u32,
......@@ -3060,13 +3060,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
30603060 } = switch (ip.indexToKey(nav_val.toIntern())) {
30613061 .int_type,
30623062 .ptr_type,
3063 .restricted_ptr_type,
30643063 .array_type,
30653064 .vector_type,
30663065 .opt_type,
30673066 .error_union_type,
30683067 .anyframe_type,
30693068 .simple_type,
3069 .restricted_type,
30703070 .tuple_type,
30713071 .func_type,
30723072 .error_set_type,
......@@ -3128,6 +3128,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31283128 .aggregate,
31293129 .un,
31303130 .bitpack,
3131 .restricted_value,
31313132 => if (nav.resolved.?.@"const") .@"const" else .@"var",
31323133
31333134 .@"extern" => unreachable,
......@@ -3509,12 +3510,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35093510
35103511 if (value_index == .anyerror_type) return; // handled in `flush` instead
35113512
3512 const value_ip_key = ip.indexToKey(value_index);
3513 switch (value_ip_key) {
3513 const value_ip_key: InternPool.Key = switch (ip.indexToKey(value_index)) {
35143514 .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`)
35153515 .@"extern" => return, // populated by the Nav instead (`initWipNav`)
3516 else => {},
3517 }
3516 .restricted_value => |restricted_value| switch (Type.restrictedRepr(.fromInterned(restricted_value.ty), zcu)) {
3517 .indirect => .{ .restricted_value = restricted_value },
3518 .direct => ip.indexToKey(restricted_value.unrestricted_value),
3519 },
3520 else => |key| key,
3521 };
35183522
35193523 switch (value_index) {
35203524 .generic_poison_type => log.debug("updateValue(anytype)", .{}),
......@@ -3567,7 +3571,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35673571
35683572 const diw = &wip_nav.debug_info.writer;
35693573 var big_int_space: Value.BigIntSpace = undefined;
3570 key: switch (value_ip_key) {
3574 switch (value_ip_key) {
35713575 .func => unreachable, // handled above
35723576 .@"extern" => unreachable, // handled above
35733577
......@@ -3630,13 +3634,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
36303634 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
36313635 },
36323636 },
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 },
36403637 .array_type => |array_type| {
36413638 const array_child_type: Type = .fromInterned(array_type.child);
36423639 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
38473844 .anyerror => unreachable, // already did early return above
38483845 .adhoc_inferred_error_set => unreachable,
38493846 },
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 },
38503869 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
38513870 try wip_nav.abbrevCode(.generated_empty_struct_type);
38523871 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
42654284 if (error_set_type.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
42664285 },
42674286 .inferred_error_set_type => |func| {
4268 try wip_nav.abbrevCode(.inferred_error_set_type);
4287 try wip_nav.abbrevCode(.alias_type);
42694288 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
42704289 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {
42714290 .none => .anyerror_type,
......@@ -4648,6 +4667,15 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
46484667 }
46494668 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
46504669 },
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 },
46514679 .memoized_call => unreachable, // not a value
46524680 }
46534681 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
......@@ -5209,7 +5237,7 @@ const AbbrevCode = enum {
52095237 tagged_union_default_field,
52105238 void_type,
52115239 numeric_type,
5212 inferred_error_set_type,
5240 alias_type,
52135241 ptr_type,
52145242 ptr_sentinel_type,
52155243 ptr_aligned_type,
......@@ -5839,7 +5867,7 @@ const AbbrevCode = enum {
58395867 .{ .alignment, .udata },
58405868 },
58415869 },
5842 .inferred_error_set_type = .{
5870 .alias_type = .{
58435871 .tag = .typedef,
58445872 .attrs = &.{
58455873 .{ .name, .strp },
src/link/Elf2.zig+8-1
......@@ -3349,7 +3349,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
33493349
33503350 if (structure.modify) |modification| modification.operation.apply(
33513351 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 },
33533360 );
33543361}
33553362
src/print_value.zig+10-9
......@@ -49,7 +49,6 @@ pub fn print(
4949 switch (ip.indexToKey(val.toIntern())) {
5050 .int_type,
5151 .ptr_type,
52 .restricted_ptr_type,
5352 .array_type,
5453 .vector_type,
5554 .opt_type,
......@@ -64,6 +63,7 @@ pub fn print(
6463 .func_type,
6564 .error_set_type,
6665 .inferred_error_set_type,
66 .restricted_type,
6767 => try Type.print(val.toType(), writer, pt, null),
6868 .undef => try writer.writeAll("undefined"),
6969 .simple_value => |simple_value| switch (simple_value) {
......@@ -88,7 +88,7 @@ pub fn print(
8888 .err_name => |err_name| try writer.print("error.{f}", .{
8989 err_name.fmt(ip),
9090 }),
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),
9292 },
9393 .enum_literal => |enum_literal| try writer.print(".{f}", .{
9494 enum_literal.fmt(ip),
......@@ -102,7 +102,7 @@ pub fn print(
102102 return writer.writeAll("@enumFromInt(...)");
103103 }
104104 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);
106106 try writer.writeAll(")");
107107 },
108108 .float => |float| switch (float.storage) {
......@@ -130,7 +130,7 @@ pub fn print(
130130 if (level == 0) {
131131 try writer.writeAll("(...)");
132132 } 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);
134134 }
135135 try writer.writeAll("]");
136136 },
......@@ -148,7 +148,7 @@ pub fn print(
148148 },
149149 .opt => |opt| switch (opt.val) {
150150 .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),
152152 },
153153 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),
154154 .un => |un| {
......@@ -159,13 +159,13 @@ pub fn print(
159159 if (un.tag == .none) {
160160 const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt);
161161 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);
163163 try writer.writeAll("))");
164164 } else {
165165 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);
167167 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);
169169 try writer.writeAll(" }");
170170 }
171171 },
......@@ -198,6 +198,7 @@ pub fn print(
198198 else => unreachable,
199199 }
200200 },
201 .restricted_value => |restricted_value| try print(.fromInterned(restricted_value.unrestricted_value), writer, level, pt, opt_sema),
201202 .memoized_call => unreachable,
202203 }
203204}
......@@ -470,7 +471,7 @@ pub fn printPtrDerivation(
470471 if (x.level == 0) {
471472 try writer.writeAll("...");
472473 } 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);
474475 }
475476 try writer.writeByte(')');
476477 },
src/print_zir.zig+11-8
......@@ -622,14 +622,6 @@ const Writer = struct {
622622 try stream.writeAll(")) ");
623623 try self.writeSrcNode(stream, extra.node);
624624 },
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 },
633625 .reify_fn => {
634626 const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;
635627 try self.writeInstRef(stream, extra.param_types);
......@@ -642,6 +634,17 @@ const Writer = struct {
642634 try stream.writeAll(")) ");
643635 try self.writeSrcNode(stream, extra.node);
644636 },
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 },
645648 .reify_struct => {
646649 const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
647650 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
908908 };
909909}
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 {
912912 return switch (feature) {
913913 .panic_fn => switch (backend) {
914914 .stage2_aarch64,
......@@ -949,7 +949,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
949949 else => true,
950950 },
951951 .restricted_types => switch (backend) {
952 .stage2_c, .stage2_llvm, .stage2_x86_64 => true,
952 .stage2_c => true,
953 .stage2_llvm, .stage2_x86_64 => !incremental,
953954 else => false,
954955 },
955956 };