| author | |
| committer | |
| log | f250802ce794589f77367113335216c1993f7412 |
| tree | 80f260bc0447d67924caa4162344ad21bf71ea2a |
| parent | fc23fe90ce1f3d28841c5a5a93a8bdf7edaefc54 |
conservative, incomplete change8 files changed, 96 insertions(+), 0 deletions(-)
lib/std/zig/AstGen.zig+6| ... | ... | @@ -2876,6 +2876,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2876 | 2876 | .validate_array_init_ref_ty, |
| 2877 | 2877 | .array_init_elem_type, |
| 2878 | 2878 | .array_init_elem_ptr, |
| 2879 | .restrict, | |
| 2879 | 2880 | => break :b false, |
| 2880 | 2881 | |
| 2881 | 2882 | .extended => switch (gz.astgen.instructions.items(.data)[@intFromEnum(inst)].extended.opcode) { |
| ... | ... | @@ -9547,6 +9548,11 @@ fn builtinCall( |
| 9547 | 9548 | }); |
| 9548 | 9549 | return rvalue(gz, ri, result, node); |
| 9549 | 9550 | }, |
| 9551 | .Restrict => { | |
| 9552 | const operand = try typeExpr(gz, scope, params[0]); | |
| 9553 | const result = try gz.addUnNode(.restrict, operand, node); | |
| 9554 | return rvalue(gz, ri, result, node); | |
| 9555 | }, | |
| 9550 | 9556 | |
| 9551 | 9557 | .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow), |
| 9552 | 9558 | .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow), |
lib/std/zig/AstRlAnnotate.zig+1| ... | ... | @@ -923,6 +923,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 923 | 923 | .work_item_id, |
| 924 | 924 | .work_group_size, |
| 925 | 925 | .work_group_id, |
| 926 | .Restrict, | |
| 926 | 927 | => { |
| 927 | 928 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); |
| 928 | 929 | return false; |
lib/std/zig/BuiltinFn.zig+8| ... | ... | @@ -90,6 +90,7 @@ pub const Tag = enum { |
| 90 | 90 | size_of, |
| 91 | 91 | splat, |
| 92 | 92 | reduce, |
| 93 | Restrict, | |
| 93 | 94 | src, |
| 94 | 95 | sqrt, |
| 95 | 96 | sin, |
| ... | ... | @@ -795,6 +796,13 @@ pub const list = list: { |
| 795 | 796 | .param_count = 2, |
| 796 | 797 | }, |
| 797 | 798 | }, |
| 799 | .{ | |
| 800 | "@Restrict", | |
| 801 | .{ | |
| 802 | .tag = .Restrict, | |
| 803 | .param_count = 1, | |
| 804 | }, | |
| 805 | }, | |
| 798 | 806 | .{ |
| 799 | 807 | "@src", |
| 800 | 808 | .{ |
lib/std/zig/Zir.zig+11| ... | ... | @@ -1071,6 +1071,12 @@ pub const Inst = struct { |
| 1071 | 1071 | /// Uses the `un_node` field. |
| 1072 | 1072 | restore_err_ret_index_fn_entry, |
| 1073 | 1073 | |
| 1074 | /// Creates a new restricted function pointer type based on the | |
| 1075 | /// provided function pointer type. | |
| 1076 | /// | |
| 1077 | /// Uses the `un_node` field. | |
| 1078 | restrict, | |
| 1079 | ||
| 1074 | 1080 | /// The ZIR instruction tag is one of the `Extended` ones. |
| 1075 | 1081 | /// Uses the `extended` union field. |
| 1076 | 1082 | extended, |
| ... | ... | @@ -1315,6 +1321,7 @@ pub const Inst = struct { |
| 1315 | 1321 | .validate_const, |
| 1316 | 1322 | .restore_err_ret_index_unconditional, |
| 1317 | 1323 | .restore_err_ret_index_fn_entry, |
| 1324 | .restrict, | |
| 1318 | 1325 | => false, |
| 1319 | 1326 | |
| 1320 | 1327 | .@"break", |
| ... | ... | @@ -1595,6 +1602,7 @@ pub const Inst = struct { |
| 1595 | 1602 | .validate_array_init_ref_ty, |
| 1596 | 1603 | .array_init_elem_type, |
| 1597 | 1604 | .array_init_elem_ptr, |
| 1605 | .restrict, | |
| 1598 | 1606 | => false, |
| 1599 | 1607 | |
| 1600 | 1608 | .extended => switch (data.extended.opcode) { |
| ... | ... | @@ -1711,6 +1719,7 @@ pub const Inst = struct { |
| 1711 | 1719 | .merge_error_sets = .pl_node, |
| 1712 | 1720 | .mod_rem = .pl_node, |
| 1713 | 1721 | .ref = .un_tok, |
| 1722 | .restrict = .un_node, | |
| 1714 | 1723 | .ret_node = .un_node, |
| 1715 | 1724 | .ret_load = .un_node, |
| 1716 | 1725 | .ret_implicit = .un_tok, |
| ... | ... | @@ -4755,6 +4764,8 @@ fn findTrackableInner( |
| 4755 | 4764 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4756 | 4765 | } |
| 4757 | 4766 | }, |
| 4767 | // Restricted function pointer types need tracking, but have no body. | |
| 4768 | .restrict => return contents.other.append(gpa, inst), | |
| 4758 | 4769 | } |
| 4759 | 4770 | } |
| 4760 | 4771 |
src/InternPool.zig+41| ... | ... | @@ -117,6 +117,13 @@ pub const empty: InternPool = .{ |
| 117 | 117 | .free_dep_entries = .empty, |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | pub const RestrictedSetIndex = enum(u32) { | |
| 121 | /// placeholder while I slowly work my way towards a more complete implementation | |
| 122 | some = 0, | |
| 123 | none = std.math.maxInt(u32), | |
| 124 | _, | |
| 125 | }; | |
| 126 | ||
| 120 | 127 | /// A `TrackedInst.Index` provides a single, unchanging reference to a ZIR instruction across a whole |
| 121 | 128 | /// compilation. From this index, you can acquire a `TrackedInst`, which containss a reference to both |
| 122 | 129 | /// the file which the instruction lives in, and the instruction index itself, which is updated on |
| ... | ... | @@ -2079,6 +2086,7 @@ pub const Key = union(enum) { |
| 2079 | 2086 | sentinel: Index = .none, |
| 2080 | 2087 | flags: Flags = .{}, |
| 2081 | 2088 | packed_offset: PackedOffset = .{ .bit_offset = 0, .host_size = 0 }, |
| 2089 | restricted_set: RestrictedSetIndex = .none, | |
| 2082 | 2090 | |
| 2083 | 2091 | pub const VectorIndex = enum(u16) { |
| 2084 | 2092 | none = std.math.maxInt(u16), |
| ... | ... | @@ -5389,6 +5397,9 @@ pub const Tag = enum(u8) { |
| 5389 | 5397 | type_vector, |
| 5390 | 5398 | /// A fully explicitly specified pointer type. |
| 5391 | 5399 | type_pointer, |
| 5400 | /// A pointer type created by using the `@Restrict` builtin. | |
| 5401 | /// data is `Index` of underlying, non-restrict pointer type. | |
| 5402 | type_pointer_restricted, | |
| 5392 | 5403 | /// A slice type. |
| 5393 | 5404 | /// data is Index of underlying pointer type. |
| 5394 | 5405 | type_slice, |
| ... | ... | @@ -5666,6 +5677,7 @@ pub const Tag = enum(u8) { |
| 5666 | 5677 | .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector }, |
| 5667 | 5678 | .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector }, |
| 5668 | 5679 | .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer }, |
| 5680 | .type_pointer_restricted = .{ .summary = .@"@Restrict(*... {.payload.child%summary})", .data = Index }, | |
| 5669 | 5681 | .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index }, |
| 5670 | 5682 | .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index }, |
| 5671 | 5683 | .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index }, |
| ... | ... | @@ -6970,6 +6982,16 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6970 | 6982 | |
| 6971 | 6983 | .type_pointer => .{ .ptr_type = extraData(unwrapped_index.getExtra(ip), Tag.TypePointer, data) }, |
| 6972 | 6984 | |
| 6985 | .type_pointer_restricted => { | |
| 6986 | const child_ptr_index: Index = @enumFromInt(data); | |
| 6987 | const child_ptr_unwrapped = child_ptr_index.unwrap(ip); | |
| 6988 | const child_ptr_item = child_ptr_unwrapped.getItem(ip); | |
| 6989 | assert(child_ptr_item.tag == .type_pointer); | |
| 6990 | var ptr_info = extraData(child_ptr_unwrapped.getExtra(ip), Tag.TypePointer, child_ptr_item.data); | |
| 6991 | ptr_info.restricted_set = .some; | |
| 6992 | return .{ .ptr_type = ptr_info }; | |
| 6993 | }, | |
| 6994 | ||
| 6973 | 6995 | .type_slice => { |
| 6974 | 6996 | const many_ptr_index: Index = @enumFromInt(data); |
| 6975 | 6997 | const many_ptr_unwrapped = many_ptr_index.unwrap(ip); |
| ... | ... | @@ -10388,6 +10410,7 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { |
| 10388 | 10410 | TrackedInst.Index, |
| 10389 | 10411 | TrackedInst.Index.Optional, |
| 10390 | 10412 | ComptimeAllocIndex, |
| 10413 | RestrictedSetIndex, | |
| 10391 | 10414 | => @intFromEnum(@field(item, field.name)), |
| 10392 | 10415 | |
| 10393 | 10416 | u32, |
| ... | ... | @@ -10451,6 +10474,7 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat |
| 10451 | 10474 | TrackedInst.Index, |
| 10452 | 10475 | TrackedInst.Index.Optional, |
| 10453 | 10476 | ComptimeAllocIndex, |
| 10477 | RestrictedSetIndex, | |
| 10454 | 10478 | => @enumFromInt(extra_item), |
| 10455 | 10479 | |
| 10456 | 10480 | u32, |
| ... | ... | @@ -11092,6 +11116,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 11092 | 11116 | .type_array_big => @sizeOf(Array), |
| 11093 | 11117 | .type_vector => @sizeOf(Vector), |
| 11094 | 11118 | .type_pointer => @sizeOf(Tag.TypePointer), |
| 11119 | .type_pointer_restricted => 0, | |
| 11095 | 11120 | .type_slice => 0, |
| 11096 | 11121 | .type_optional => 0, |
| 11097 | 11122 | .type_anyframe => 0, |
| ... | ... | @@ -11319,6 +11344,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { |
| 11319 | 11344 | .type_array_big, |
| 11320 | 11345 | .type_vector, |
| 11321 | 11346 | .type_pointer, |
| 11347 | .type_pointer_restricted, | |
| 11322 | 11348 | .type_optional, |
| 11323 | 11349 | .type_anyframe, |
| 11324 | 11350 | .type_error_union, |
| ... | ... | @@ -11902,6 +11928,19 @@ pub fn getOrPutTrailingString( |
| 11902 | 11928 | return value; |
| 11903 | 11929 | } |
| 11904 | 11930 | |
| 11931 | pub fn restrictedFunctionPointerType( | |
| 11932 | ip: *InternPool, | |
| 11933 | gpa: Allocator, | |
| 11934 | tid: Zcu.PerThread.Id, | |
| 11935 | fn_ty: Index, | |
| 11936 | ) Allocator.Error!Index { | |
| 11937 | _ = ip; | |
| 11938 | _ = gpa; | |
| 11939 | _ = tid; | |
| 11940 | _ = fn_ty; | |
| 11941 | @panic("TODO"); | |
| 11942 | } | |
| 11943 | ||
| 11905 | 11944 | pub fn getString(ip: *InternPool, key: []const u8) OptionalNullTerminatedString { |
| 11906 | 11945 | const full_hash = Hash.hash(0, key); |
| 11907 | 11946 | const hash: u32 = @truncate(full_hash >> 32); |
| ... | ... | @@ -12055,6 +12094,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 12055 | 12094 | .type_array_small, |
| 12056 | 12095 | .type_vector, |
| 12057 | 12096 | .type_pointer, |
| 12097 | .type_pointer_restricted, | |
| 12058 | 12098 | .type_slice, |
| 12059 | 12099 | .type_optional, |
| 12060 | 12100 | .type_anyframe, |
| ... | ... | @@ -12411,6 +12451,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12411 | 12451 | .type_vector => .vector, |
| 12412 | 12452 | |
| 12413 | 12453 | .type_pointer, |
| 12454 | .type_pointer_restricted, | |
| 12414 | 12455 | .type_slice, |
| 12415 | 12456 | => .pointer, |
| 12416 | 12457 |
src/Sema.zig+22| ... | ... | @@ -1305,6 +1305,7 @@ fn analyzeBodyInner( |
| 1305 | 1305 | .validate_array_init_ref_ty => try sema.zirValidateArrayInitRefTy(block, inst), |
| 1306 | 1306 | .opt_eu_base_ptr_init => try sema.zirOptEuBasePtrInit(block, inst), |
| 1307 | 1307 | .coerce_ptr_elem_ty => try sema.zirCoercePtrElemTy(block, inst), |
| 1308 | .restrict => try sema.zirRestrict(block, inst), | |
| 1308 | 1309 | |
| 1309 | 1310 | .clz => try sema.zirBitCount(block, inst, .clz, Value.clz), |
| 1310 | 1311 | .ctz => try sema.zirBitCount(block, inst, .ctz, Value.ctz), |
| ... | ... | @@ -4681,6 +4682,26 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4681 | 4682 | } |
| 4682 | 4683 | } |
| 4683 | 4684 | |
| 4685 | fn zirRestrict(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 4686 | const pt = sema.pt; | |
| 4687 | const zcu = pt.zcu; | |
| 4688 | ||
| 4689 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | |
| 4690 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); | |
| 4691 | const ptr_ty = try sema.resolveType(block, ty_src, inst_data.operand); | |
| 4692 | ||
| 4693 | try sema.checkPtrOperand(block, ty_src, ptr_ty); | |
| 4694 | ||
| 4695 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 4696 | const pointee_ty: Type = .fromInterned(ptr_info.child); | |
| 4697 | if (ptr_info.flags.size != .one or pointee_ty.zigTypeTag(zcu) == .@"fn") { | |
| 4698 | return sema.fail(block, ty_src, "expected function pointer type; found {f}", .{ptr_ty.fmt(pt)}); | |
| 4699 | } | |
| 4700 | ||
| 4701 | const new_ty = try pt.restrictedFunctionPointerType(pointee_ty); | |
| 4702 | return .fromType(new_ty); | |
| 4703 | } | |
| 4704 | ||
| 4684 | 4705 | fn zirTryOperandTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { |
| 4685 | 4706 | const pt = sema.pt; |
| 4686 | 4707 | const zcu = pt.zcu; |
| ... | ... | @@ -36062,6 +36083,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36062 | 36083 | .type_int_signed, // i0 handled above |
| 36063 | 36084 | .type_int_unsigned, // u0 handled above |
| 36064 | 36085 | .type_pointer, |
| 36086 | .type_pointer_restricted, | |
| 36065 | 36087 | .type_slice, |
| 36066 | 36088 | .type_anyframe, |
| 36067 | 36089 | .type_error_union, |
src/Zcu/PerThread.zig+6| ... | ... | @@ -3420,6 +3420,8 @@ pub fn internUnion(pt: Zcu.PerThread, un: InternPool.Key.Union) Allocator.Error! |
| 3420 | 3420 | /// this because it requires potentially pushing to the job queue. |
| 3421 | 3421 | pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value { |
| 3422 | 3422 | const ip = &pt.zcu.intern_pool; |
| 3423 | // TODO: avoid indexToKey | |
| 3424 | // TODO: check if dest is restricted function pointer type | |
| 3423 | 3425 | switch (ip.indexToKey(val.toIntern())) { |
| 3424 | 3426 | .@"extern" => |e| { |
| 3425 | 3427 | const coerced = try pt.getExtern(.{ |
| ... | ... | @@ -3544,6 +3546,10 @@ pub fn funcType(pt: Zcu.PerThread, key: InternPool.GetFuncTypeKey) Allocator.Err |
| 3544 | 3546 | return Type.fromInterned(try pt.zcu.intern_pool.getFuncType(pt.zcu.gpa, pt.tid, key)); |
| 3545 | 3547 | } |
| 3546 | 3548 | |
| 3549 | pub fn restrictedFunctionPointerType(pt: Zcu.PerThread, fn_ty: Type) Allocator.Error!Type { | |
| 3550 | return .fromInterned(try pt.zcu.intern_pool.restrictedFunctionPointerType(pt.zcu.gpa, pt.tid, fn_ty.toIntern())); | |
| 3551 | } | |
| 3552 | ||
| 3547 | 3553 | /// Use this for `anyframe->T` only. |
| 3548 | 3554 | /// For `anyframe`, use the `InternPool.Index.anyframe` tag directly. |
| 3549 | 3555 | pub fn anyframeType(pt: Zcu.PerThread, payload_ty: Type) Allocator.Error!Type { |
src/print_zir.zig+1| ... | ... | @@ -266,6 +266,7 @@ const Writer = struct { |
| 266 | 266 | .opt_eu_base_ptr_init, |
| 267 | 267 | .restore_err_ret_index_unconditional, |
| 268 | 268 | .restore_err_ret_index_fn_entry, |
| 269 | .restrict, | |
| 269 | 270 | => try self.writeUnNode(stream, inst), |
| 270 | 271 | |
| 271 | 272 | .ref, |