authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-06 16:12:31-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-06 16:12:31-04:00
log367e2b2fe43a2de09767ad8d5657866088b44678
tree686b57ecfcfd472d70493c46c60a562b96d5ad31
parent41bf81dc3231eb763c93eb95b152e7ab8d3c5af8
parent14685e59b26c8dc002ce6c25c6916cbad54e79d0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11800 from Vexu/stage2

`zig2 build test-std` progress

14 files changed, 339 insertions(+), 140 deletions(-)

lib/std/crypto/scrypt.zig+10-10
......@@ -73,11 +73,11 @@ fn salsaXor(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16)
7373}
7474
7575fn blockMix(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16) u32, r: u30) void {
76 blockCopy(tmp, in[(2 * r - 1) * 16 ..], 1);
76 blockCopy(tmp, @alignCast(16, in[(2 * r - 1) * 16 ..]), 1);
7777 var i: usize = 0;
7878 while (i < 2 * r) : (i += 2) {
79 salsaXor(tmp, in[i * 16 ..], out[i * 8 ..]);
80 salsaXor(tmp, in[i * 16 + 16 ..], out[i * 8 + r * 16 ..]);
79 salsaXor(tmp, @alignCast(16, in[i * 16 ..]), @alignCast(16, out[i * 8 ..]));
80 salsaXor(tmp, @alignCast(16, in[i * 16 + 16 ..]), @alignCast(16, out[i * 8 + r * 16 ..]));
8181 }
8282}
8383
......@@ -87,8 +87,8 @@ fn integerify(b: []align(16) const u32, r: u30) u64 {
8787}
8888
8989fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16) u32) void {
90 var x = xy[0 .. 32 * r];
91 var y = xy[32 * r ..];
90 var x = @alignCast(16, xy[0 .. 32 * r]);
91 var y = @alignCast(16, xy[32 * r ..]);
9292
9393 for (x) |*v1, j| {
9494 v1.* = mem.readIntSliceLittle(u32, b[4 * j ..]);
......@@ -97,21 +97,21 @@ fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16)
9797 var tmp: [16]u32 align(16) = undefined;
9898 var i: usize = 0;
9999 while (i < n) : (i += 2) {
100 blockCopy(v[i * (32 * r) ..], x, 2 * r);
100 blockCopy(@alignCast(16, v[i * (32 * r) ..]), x, 2 * r);
101101 blockMix(&tmp, x, y, r);
102102
103 blockCopy(v[(i + 1) * (32 * r) ..], y, 2 * r);
103 blockCopy(@alignCast(16, v[(i + 1) * (32 * r) ..]), y, 2 * r);
104104 blockMix(&tmp, y, x, r);
105105 }
106106
107107 i = 0;
108108 while (i < n) : (i += 2) {
109109 var j = @intCast(usize, integerify(x, r) & (n - 1));
110 blockXor(x, v[j * (32 * r) ..], 2 * r);
110 blockXor(x, @alignCast(16, v[j * (32 * r) ..]), 2 * r);
111111 blockMix(&tmp, x, y, r);
112112
113113 j = @intCast(usize, integerify(y, r) & (n - 1));
114 blockXor(y, v[j * (32 * r) ..], 2 * r);
114 blockXor(y, @alignCast(16, v[j * (32 * r) ..]), 2 * r);
115115 blockMix(&tmp, y, x, r);
116116 }
117117
......@@ -201,7 +201,7 @@ pub fn kdf(
201201 try pwhash.pbkdf2(dk, password, salt, 1, HmacSha256);
202202 var i: u32 = 0;
203203 while (i < params.p) : (i += 1) {
204 smix(dk[i * 128 * params.r ..], params.r, n, v, xy);
204 smix(@alignCast(16, dk[i * 128 * params.r ..]), params.r, n, v, xy);
205205 }
206206 try pwhash.pbkdf2(derived_key, password, dk, 1, HmacSha256);
207207}
lib/std/fs.zig+2-4
......@@ -887,10 +887,8 @@ pub const Dir = struct {
887887 }
888888
889889 pub fn deinit(self: *Walker) void {
890 while (self.stack.popOrNull()) |*item| {
891 if (self.stack.items.len != 0) {
892 item.iter.dir.close();
893 }
890 for (self.stack.items) |*item| {
891 item.iter.dir.close();
894892 }
895893 self.stack.deinit();
896894 self.name_buffer.deinit();
lib/std/os/linux/io_uring.zig+96-100
......@@ -7,10 +7,6 @@ const os = std.os;
77const linux = os.linux;
88const testing = std.testing;
99
10const io_uring_params = linux.io_uring_params;
11const io_uring_sqe = linux.io_uring_sqe;
12const io_uring_cqe = linux.io_uring_cqe;
13
1410pub const IO_Uring = struct {
1511 fd: os.fd_t = -1,
1612 sq: SubmissionQueue,
......@@ -18,24 +14,24 @@ pub const IO_Uring = struct {
1814 flags: u32,
1915 features: u32,
2016
21 /// A friendly way to setup an io_uring, with default io_uring_params.
17 /// A friendly way to setup an io_uring, with default linux.io_uring_params.
2218 /// `entries` must be a power of two between 1 and 4096, although the kernel will make the final
2319 /// call on how many entries the submission and completion queues will ultimately have,
2420 /// see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L8027-L8050.
2521 /// Matches the interface of io_uring_queue_init() in liburing.
2622 pub fn init(entries: u13, flags: u32) !IO_Uring {
27 var params = mem.zeroInit(io_uring_params, .{
23 var params = mem.zeroInit(linux.io_uring_params, .{
2824 .flags = flags,
2925 .sq_thread_idle = 1000,
3026 });
3127 return try IO_Uring.init_params(entries, &params);
3228 }
3329
34 /// A powerful way to setup an io_uring, if you want to tweak io_uring_params such as submission
30 /// A powerful way to setup an io_uring, if you want to tweak linux.io_uring_params such as submission
3531 /// queue thread cpu affinity or thread idle timeout (the kernel and our default is 1 second).
3632 /// `params` is passed by reference because the kernel needs to modify the parameters.
3733 /// Matches the interface of io_uring_queue_init_params() in liburing.
38 pub fn init_params(entries: u13, p: *io_uring_params) !IO_Uring {
34 pub fn init_params(entries: u13, p: *linux.io_uring_params) !IO_Uring {
3935 if (entries == 0) return error.EntriesZero;
4036 if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;
4137
......@@ -53,7 +49,7 @@ pub const IO_Uring = struct {
5349 .FAULT => return error.ParamsOutsideAccessibleAddressSpace,
5450 // The resv array contains non-zero data, p.flags contains an unsupported flag,
5551 // entries out of bounds, IORING_SETUP_SQ_AFF was specified without IORING_SETUP_SQPOLL,
56 // or IORING_SETUP_CQSIZE was specified but io_uring_params.cq_entries was invalid:
52 // or IORING_SETUP_CQSIZE was specified but linux.io_uring_params.cq_entries was invalid:
5753 .INVAL => return error.ArgumentsInvalid,
5854 .MFILE => return error.ProcessFdQuotaExceeded,
5955 .NFILE => return error.SystemFdQuotaExceeded,
......@@ -135,7 +131,7 @@ pub const IO_Uring = struct {
135131 /// and the null return in liburing is more a C idiom than anything else, for lack of a better
136132 /// alternative. In Zig, we have first-class error handling... so let's use it.
137133 /// Matches the implementation of io_uring_get_sqe() in liburing.
138 pub fn get_sqe(self: *IO_Uring) !*io_uring_sqe {
134 pub fn get_sqe(self: *IO_Uring) !*linux.io_uring_sqe {
139135 const head = @atomicLoad(u32, self.sq.head, .Acquire);
140136 // Remember that these head and tail offsets wrap around every four billion operations.
141137 // We must therefore use wrapping addition and subtraction to avoid a runtime crash.
......@@ -268,7 +264,7 @@ pub const IO_Uring = struct {
268264 /// Faster, because we can now amortize the atomic store release to `cq.head` across the batch.
269265 /// See https://github.com/axboe/liburing/issues/103#issuecomment-686665007.
270266 /// Matches the implementation of io_uring_peek_batch_cqe() in liburing, but supports waiting.
271 pub fn copy_cqes(self: *IO_Uring, cqes: []io_uring_cqe, wait_nr: u32) !u32 {
267 pub fn copy_cqes(self: *IO_Uring, cqes: []linux.io_uring_cqe, wait_nr: u32) !u32 {
272268 const count = self.copy_cqes_ready(cqes, wait_nr);
273269 if (count > 0) return count;
274270 if (self.cq_ring_needs_flush() or wait_nr > 0) {
......@@ -278,7 +274,7 @@ pub const IO_Uring = struct {
278274 return 0;
279275 }
280276
281 fn copy_cqes_ready(self: *IO_Uring, cqes: []io_uring_cqe, wait_nr: u32) u32 {
277 fn copy_cqes_ready(self: *IO_Uring, cqes: []linux.io_uring_cqe, wait_nr: u32) u32 {
282278 _ = wait_nr;
283279 const ready = self.cq_ready();
284280 const count = std.math.min(cqes.len, ready);
......@@ -298,8 +294,8 @@ pub const IO_Uring = struct {
298294
299295 /// Returns a copy of an I/O completion, waiting for it if necessary, and advancing the CQ ring.
300296 /// A convenience method for `copy_cqes()` for when you don't need to batch or peek.
301 pub fn copy_cqe(ring: *IO_Uring) !io_uring_cqe {
302 var cqes: [1]io_uring_cqe = undefined;
297 pub fn copy_cqe(ring: *IO_Uring) !linux.io_uring_cqe {
298 var cqes: [1]linux.io_uring_cqe = undefined;
303299 while (true) {
304300 const count = try ring.copy_cqes(&cqes, 1);
305301 if (count > 0) return cqes[0];
......@@ -316,7 +312,7 @@ pub const IO_Uring = struct {
316312 /// Must be called exactly once after a zero-copy CQE has been processed by your application.
317313 /// Not idempotent, calling more than once will result in other CQEs being lost.
318314 /// Matches the implementation of cqe_seen() in liburing.
319 pub fn cqe_seen(self: *IO_Uring, cqe: *io_uring_cqe) void {
315 pub fn cqe_seen(self: *IO_Uring, cqe: *linux.io_uring_cqe) void {
320316 _ = cqe;
321317 self.cq_advance(1);
322318 }
......@@ -339,7 +335,7 @@ pub const IO_Uring = struct {
339335 /// apply to the write, since the fsync may complete before the write is issued to the disk.
340336 /// You should preferably use `link_with_next_sqe()` on a write's SQE to link it with an fsync,
341337 /// or else insert a full write barrier using `drain_previous_sqes()` when queueing an fsync.
342 pub fn fsync(self: *IO_Uring, user_data: u64, fd: os.fd_t, flags: u32) !*io_uring_sqe {
338 pub fn fsync(self: *IO_Uring, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe {
343339 const sqe = try self.get_sqe();
344340 io_uring_prep_fsync(sqe, fd, flags);
345341 sqe.user_data = user_data;
......@@ -351,7 +347,7 @@ pub const IO_Uring = struct {
351347 /// A no-op is more useful than may appear at first glance.
352348 /// For example, you could call `drain_previous_sqes()` on the returned SQE, to use the no-op to
353349 /// know when the ring is idle before acting on a kill signal.
354 pub fn nop(self: *IO_Uring, user_data: u64) !*io_uring_sqe {
350 pub fn nop(self: *IO_Uring, user_data: u64) !*linux.io_uring_sqe {
355351 const sqe = try self.get_sqe();
356352 io_uring_prep_nop(sqe);
357353 sqe.user_data = user_data;
......@@ -387,7 +383,7 @@ pub const IO_Uring = struct {
387383 fd: os.fd_t,
388384 buffer: ReadBuffer,
389385 offset: u64,
390 ) !*io_uring_sqe {
386 ) !*linux.io_uring_sqe {
391387 const sqe = try self.get_sqe();
392388 switch (buffer) {
393389 .buffer => |slice| io_uring_prep_read(sqe, fd, slice, offset),
......@@ -410,7 +406,7 @@ pub const IO_Uring = struct {
410406 fd: os.fd_t,
411407 buffer: []const u8,
412408 offset: u64,
413 ) !*io_uring_sqe {
409 ) !*linux.io_uring_sqe {
414410 const sqe = try self.get_sqe();
415411 io_uring_prep_write(sqe, fd, buffer, offset);
416412 sqe.user_data = user_data;
......@@ -429,7 +425,7 @@ pub const IO_Uring = struct {
429425 buffer: *os.iovec,
430426 offset: u64,
431427 buffer_index: u16,
432 ) !*io_uring_sqe {
428 ) !*linux.io_uring_sqe {
433429 const sqe = try self.get_sqe();
434430 io_uring_prep_read_fixed(sqe, fd, buffer, offset, buffer_index);
435431 sqe.user_data = user_data;
......@@ -446,7 +442,7 @@ pub const IO_Uring = struct {
446442 fd: os.fd_t,
447443 iovecs: []const os.iovec_const,
448444 offset: u64,
449 ) !*io_uring_sqe {
445 ) !*linux.io_uring_sqe {
450446 const sqe = try self.get_sqe();
451447 io_uring_prep_writev(sqe, fd, iovecs, offset);
452448 sqe.user_data = user_data;
......@@ -465,7 +461,7 @@ pub const IO_Uring = struct {
465461 buffer: *os.iovec,
466462 offset: u64,
467463 buffer_index: u16,
468 ) !*io_uring_sqe {
464 ) !*linux.io_uring_sqe {
469465 const sqe = try self.get_sqe();
470466 io_uring_prep_write_fixed(sqe, fd, buffer, offset, buffer_index);
471467 sqe.user_data = user_data;
......@@ -481,7 +477,7 @@ pub const IO_Uring = struct {
481477 addr: *os.sockaddr,
482478 addrlen: *os.socklen_t,
483479 flags: u32,
484 ) !*io_uring_sqe {
480 ) !*linux.io_uring_sqe {
485481 const sqe = try self.get_sqe();
486482 io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
487483 sqe.user_data = user_data;
......@@ -496,7 +492,7 @@ pub const IO_Uring = struct {
496492 fd: os.fd_t,
497493 addr: *const os.sockaddr,
498494 addrlen: os.socklen_t,
499 ) !*io_uring_sqe {
495 ) !*linux.io_uring_sqe {
500496 const sqe = try self.get_sqe();
501497 io_uring_prep_connect(sqe, fd, addr, addrlen);
502498 sqe.user_data = user_data;
......@@ -512,7 +508,7 @@ pub const IO_Uring = struct {
512508 fd: os.fd_t,
513509 op: u32,
514510 ev: ?*linux.epoll_event,
515 ) !*io_uring_sqe {
511 ) !*linux.io_uring_sqe {
516512 const sqe = try self.get_sqe();
517513 io_uring_prep_epoll_ctl(sqe, epfd, fd, op, ev);
518514 sqe.user_data = user_data;
......@@ -541,7 +537,7 @@ pub const IO_Uring = struct {
541537 fd: os.fd_t,
542538 buffer: RecvBuffer,
543539 flags: u32,
544 ) !*io_uring_sqe {
540 ) !*linux.io_uring_sqe {
545541 const sqe = try self.get_sqe();
546542 switch (buffer) {
547543 .buffer => |slice| io_uring_prep_recv(sqe, fd, slice, flags),
......@@ -564,7 +560,7 @@ pub const IO_Uring = struct {
564560 fd: os.fd_t,
565561 buffer: []const u8,
566562 flags: u32,
567 ) !*io_uring_sqe {
563 ) !*linux.io_uring_sqe {
568564 const sqe = try self.get_sqe();
569565 io_uring_prep_send(sqe, fd, buffer, flags);
570566 sqe.user_data = user_data;
......@@ -579,7 +575,7 @@ pub const IO_Uring = struct {
579575 fd: os.fd_t,
580576 msg: *os.msghdr,
581577 flags: u32,
582 ) !*io_uring_sqe {
578 ) !*linux.io_uring_sqe {
583579 const sqe = try self.get_sqe();
584580 io_uring_prep_recvmsg(sqe, fd, msg, flags);
585581 sqe.user_data = user_data;
......@@ -594,7 +590,7 @@ pub const IO_Uring = struct {
594590 fd: os.fd_t,
595591 msg: *const os.msghdr_const,
596592 flags: u32,
597 ) !*io_uring_sqe {
593 ) !*linux.io_uring_sqe {
598594 const sqe = try self.get_sqe();
599595 io_uring_prep_sendmsg(sqe, fd, msg, flags);
600596 sqe.user_data = user_data;
......@@ -610,7 +606,7 @@ pub const IO_Uring = struct {
610606 path: [*:0]const u8,
611607 flags: u32,
612608 mode: os.mode_t,
613 ) !*io_uring_sqe {
609 ) !*linux.io_uring_sqe {
614610 const sqe = try self.get_sqe();
615611 io_uring_prep_openat(sqe, fd, path, flags, mode);
616612 sqe.user_data = user_data;
......@@ -619,7 +615,7 @@ pub const IO_Uring = struct {
619615
620616 /// Queues (but does not submit) an SQE to perform a `close(2)`.
621617 /// Returns a pointer to the SQE.
622 pub fn close(self: *IO_Uring, user_data: u64, fd: os.fd_t) !*io_uring_sqe {
618 pub fn close(self: *IO_Uring, user_data: u64, fd: os.fd_t) !*linux.io_uring_sqe {
623619 const sqe = try self.get_sqe();
624620 io_uring_prep_close(sqe, fd);
625621 sqe.user_data = user_data;
......@@ -645,7 +641,7 @@ pub const IO_Uring = struct {
645641 ts: *const os.linux.kernel_timespec,
646642 count: u32,
647643 flags: u32,
648 ) !*io_uring_sqe {
644 ) !*linux.io_uring_sqe {
649645 const sqe = try self.get_sqe();
650646 io_uring_prep_timeout(sqe, ts, count, flags);
651647 sqe.user_data = user_data;
......@@ -665,7 +661,7 @@ pub const IO_Uring = struct {
665661 user_data: u64,
666662 timeout_user_data: u64,
667663 flags: u32,
668 ) !*io_uring_sqe {
664 ) !*linux.io_uring_sqe {
669665 const sqe = try self.get_sqe();
670666 io_uring_prep_timeout_remove(sqe, timeout_user_data, flags);
671667 sqe.user_data = user_data;
......@@ -693,7 +689,7 @@ pub const IO_Uring = struct {
693689 user_data: u64,
694690 ts: *const os.linux.kernel_timespec,
695691 flags: u32,
696 ) !*io_uring_sqe {
692 ) !*linux.io_uring_sqe {
697693 const sqe = try self.get_sqe();
698694 io_uring_prep_link_timeout(sqe, ts, flags);
699695 sqe.user_data = user_data;
......@@ -707,7 +703,7 @@ pub const IO_Uring = struct {
707703 user_data: u64,
708704 fd: os.fd_t,
709705 poll_mask: u32,
710 ) !*io_uring_sqe {
706 ) !*linux.io_uring_sqe {
711707 const sqe = try self.get_sqe();
712708 io_uring_prep_poll_add(sqe, fd, poll_mask);
713709 sqe.user_data = user_data;
......@@ -720,7 +716,7 @@ pub const IO_Uring = struct {
720716 self: *IO_Uring,
721717 user_data: u64,
722718 target_user_data: u64,
723 ) !*io_uring_sqe {
719 ) !*linux.io_uring_sqe {
724720 const sqe = try self.get_sqe();
725721 io_uring_prep_poll_remove(sqe, target_user_data);
726722 sqe.user_data = user_data;
......@@ -736,7 +732,7 @@ pub const IO_Uring = struct {
736732 new_user_data: u64,
737733 poll_mask: u32,
738734 flags: u32,
739 ) !*io_uring_sqe {
735 ) !*linux.io_uring_sqe {
740736 const sqe = try self.get_sqe();
741737 io_uring_prep_poll_update(sqe, old_user_data, new_user_data, poll_mask, flags);
742738 sqe.user_data = user_data;
......@@ -752,7 +748,7 @@ pub const IO_Uring = struct {
752748 mode: i32,
753749 offset: u64,
754750 len: u64,
755 ) !*io_uring_sqe {
751 ) !*linux.io_uring_sqe {
756752 const sqe = try self.get_sqe();
757753 io_uring_prep_fallocate(sqe, fd, mode, offset, len);
758754 sqe.user_data = user_data;
......@@ -769,7 +765,7 @@ pub const IO_Uring = struct {
769765 flags: u32,
770766 mask: u32,
771767 buf: *linux.Statx,
772 ) !*io_uring_sqe {
768 ) !*linux.io_uring_sqe {
773769 const sqe = try self.get_sqe();
774770 io_uring_prep_statx(sqe, fd, path, flags, mask, buf);
775771 sqe.user_data = user_data;
......@@ -789,7 +785,7 @@ pub const IO_Uring = struct {
789785 user_data: u64,
790786 cancel_user_data: u64,
791787 flags: u32,
792 ) !*io_uring_sqe {
788 ) !*linux.io_uring_sqe {
793789 const sqe = try self.get_sqe();
794790 io_uring_prep_cancel(sqe, cancel_user_data, flags);
795791 sqe.user_data = user_data;
......@@ -805,7 +801,7 @@ pub const IO_Uring = struct {
805801 user_data: u64,
806802 sockfd: os.socket_t,
807803 how: u32,
808 ) !*io_uring_sqe {
804 ) !*linux.io_uring_sqe {
809805 const sqe = try self.get_sqe();
810806 io_uring_prep_shutdown(sqe, sockfd, how);
811807 sqe.user_data = user_data;
......@@ -822,7 +818,7 @@ pub const IO_Uring = struct {
822818 new_dir_fd: os.fd_t,
823819 new_path: [*:0]const u8,
824820 flags: u32,
825 ) !*io_uring_sqe {
821 ) !*linux.io_uring_sqe {
826822 const sqe = try self.get_sqe();
827823 io_uring_prep_renameat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);
828824 sqe.user_data = user_data;
......@@ -837,7 +833,7 @@ pub const IO_Uring = struct {
837833 dir_fd: os.fd_t,
838834 path: [*:0]const u8,
839835 flags: u32,
840 ) !*io_uring_sqe {
836 ) !*linux.io_uring_sqe {
841837 const sqe = try self.get_sqe();
842838 io_uring_prep_unlinkat(sqe, dir_fd, path, flags);
843839 sqe.user_data = user_data;
......@@ -852,7 +848,7 @@ pub const IO_Uring = struct {
852848 dir_fd: os.fd_t,
853849 path: [*:0]const u8,
854850 mode: os.mode_t,
855 ) !*io_uring_sqe {
851 ) !*linux.io_uring_sqe {
856852 const sqe = try self.get_sqe();
857853 io_uring_prep_mkdirat(sqe, dir_fd, path, mode);
858854 sqe.user_data = user_data;
......@@ -867,7 +863,7 @@ pub const IO_Uring = struct {
867863 target: [*:0]const u8,
868864 new_dir_fd: os.fd_t,
869865 link_path: [*:0]const u8,
870 ) !*io_uring_sqe {
866 ) !*linux.io_uring_sqe {
871867 const sqe = try self.get_sqe();
872868 io_uring_prep_symlinkat(sqe, target, new_dir_fd, link_path);
873869 sqe.user_data = user_data;
......@@ -884,7 +880,7 @@ pub const IO_Uring = struct {
884880 new_dir_fd: os.fd_t,
885881 new_path: [*:0]const u8,
886882 flags: u32,
887 ) !*io_uring_sqe {
883 ) !*linux.io_uring_sqe {
888884 const sqe = try self.get_sqe();
889885 io_uring_prep_linkat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);
890886 sqe.user_data = user_data;
......@@ -905,7 +901,7 @@ pub const IO_Uring = struct {
905901 buffer_size: usize,
906902 group_id: usize,
907903 buffer_id: usize,
908 ) !*io_uring_sqe {
904 ) !*linux.io_uring_sqe {
909905 const sqe = try self.get_sqe();
910906 io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id);
911907 sqe.user_data = user_data;
......@@ -919,7 +915,7 @@ pub const IO_Uring = struct {
919915 user_data: u64,
920916 buffers_count: usize,
921917 group_id: usize,
922 ) !*io_uring_sqe {
918 ) !*linux.io_uring_sqe {
923919 const sqe = try self.get_sqe();
924920 io_uring_prep_remove_buffers(sqe, buffers_count, group_id);
925921 sqe.user_data = user_data;
......@@ -1083,7 +1079,7 @@ pub const SubmissionQueue = struct {
10831079 flags: *u32,
10841080 dropped: *u32,
10851081 array: []u32,
1086 sqes: []io_uring_sqe,
1082 sqes: []linux.io_uring_sqe,
10871083 mmap: []align(mem.page_size) u8,
10881084 mmap_sqes: []align(mem.page_size) u8,
10891085
......@@ -1094,12 +1090,12 @@ pub const SubmissionQueue = struct {
10941090 sqe_head: u32 = 0,
10951091 sqe_tail: u32 = 0,
10961092
1097 pub fn init(fd: os.fd_t, p: io_uring_params) !SubmissionQueue {
1093 pub fn init(fd: os.fd_t, p: linux.io_uring_params) !SubmissionQueue {
10981094 assert(fd >= 0);
10991095 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
11001096 const size = std.math.max(
11011097 p.sq_off.array + p.sq_entries * @sizeOf(u32),
1102 p.cq_off.cqes + p.cq_entries * @sizeOf(io_uring_cqe),
1098 p.cq_off.cqes + p.cq_entries * @sizeOf(linux.io_uring_cqe),
11031099 );
11041100 const mmap = try os.mmap(
11051101 null,
......@@ -1113,8 +1109,8 @@ pub const SubmissionQueue = struct {
11131109 assert(mmap.len == size);
11141110
11151111 // The motivation for the `sqes` and `array` indirection is to make it possible for the
1116 // application to preallocate static io_uring_sqe entries and then replay them when needed.
1117 const size_sqes = p.sq_entries * @sizeOf(io_uring_sqe);
1112 // application to preallocate static linux.io_uring_sqe entries and then replay them when needed.
1113 const size_sqes = p.sq_entries * @sizeOf(linux.io_uring_sqe);
11181114 const mmap_sqes = try os.mmap(
11191115 null,
11201116 size_sqes,
......@@ -1127,7 +1123,7 @@ pub const SubmissionQueue = struct {
11271123 assert(mmap_sqes.len == size_sqes);
11281124
11291125 const array = @ptrCast([*]u32, @alignCast(@alignOf(u32), &mmap[p.sq_off.array]));
1130 const sqes = @ptrCast([*]io_uring_sqe, @alignCast(@alignOf(io_uring_sqe), &mmap_sqes[0]));
1126 const sqes = @ptrCast([*]linux.io_uring_sqe, @alignCast(@alignOf(linux.io_uring_sqe), &mmap_sqes[0]));
11311127 // We expect the kernel copies p.sq_entries to the u32 pointed to by p.sq_off.ring_entries,
11321128 // see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L7843-L7844.
11331129 assert(
......@@ -1158,15 +1154,15 @@ pub const CompletionQueue = struct {
11581154 tail: *u32,
11591155 mask: u32,
11601156 overflow: *u32,
1161 cqes: []io_uring_cqe,
1157 cqes: []linux.io_uring_cqe,
11621158
1163 pub fn init(fd: os.fd_t, p: io_uring_params, sq: SubmissionQueue) !CompletionQueue {
1159 pub fn init(fd: os.fd_t, p: linux.io_uring_params, sq: SubmissionQueue) !CompletionQueue {
11641160 assert(fd >= 0);
11651161 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
11661162 const mmap = sq.mmap;
11671163 const cqes = @ptrCast(
1168 [*]io_uring_cqe,
1169 @alignCast(@alignOf(io_uring_cqe), &mmap[p.cq_off.cqes]),
1164 [*]linux.io_uring_cqe,
1165 @alignCast(@alignOf(linux.io_uring_cqe), &mmap[p.cq_off.cqes]),
11701166 );
11711167 assert(p.cq_entries ==
11721168 @ptrCast(*u32, @alignCast(@alignOf(u32), &mmap[p.cq_off.ring_entries])).*);
......@@ -1186,7 +1182,7 @@ pub const CompletionQueue = struct {
11861182 }
11871183};
11881184
1189pub fn io_uring_prep_nop(sqe: *io_uring_sqe) void {
1185pub fn io_uring_prep_nop(sqe: *linux.io_uring_sqe) void {
11901186 sqe.* = .{
11911187 .opcode = .NOP,
11921188 .flags = 0,
......@@ -1204,7 +1200,7 @@ pub fn io_uring_prep_nop(sqe: *io_uring_sqe) void {
12041200 };
12051201}
12061202
1207pub fn io_uring_prep_fsync(sqe: *io_uring_sqe, fd: os.fd_t, flags: u32) void {
1203pub fn io_uring_prep_fsync(sqe: *linux.io_uring_sqe, fd: os.fd_t, flags: u32) void {
12081204 sqe.* = .{
12091205 .opcode = .FSYNC,
12101206 .flags = 0,
......@@ -1224,7 +1220,7 @@ pub fn io_uring_prep_fsync(sqe: *io_uring_sqe, fd: os.fd_t, flags: u32) void {
12241220
12251221pub fn io_uring_prep_rw(
12261222 op: linux.IORING_OP,
1227 sqe: *io_uring_sqe,
1223 sqe: *linux.io_uring_sqe,
12281224 fd: os.fd_t,
12291225 addr: u64,
12301226 len: usize,
......@@ -1247,16 +1243,16 @@ pub fn io_uring_prep_rw(
12471243 };
12481244}
12491245
1250pub fn io_uring_prep_read(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {
1246pub fn io_uring_prep_read(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {
12511247 io_uring_prep_rw(.READ, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
12521248}
12531249
1254pub fn io_uring_prep_write(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {
1250pub fn io_uring_prep_write(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {
12551251 io_uring_prep_rw(.WRITE, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
12561252}
12571253
12581254pub fn io_uring_prep_readv(
1259 sqe: *io_uring_sqe,
1255 sqe: *linux.io_uring_sqe,
12601256 fd: os.fd_t,
12611257 iovecs: []const os.iovec,
12621258 offset: u64,
......@@ -1265,7 +1261,7 @@ pub fn io_uring_prep_readv(
12651261}
12661262
12671263pub fn io_uring_prep_writev(
1268 sqe: *io_uring_sqe,
1264 sqe: *linux.io_uring_sqe,
12691265 fd: os.fd_t,
12701266 iovecs: []const os.iovec_const,
12711267 offset: u64,
......@@ -1273,12 +1269,12 @@ pub fn io_uring_prep_writev(
12731269 io_uring_prep_rw(.WRITEV, sqe, fd, @ptrToInt(iovecs.ptr), iovecs.len, offset);
12741270}
12751271
1276pub fn io_uring_prep_read_fixed(sqe: *io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
1272pub fn io_uring_prep_read_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
12771273 io_uring_prep_rw(.READ_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);
12781274 sqe.buf_index = buffer_index;
12791275}
12801276
1281pub fn io_uring_prep_write_fixed(sqe: *io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
1277pub fn io_uring_prep_write_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
12821278 io_uring_prep_rw(.WRITE_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);
12831279 sqe.buf_index = buffer_index;
12841280}
......@@ -1294,7 +1290,7 @@ pub inline fn __io_uring_prep_poll_mask(poll_mask: u32) u32 {
12941290}
12951291
12961292pub fn io_uring_prep_accept(
1297 sqe: *io_uring_sqe,
1293 sqe: *linux.io_uring_sqe,
12981294 fd: os.fd_t,
12991295 addr: *os.sockaddr,
13001296 addrlen: *os.socklen_t,
......@@ -1307,7 +1303,7 @@ pub fn io_uring_prep_accept(
13071303}
13081304
13091305pub fn io_uring_prep_connect(
1310 sqe: *io_uring_sqe,
1306 sqe: *linux.io_uring_sqe,
13111307 fd: os.fd_t,
13121308 addr: *const os.sockaddr,
13131309 addrlen: os.socklen_t,
......@@ -1317,7 +1313,7 @@ pub fn io_uring_prep_connect(
13171313}
13181314
13191315pub fn io_uring_prep_epoll_ctl(
1320 sqe: *io_uring_sqe,
1316 sqe: *linux.io_uring_sqe,
13211317 epfd: os.fd_t,
13221318 fd: os.fd_t,
13231319 op: u32,
......@@ -1326,18 +1322,18 @@ pub fn io_uring_prep_epoll_ctl(
13261322 io_uring_prep_rw(.EPOLL_CTL, sqe, epfd, @ptrToInt(ev), op, @intCast(u64, fd));
13271323}
13281324
1329pub fn io_uring_prep_recv(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {
1325pub fn io_uring_prep_recv(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {
13301326 io_uring_prep_rw(.RECV, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
13311327 sqe.rw_flags = flags;
13321328}
13331329
1334pub fn io_uring_prep_send(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {
1330pub fn io_uring_prep_send(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {
13351331 io_uring_prep_rw(.SEND, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
13361332 sqe.rw_flags = flags;
13371333}
13381334
13391335pub fn io_uring_prep_recvmsg(
1340 sqe: *io_uring_sqe,
1336 sqe: *linux.io_uring_sqe,
13411337 fd: os.fd_t,
13421338 msg: *os.msghdr,
13431339 flags: u32,
......@@ -1347,7 +1343,7 @@ pub fn io_uring_prep_recvmsg(
13471343}
13481344
13491345pub fn io_uring_prep_sendmsg(
1350 sqe: *io_uring_sqe,
1346 sqe: *linux.io_uring_sqe,
13511347 fd: os.fd_t,
13521348 msg: *const os.msghdr_const,
13531349 flags: u32,
......@@ -1357,7 +1353,7 @@ pub fn io_uring_prep_sendmsg(
13571353}
13581354
13591355pub fn io_uring_prep_openat(
1360 sqe: *io_uring_sqe,
1356 sqe: *linux.io_uring_sqe,
13611357 fd: os.fd_t,
13621358 path: [*:0]const u8,
13631359 flags: u32,
......@@ -1367,7 +1363,7 @@ pub fn io_uring_prep_openat(
13671363 sqe.rw_flags = flags;
13681364}
13691365
1370pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {
1366pub fn io_uring_prep_close(sqe: *linux.io_uring_sqe, fd: os.fd_t) void {
13711367 sqe.* = .{
13721368 .opcode = .CLOSE,
13731369 .flags = 0,
......@@ -1386,7 +1382,7 @@ pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {
13861382}
13871383
13881384pub fn io_uring_prep_timeout(
1389 sqe: *io_uring_sqe,
1385 sqe: *linux.io_uring_sqe,
13901386 ts: *const os.linux.kernel_timespec,
13911387 count: u32,
13921388 flags: u32,
......@@ -1395,7 +1391,7 @@ pub fn io_uring_prep_timeout(
13951391 sqe.rw_flags = flags;
13961392}
13971393
1398pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64, flags: u32) void {
1394pub fn io_uring_prep_timeout_remove(sqe: *linux.io_uring_sqe, timeout_user_data: u64, flags: u32) void {
13991395 sqe.* = .{
14001396 .opcode = .TIMEOUT_REMOVE,
14011397 .flags = 0,
......@@ -1414,7 +1410,7 @@ pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64,
14141410}
14151411
14161412pub fn io_uring_prep_link_timeout(
1417 sqe: *io_uring_sqe,
1413 sqe: *linux.io_uring_sqe,
14181414 ts: *const os.linux.kernel_timespec,
14191415 flags: u32,
14201416) void {
......@@ -1423,7 +1419,7 @@ pub fn io_uring_prep_link_timeout(
14231419}
14241420
14251421pub fn io_uring_prep_poll_add(
1426 sqe: *io_uring_sqe,
1422 sqe: *linux.io_uring_sqe,
14271423 fd: os.fd_t,
14281424 poll_mask: u32,
14291425) void {
......@@ -1432,14 +1428,14 @@ pub fn io_uring_prep_poll_add(
14321428}
14331429
14341430pub fn io_uring_prep_poll_remove(
1435 sqe: *io_uring_sqe,
1431 sqe: *linux.io_uring_sqe,
14361432 target_user_data: u64,
14371433) void {
14381434 io_uring_prep_rw(.POLL_REMOVE, sqe, -1, target_user_data, 0, 0);
14391435}
14401436
14411437pub fn io_uring_prep_poll_update(
1442 sqe: *io_uring_sqe,
1438 sqe: *linux.io_uring_sqe,
14431439 old_user_data: u64,
14441440 new_user_data: u64,
14451441 poll_mask: u32,
......@@ -1450,7 +1446,7 @@ pub fn io_uring_prep_poll_update(
14501446}
14511447
14521448pub fn io_uring_prep_fallocate(
1453 sqe: *io_uring_sqe,
1449 sqe: *linux.io_uring_sqe,
14541450 fd: os.fd_t,
14551451 mode: i32,
14561452 offset: u64,
......@@ -1474,7 +1470,7 @@ pub fn io_uring_prep_fallocate(
14741470}
14751471
14761472pub fn io_uring_prep_statx(
1477 sqe: *io_uring_sqe,
1473 sqe: *linux.io_uring_sqe,
14781474 fd: os.fd_t,
14791475 path: [*:0]const u8,
14801476 flags: u32,
......@@ -1486,7 +1482,7 @@ pub fn io_uring_prep_statx(
14861482}
14871483
14881484pub fn io_uring_prep_cancel(
1489 sqe: *io_uring_sqe,
1485 sqe: *linux.io_uring_sqe,
14901486 cancel_user_data: u64,
14911487 flags: u32,
14921488) void {
......@@ -1495,7 +1491,7 @@ pub fn io_uring_prep_cancel(
14951491}
14961492
14971493pub fn io_uring_prep_shutdown(
1498 sqe: *io_uring_sqe,
1494 sqe: *linux.io_uring_sqe,
14991495 sockfd: os.socket_t,
15001496 how: u32,
15011497) void {
......@@ -1503,7 +1499,7 @@ pub fn io_uring_prep_shutdown(
15031499}
15041500
15051501pub fn io_uring_prep_renameat(
1506 sqe: *io_uring_sqe,
1502 sqe: *linux.io_uring_sqe,
15071503 old_dir_fd: os.fd_t,
15081504 old_path: [*:0]const u8,
15091505 new_dir_fd: os.fd_t,
......@@ -1523,7 +1519,7 @@ pub fn io_uring_prep_renameat(
15231519}
15241520
15251521pub fn io_uring_prep_unlinkat(
1526 sqe: *io_uring_sqe,
1522 sqe: *linux.io_uring_sqe,
15271523 dir_fd: os.fd_t,
15281524 path: [*:0]const u8,
15291525 flags: u32,
......@@ -1533,7 +1529,7 @@ pub fn io_uring_prep_unlinkat(
15331529}
15341530
15351531pub fn io_uring_prep_mkdirat(
1536 sqe: *io_uring_sqe,
1532 sqe: *linux.io_uring_sqe,
15371533 dir_fd: os.fd_t,
15381534 path: [*:0]const u8,
15391535 mode: os.mode_t,
......@@ -1542,7 +1538,7 @@ pub fn io_uring_prep_mkdirat(
15421538}
15431539
15441540pub fn io_uring_prep_symlinkat(
1545 sqe: *io_uring_sqe,
1541 sqe: *linux.io_uring_sqe,
15461542 target: [*:0]const u8,
15471543 new_dir_fd: os.fd_t,
15481544 link_path: [*:0]const u8,
......@@ -1558,7 +1554,7 @@ pub fn io_uring_prep_symlinkat(
15581554}
15591555
15601556pub fn io_uring_prep_linkat(
1561 sqe: *io_uring_sqe,
1557 sqe: *linux.io_uring_sqe,
15621558 old_dir_fd: os.fd_t,
15631559 old_path: [*:0]const u8,
15641560 new_dir_fd: os.fd_t,
......@@ -1578,7 +1574,7 @@ pub fn io_uring_prep_linkat(
15781574}
15791575
15801576pub fn io_uring_prep_provide_buffers(
1581 sqe: *io_uring_sqe,
1577 sqe: *linux.io_uring_sqe,
15821578 buffers: [*]u8,
15831579 num: usize,
15841580 buffer_len: usize,
......@@ -1591,7 +1587,7 @@ pub fn io_uring_prep_provide_buffers(
15911587}
15921588
15931589pub fn io_uring_prep_remove_buffers(
1594 sqe: *io_uring_sqe,
1590 sqe: *linux.io_uring_sqe,
15951591 num: usize,
15961592 group_id: usize,
15971593) void {
......@@ -1602,9 +1598,9 @@ pub fn io_uring_prep_remove_buffers(
16021598test "structs/offsets/entries" {
16031599 if (builtin.os.tag != .linux) return error.SkipZigTest;
16041600
1605 try testing.expectEqual(@as(usize, 120), @sizeOf(io_uring_params));
1606 try testing.expectEqual(@as(usize, 64), @sizeOf(io_uring_sqe));
1607 try testing.expectEqual(@as(usize, 16), @sizeOf(io_uring_cqe));
1601 try testing.expectEqual(@as(usize, 120), @sizeOf(linux.io_uring_params));
1602 try testing.expectEqual(@as(usize, 64), @sizeOf(linux.io_uring_sqe));
1603 try testing.expectEqual(@as(usize, 16), @sizeOf(linux.io_uring_cqe));
16081604
16091605 try testing.expectEqual(0, linux.IORING_OFF_SQ_RING);
16101606 try testing.expectEqual(0x8000000, linux.IORING_OFF_CQ_RING);
......@@ -1628,7 +1624,7 @@ test "nop" {
16281624 }
16291625
16301626 const sqe = try ring.nop(0xaaaaaaaa);
1631 try testing.expectEqual(io_uring_sqe{
1627 try testing.expectEqual(linux.io_uring_sqe{
16321628 .opcode = .NOP,
16331629 .flags = 0,
16341630 .ioprio = 0,
......@@ -1658,7 +1654,7 @@ test "nop" {
16581654 try testing.expectEqual(@as(u32, 0), ring.cq.head.*);
16591655 try testing.expectEqual(@as(u32, 0), ring.sq_ready());
16601656
1661 try testing.expectEqual(io_uring_cqe{
1657 try testing.expectEqual(linux.io_uring_cqe{
16621658 .user_data = 0xaaaaaaaa,
16631659 .res = 0,
16641660 .flags = 0,
......@@ -1669,7 +1665,7 @@ test "nop" {
16691665 const sqe_barrier = try ring.nop(0xbbbbbbbb);
16701666 sqe_barrier.flags |= linux.IOSQE_IO_DRAIN;
16711667 try testing.expectEqual(@as(u32, 1), try ring.submit());
1672 try testing.expectEqual(io_uring_cqe{
1668 try testing.expectEqual(linux.io_uring_cqe{
16731669 .user_data = 0xbbbbbbbb,
16741670 .res = 0,
16751671 .flags = 0,
......@@ -1909,7 +1905,7 @@ test "openat" {
19091905 const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT;
19101906 const mode: os.mode_t = 0o666;
19111907 const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode);
1912 try testing.expectEqual(io_uring_sqe{
1908 try testing.expectEqual(linux.io_uring_sqe{
19131909 .opcode = .OPENAT,
19141910 .flags = 0,
19151911 .ioprio = 0,
lib/std/os/test.zig+4-2
......@@ -766,8 +766,10 @@ test "sigaction" {
766766 }
767767 };
768768
769 const actual_handler = if (builtin.zig_backend == .stage1) S.handler else &S.handler;
770
769771 var sa = os.Sigaction{
770 .handler = .{ .sigaction = S.handler },
772 .handler = .{ .sigaction = actual_handler },
771773 .mask = os.empty_sigset,
772774 .flags = os.SA.SIGINFO | os.SA.RESETHAND,
773775 };
......@@ -776,7 +778,7 @@ test "sigaction" {
776778 try os.sigaction(os.SIG.USR1, &sa, null);
777779 // Check that we can read it back correctly.
778780 try os.sigaction(os.SIG.USR1, null, &old_sa);
779 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);
781 try testing.expectEqual(actual_handler, old_sa.handler.sigaction.?);
780782 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
781783 // Invoke the handler.
782784 try os.raise(os.SIG.USR1);
src/AstGen.zig+9-2
......@@ -291,8 +291,8 @@ pub const ResultLoc = union(enum) {
291291 }
292292};
293293
294pub const align_rl: ResultLoc = .{ .ty = .u16_type };
295pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u16_type };
294pub const align_rl: ResultLoc = .{ .ty = .u29_type };
295pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u29_type };
296296pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
297297pub const type_rl: ResultLoc = .{ .ty = .type_type };
298298pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };
......@@ -8077,6 +8077,7 @@ const primitives = std.ComptimeStringMap(Zir.Inst.Ref, .{
80778077 .{ "true", .bool_true },
80788078 .{ "type", .type_type },
80798079 .{ "u16", .u16_type },
8080 .{ "u29", .u29_type },
80808081 .{ "u32", .u32_type },
80818082 .{ "u64", .u64_type },
80828083 .{ "u128", .u128_type },
......@@ -8749,6 +8750,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
87498750 .isize_type,
87508751 .type_type,
87518752 .u16_type,
8753 .u29_type,
87528754 .u32_type,
87538755 .u64_type,
87548756 .u128_type,
......@@ -8988,6 +8990,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
89888990 .i8_type,
89898991 .isize_type,
89908992 .u16_type,
8993 .u29_type,
89918994 .u32_type,
89928995 .u64_type,
89938996 .u128_type,
......@@ -9063,6 +9066,7 @@ fn rvalue(
90639066 as_ty | @enumToInt(Zir.Inst.Ref.u8_type),
90649067 as_ty | @enumToInt(Zir.Inst.Ref.i8_type),
90659068 as_ty | @enumToInt(Zir.Inst.Ref.u16_type),
9069 as_ty | @enumToInt(Zir.Inst.Ref.u29_type),
90669070 as_ty | @enumToInt(Zir.Inst.Ref.i16_type),
90679071 as_ty | @enumToInt(Zir.Inst.Ref.u32_type),
90689072 as_ty | @enumToInt(Zir.Inst.Ref.i32_type),
......@@ -9875,6 +9879,9 @@ const GenZir = struct {
98759879 errdefer as_scope.unstack();
98769880 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
98779881
9882 // `rl_ty_inst` needs to be set in case the stores to `rl_ptr` are eliminated.
9883 as_scope.rl_ty_inst = dest_type;
9884
98789885 return as_scope;
98799886 }
98809887
src/Module.zig+1-1
......@@ -4016,7 +4016,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
40164016 try wip_captures.finalize();
40174017 const src: LazySrcLoc = .{ .node_offset = 0 };
40184018 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);
4019 const decl_align: u16 = blk: {
4019 const decl_align: u32 = blk: {
40204020 const align_ref = decl.zirAlignRef();
40214021 if (align_ref == .none) break :blk 0;
40224022 break :blk try sema.resolveAlign(&block_scope, src, align_ref);
src/Sema.zig+56-17
......@@ -1739,9 +1739,9 @@ pub fn resolveAlign(
17391739 block: *Block,
17401740 src: LazySrcLoc,
17411741 zir_ref: Zir.Inst.Ref,
1742) !u16 {
1743 const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u16));
1744 const alignment = @intCast(u16, alignment_big); // We coerce to u16 in the prev line.
1742) !u32 {
1743 const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u29));
1744 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.
17451745 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});
17461746 if (!std.math.isPowerOfTwo(alignment)) {
17471747 return sema.fail(block, src, "alignment value {d} is not a power of two", .{
......@@ -1875,7 +1875,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18751875
18761876 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
18771877 const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value);
1878 try sema.storePtr(&trash_block, src, dummy_ptr, dummy_operand);
1878 try sema.storePtr2(&trash_block, src, dummy_ptr, src, dummy_operand, src, .bitcast);
18791879
18801880 {
18811881 const air_tags = sema.air_instructions.items(.tag);
......@@ -2526,7 +2526,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
25262526 const src: LazySrcLoc = .{ .node_offset = inst_data };
25272527 try sema.requireFunctionBlock(block, src);
25282528
2529 if (block.is_comptime) {
2529 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
25302530 const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);
25312531 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0, src);
25322532 }
......@@ -2663,7 +2663,7 @@ fn zirAllocExtended(
26632663 break :blk try sema.resolveType(block, ty_src, type_ref);
26642664 } else undefined;
26652665
2666 const alignment: u16 = if (small.has_align) blk: {
2666 const alignment: u32 = if (small.has_align) blk: {
26672667 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
26682668 extra_index += 1;
26692669 const alignment = try sema.resolveAlign(block, align_src, align_ref);
......@@ -3616,7 +3616,7 @@ fn zirValidateArrayInit(
36163616 const air_tags = sema.air_instructions.items(.tag);
36173617 const air_datas = sema.air_instructions.items(.data);
36183618
3619 for (instrs) |elem_ptr, i| {
3619 outer: for (instrs) |elem_ptr, i| {
36203620 const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;
36213621 const elem_src: LazySrcLoc = .{ .node_offset = elem_ptr_data.src_node };
36223622
......@@ -3630,6 +3630,10 @@ fn zirValidateArrayInit(
36303630 // of the for loop.
36313631 var block_index = block.instructions.items.len - 1;
36323632 while (block.instructions.items[block_index] != elem_ptr_air_inst) {
3633 if (block_index == 0) {
3634 array_is_comptime = true;
3635 continue :outer;
3636 }
36333637 block_index -= 1;
36343638 }
36353639 first_block_index = @minimum(first_block_index, block_index);
......@@ -3672,6 +3676,13 @@ fn zirValidateArrayInit(
36723676 }
36733677
36743678 if (array_is_comptime) {
3679 if (try sema.resolveDefinedValue(block, init_src, array_ptr)) |ptr_val| {
3680 if (ptr_val.tag() == .comptime_field_ptr) {
3681 // This store was validated by the individual elem ptrs.
3682 return;
3683 }
3684 }
3685
36753686 // Our task is to delete all the `elem_ptr` and `store` instructions, and insert
36763687 // instead a single `store` to the array_ptr with a comptime struct value.
36773688 // Also to populate the sentinel value, if any.
......@@ -14199,7 +14210,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1419914210 .size = ptr_size,
1420014211 .mutable = !is_const_val.toBool(),
1420114212 .@"volatile" = is_volatile_val.toBool(),
14202 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
14213 .@"align" = @intCast(u29, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
1420314214 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
1420414215 .pointee_type = try child_ty.copy(sema.arena),
1420514216 .@"allowzero" = is_allowzero_val.toBool(),
......@@ -16973,7 +16984,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1697316984 const body = sema.code.extra[extra_index..][0..body_len];
1697416985 extra_index += body.len;
1697516986
16976 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u16);
16987 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29);
1697716988 if (val.tag() == .generic_poison) {
1697816989 break :blk null;
1697916990 }
......@@ -18462,14 +18473,11 @@ fn structFieldPtrByIndex(
1846218473 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
1846318474
1846418475 if (field.is_comptime) {
18465 var anon_decl = try block.startAnonDecl(field_src);
18466 defer anon_decl.deinit();
18467 const decl = try anon_decl.finish(
18468 try field.ty.copy(anon_decl.arena()),
18469 try field.default_val.copy(anon_decl.arena()),
18470 ptr_ty_data.@"align",
18471 );
18472 return sema.analyzeDeclRef(decl);
18476 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
18477 .field_ty = try field.ty.copy(sema.arena),
18478 .field_val = try field.default_val.copy(sema.arena),
18479 });
18480 return sema.addConstant(ptr_field_ty, val);
1847318481 }
1847418482
1847518483 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
......@@ -20187,6 +20195,13 @@ fn storePtr2(
2018720195
2018820196 // TODO handle if the element type requires comptime
2018920197
20198 if (air_tag == .bitcast) {
20199 // `air_tag == .bitcast` is used as a special case for `zirCoerceResultPtr`
20200 // to avoid calling `requireRuntimeBlock` for the dummy block.
20201 _ = try block.addBinOp(.store, ptr, operand);
20202 return;
20203 }
20204
2019020205 try sema.requireRuntimeBlock(block, runtime_src);
2019120206 try sema.queueFullTypeResolution(elem_ty);
2019220207 _ = try block.addBinOp(air_tag, ptr, operand);
......@@ -20240,6 +20255,14 @@ fn storePtrVal(
2024020255
2024120256 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
2024220257
20258 if (mut_kit.decl_ref_mut.runtime_index == std.math.maxInt(u32)) {
20259 // Special case for comptime field ptr.
20260 if (!mut_kit.val.eql(bitcasted_val, mut_kit.ty, sema.mod)) {
20261 return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});
20262 }
20263 return;
20264 }
20265
2024320266 const arena = mut_kit.beginArena(sema.mod);
2024420267 defer mut_kit.finishArena(sema.mod);
2024520268
......@@ -20289,6 +20312,19 @@ fn beginComptimePtrMutation(
2028920312 .ty = decl.ty,
2029020313 };
2029120314 },
20315 .comptime_field_ptr => {
20316 const payload = ptr_val.castTag(.comptime_field_ptr).?.data;
20317 const duped = try sema.arena.create(Value);
20318 duped.* = payload.field_val;
20319 return ComptimePtrMutationKit{
20320 .decl_ref_mut = .{
20321 .decl_index = @intToEnum(Module.Decl.Index, 0),
20322 .runtime_index = std.math.maxInt(u32),
20323 },
20324 .val = duped,
20325 .ty = payload.field_ty,
20326 };
20327 },
2029220328 .elem_ptr => {
2029320329 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2029420330 var parent = try beginComptimePtrMutation(sema, block, src, elem_ptr.array_ptr);
......@@ -23850,6 +23886,7 @@ pub fn typeHasOnePossibleValue(
2385023886 .i8,
2385123887 .u16,
2385223888 .i16,
23889 .u29,
2385323890 .u32,
2385423891 .i32,
2385523892 .u64,
......@@ -24143,6 +24180,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
2414324180 .u8 => return .u8_type,
2414424181 .i8 => return .i8_type,
2414524182 .u16 => return .u16_type,
24183 .u29 => return .u29_type,
2414624184 .i16 => return .i16_type,
2414724185 .u32 => return .u32_type,
2414824186 .i32 => return .i32_type,
......@@ -24513,6 +24551,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
2451324551 .i8,
2451424552 .u16,
2451524553 .i16,
24554 .u29,
2451624555 .u32,
2451724556 .i32,
2451824557 .u64,
src/TypedValue.zig+11
......@@ -79,6 +79,7 @@ pub fn print(
7979 .i8_type => return writer.writeAll("i8"),
8080 .u16_type => return writer.writeAll("u16"),
8181 .i16_type => return writer.writeAll("i16"),
82 .u29_type => return writer.writeAll("u29"),
8283 .u32_type => return writer.writeAll("u32"),
8384 .i32_type => return writer.writeAll("i32"),
8485 .u64_type => return writer.writeAll("u64"),
......@@ -264,6 +265,16 @@ pub fn print(
264265 .val = decl.val,
265266 }, writer, level - 1, mod);
266267 },
268 .comptime_field_ptr => {
269 const payload = val.castTag(.comptime_field_ptr).?.data;
270 if (level == 0) {
271 return writer.writeAll("(comptime field ptr)");
272 }
273 return print(.{
274 .ty = payload.field_ty,
275 .val = payload.field_val,
276 }, writer, level - 1, mod);
277 },
267278 .elem_ptr => {
268279 const elem_ptr = val.castTag(.elem_ptr).?.data;
269280 try writer.writeAll("&");
src/Zir.zig+5
......@@ -1961,6 +1961,7 @@ pub const Inst = struct {
19611961 i8_type,
19621962 u16_type,
19631963 i16_type,
1964 u29_type,
19641965 u32_type,
19651966 i32_type,
19661967 u64_type,
......@@ -2072,6 +2073,10 @@ pub const Inst = struct {
20722073 .ty = Type.initTag(.type),
20732074 .val = Value.initTag(.i16_type),
20742075 },
2076 .u29_type = .{
2077 .ty = Type.initTag(.type),
2078 .val = Value.initTag(.u29_type),
2079 },
20752080 .u32_type = .{
20762081 .ty = Type.initTag(.type),
20772082 .val = Value.initTag(.u32_type),
src/type.zig+20
......@@ -36,6 +36,7 @@ pub const Type = extern union {
3636 .i8,
3737 .u16,
3838 .i16,
39 .u29,
3940 .u32,
4041 .i32,
4142 .u64,
......@@ -568,6 +569,7 @@ pub const Type = extern union {
568569 .i8,
569570 .u16,
570571 .i16,
572 .u29,
571573 .u32,
572574 .i32,
573575 .u64,
......@@ -979,6 +981,7 @@ pub const Type = extern union {
979981 .i8,
980982 .u16,
981983 .i16,
984 .u29,
982985 .u32,
983986 .i32,
984987 .u64,
......@@ -1261,6 +1264,7 @@ pub const Type = extern union {
12611264 .i8,
12621265 .u16,
12631266 .i16,
1267 .u29,
12641268 .u32,
12651269 .i32,
12661270 .u64,
......@@ -1551,6 +1555,7 @@ pub const Type = extern union {
15511555 .i8,
15521556 .u16,
15531557 .i16,
1558 .u29,
15541559 .u32,
15551560 .i32,
15561561 .u64,
......@@ -1935,6 +1940,7 @@ pub const Type = extern union {
19351940 .i8,
19361941 .u16,
19371942 .i16,
1943 .u29,
19381944 .u32,
19391945 .i32,
19401946 .u64,
......@@ -2235,6 +2241,7 @@ pub const Type = extern union {
22352241 .u8 => return Value.initTag(.u8_type),
22362242 .i8 => return Value.initTag(.i8_type),
22372243 .u16 => return Value.initTag(.u16_type),
2244 .u29 => return Value.initTag(.u29_type),
22382245 .i16 => return Value.initTag(.i16_type),
22392246 .u32 => return Value.initTag(.u32_type),
22402247 .i32 => return Value.initTag(.i32_type),
......@@ -2312,6 +2319,7 @@ pub const Type = extern union {
23122319 .i8,
23132320 .u16,
23142321 .i16,
2322 .u29,
23152323 .u32,
23162324 .i32,
23172325 .u64,
......@@ -2560,6 +2568,7 @@ pub const Type = extern union {
25602568 .i8,
25612569 .u16,
25622570 .i16,
2571 .u29,
25632572 .u32,
25642573 .i32,
25652574 .u64,
......@@ -2953,6 +2962,7 @@ pub const Type = extern union {
29532962 .vector => return AbiAlignmentAdvanced{ .scalar = 16 },
29542963
29552964 .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
2965 .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
29562966 .i32, .u32 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(32, target) },
29572967 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },
29582968 .u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },
......@@ -3416,6 +3426,7 @@ pub const Type = extern union {
34163426 },
34173427
34183428 .i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },
3429 .u29 => return AbiSizeAdvanced{ .scalar = intAbiSize(29, target) },
34193430 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
34203431 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },
34213432 .u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },
......@@ -3569,6 +3580,7 @@ pub const Type = extern union {
35693580 .bool, .u1 => 1,
35703581 .u8, .i8 => 8,
35713582 .i16, .u16, .f16 => 16,
3583 .u29 => 29,
35723584 .i32, .u32, .f32 => 32,
35733585 .i64, .u64, .f64 => 64,
35743586 .f80 => 80,
......@@ -4524,6 +4536,7 @@ pub const Type = extern union {
45244536 .u1,
45254537 .u8,
45264538 .u16,
4539 .u29,
45274540 .u32,
45284541 .u64,
45294542 .u128,
......@@ -4550,6 +4563,7 @@ pub const Type = extern union {
45504563 .i8 => return .{ .signedness = .signed, .bits = 8 },
45514564 .u16 => return .{ .signedness = .unsigned, .bits = 16 },
45524565 .i16 => return .{ .signedness = .signed, .bits = 16 },
4566 .u29 => return .{ .signedness = .unsigned, .bits = 29 },
45534567 .u32 => return .{ .signedness = .unsigned, .bits = 32 },
45544568 .i32 => return .{ .signedness = .signed, .bits = 32 },
45554569 .u64 => return .{ .signedness = .unsigned, .bits = 64 },
......@@ -4814,6 +4828,7 @@ pub const Type = extern union {
48144828 .i8,
48154829 .u16,
48164830 .i16,
4831 .u29,
48174832 .u32,
48184833 .i32,
48194834 .u64,
......@@ -4856,6 +4871,7 @@ pub const Type = extern union {
48564871 .i8,
48574872 .u16,
48584873 .i16,
4874 .u29,
48594875 .u32,
48604876 .i32,
48614877 .u64,
......@@ -5072,6 +5088,7 @@ pub const Type = extern union {
50725088 .i8,
50735089 .u16,
50745090 .i16,
5091 .u29,
50755092 .u32,
50765093 .i32,
50775094 .u64,
......@@ -5816,6 +5833,7 @@ pub const Type = extern union {
58165833 i8,
58175834 u16,
58185835 i16,
5836 u29,
58195837 u32,
58205838 i32,
58215839 u64,
......@@ -5939,6 +5957,7 @@ pub const Type = extern union {
59395957 .i8,
59405958 .u16,
59415959 .i16,
5960 .u29,
59425961 .u32,
59435962 .i32,
59445963 .u64,
......@@ -6302,6 +6321,7 @@ pub const Type = extern union {
63026321 pub const @"u1" = initTag(.u1);
63036322 pub const @"u8" = initTag(.u8);
63046323 pub const @"u16" = initTag(.u16);
6324 pub const @"u29" = initTag(.u29);
63056325 pub const @"u32" = initTag(.u32);
63066326 pub const @"u64" = initTag(.u64);
63076327
src/value.zig+50-4
......@@ -30,6 +30,7 @@ pub const Value = extern union {
3030 i8_type,
3131 u16_type,
3232 i16_type,
33 u29_type,
3334 u32_type,
3435 i32_type,
3536 u64_type,
......@@ -120,6 +121,8 @@ pub const Value = extern union {
120121 /// This Tag will never be seen by machine codegen backends. It is changed into a
121122 /// `decl_ref` when a comptime variable goes out of scope.
122123 decl_ref_mut,
124 /// Behaves like `decl_ref_mut` but validates that the stored value matches the field value.
125 comptime_field_ptr,
123126 /// Pointer to a specific element of an array, vector or slice.
124127 elem_ptr,
125128 /// Pointer to a specific field of a struct or union.
......@@ -194,6 +197,7 @@ pub const Value = extern union {
194197 .i8_type,
195198 .u16_type,
196199 .i16_type,
200 .u29_type,
197201 .u32_type,
198202 .i32_type,
199203 .u64_type,
......@@ -316,6 +320,7 @@ pub const Value = extern union {
316320 .aggregate => Payload.Aggregate,
317321 .@"union" => Payload.Union,
318322 .bound_fn => Payload.BoundFn,
323 .comptime_field_ptr => Payload.ComptimeFieldPtr,
319324 };
320325 }
321326
......@@ -394,6 +399,7 @@ pub const Value = extern union {
394399 .i8_type,
395400 .u16_type,
396401 .i16_type,
402 .u29_type,
397403 .u32_type,
398404 .i32_type,
399405 .u64_type,
......@@ -506,6 +512,18 @@ pub const Value = extern union {
506512 };
507513 return Value{ .ptr_otherwise = &new_payload.base };
508514 },
515 .comptime_field_ptr => {
516 const payload = self.cast(Payload.ComptimeFieldPtr).?;
517 const new_payload = try arena.create(Payload.ComptimeFieldPtr);
518 new_payload.* = .{
519 .base = payload.base,
520 .data = .{
521 .field_val = try payload.data.field_val.copy(arena),
522 .field_ty = try payload.data.field_ty.copy(arena),
523 },
524 };
525 return Value{ .ptr_otherwise = &new_payload.base };
526 },
509527 .elem_ptr => {
510528 const payload = self.castTag(.elem_ptr).?;
511529 const new_payload = try arena.create(Payload.ElemPtr);
......@@ -645,6 +663,7 @@ pub const Value = extern union {
645663 .u8_type => return out_stream.writeAll("u8"),
646664 .i8_type => return out_stream.writeAll("i8"),
647665 .u16_type => return out_stream.writeAll("u16"),
666 .u29_type => return out_stream.writeAll("u29"),
648667 .i16_type => return out_stream.writeAll("i16"),
649668 .u32_type => return out_stream.writeAll("u32"),
650669 .i32_type => return out_stream.writeAll("i32"),
......@@ -754,6 +773,9 @@ pub const Value = extern union {
754773 const decl_index = val.castTag(.decl_ref).?.data;
755774 return out_stream.print("(decl_ref {d})", .{decl_index});
756775 },
776 .comptime_field_ptr => {
777 return out_stream.writeAll("(comptime_field_ptr)");
778 },
757779 .elem_ptr => {
758780 const elem_ptr = val.castTag(.elem_ptr).?.data;
759781 try out_stream.print("&[{}] ", .{elem_ptr.index});
......@@ -882,6 +904,7 @@ pub const Value = extern union {
882904 .i8_type => Type.initTag(.i8),
883905 .u16_type => Type.initTag(.u16),
884906 .i16_type => Type.initTag(.i16),
907 .u29_type => Type.initTag(.u29),
885908 .u32_type => Type.initTag(.u32),
886909 .i32_type => Type.initTag(.i32),
887910 .u64_type => Type.initTag(.u64),
......@@ -1706,6 +1729,7 @@ pub const Value = extern union {
17061729 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
17071730
17081731 .decl_ref_mut,
1732 .comptime_field_ptr,
17091733 .extern_fn,
17101734 .decl_ref,
17111735 .function,
......@@ -1770,6 +1794,7 @@ pub const Value = extern union {
17701794 .bool_true,
17711795 .decl_ref,
17721796 .decl_ref_mut,
1797 .comptime_field_ptr,
17731798 .extern_fn,
17741799 .function,
17751800 .variable,
......@@ -2362,7 +2387,7 @@ pub const Value = extern union {
23622387
23632388 pub fn isComptimeMutablePtr(val: Value) bool {
23642389 return switch (val.tag()) {
2365 .decl_ref_mut => true,
2390 .decl_ref_mut, .comptime_field_ptr => true,
23662391 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
23672392 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
23682393 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
......@@ -2426,6 +2451,9 @@ pub const Value = extern union {
24262451 const decl: Module.Decl.Index = ptr_val.pointerDecl().?;
24272452 std.hash.autoHash(hasher, decl);
24282453 },
2454 .comptime_field_ptr => {
2455 std.hash.autoHash(hasher, Value.Tag.comptime_field_ptr);
2456 },
24292457
24302458 .elem_ptr => {
24312459 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
......@@ -2471,7 +2499,7 @@ pub const Value = extern union {
24712499 return switch (val.tag()) {
24722500 .slice => val.castTag(.slice).?.data.ptr,
24732501 // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc.
2474 .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr => val,
2502 .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr, .comptime_field_ptr => val,
24752503 else => unreachable,
24762504 };
24772505 }
......@@ -2497,6 +2525,14 @@ pub const Value = extern union {
24972525 return 1;
24982526 }
24992527 },
2528 .comptime_field_ptr => {
2529 const payload = val.castTag(.comptime_field_ptr).?.data;
2530 if (payload.field_ty.zigTypeTag() == .Array) {
2531 return payload.field_ty.arrayLen();
2532 } else {
2533 return 1;
2534 }
2535 },
25002536 else => unreachable,
25012537 };
25022538 }
......@@ -2587,6 +2623,7 @@ pub const Value = extern union {
25872623
25882624 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),
25892625 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),
2626 .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer),
25902627 .elem_ptr => {
25912628 const data = val.castTag(.elem_ptr).?.data;
25922629 return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);
......@@ -2623,6 +2660,7 @@ pub const Value = extern union {
26232660
26242661 .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end),
26252662 .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end),
2663 .comptime_field_ptr => sliceArray(val.castTag(.comptime_field_ptr).?.data.field_val, mod, arena, start, end),
26262664 .elem_ptr => blk: {
26272665 const elem_ptr = val.castTag(.elem_ptr).?.data;
26282666 break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index);
......@@ -4742,6 +4780,14 @@ pub const Value = extern union {
47424780 },
47434781 };
47444782
4783 pub const ComptimeFieldPtr = struct {
4784 base: Payload,
4785 data: struct {
4786 field_val: Value,
4787 field_ty: Type,
4788 },
4789 };
4790
47454791 pub const ElemPtr = struct {
47464792 pub const base_tag = Tag.elem_ptr;
47474793
......@@ -4864,7 +4910,7 @@ pub const Value = extern union {
48644910 /// `Module.resolvePeerTypes`.
48654911 stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
48664912 /// 0 means ABI-aligned.
4867 alignment: u16,
4913 alignment: u32,
48684914 },
48694915 };
48704916
......@@ -4875,7 +4921,7 @@ pub const Value = extern union {
48754921 data: struct {
48764922 decl_index: Module.Decl.Index,
48774923 /// 0 means ABI-aligned.
4878 alignment: u16,
4924 alignment: u32,
48794925 },
48804926 };
48814927
test/behavior/basic.zig+33
......@@ -1,5 +1,6 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const assert = std.debug.assert;
34const mem = std.mem;
45const expect = std.testing.expect;
56const expectEqualStrings = std.testing.expectEqualStrings;
......@@ -1053,3 +1054,35 @@ test "const alloc with comptime known initializer is made comptime known" {
10531054 if (u.a == 0) @compileError("bad");
10541055 }
10551056}
1057
1058comptime {
1059 // coerce result ptr outside a function
1060 const S = struct { a: comptime_int };
1061 var s: S = undefined;
1062 s = S{ .a = 1 };
1063 assert(s.a == 1);
1064}
1065
1066test "switch inside @as gets correct type" {
1067 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1068 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1069
1070 var a: u32 = 0;
1071 var b: [2]u32 = undefined;
1072 b[0] = @as(u32, switch (a) {
1073 1 => 1,
1074 else => 0,
1075 });
1076}
1077
1078test "inline call of function with a switch inside the return statement" {
1079 const S = struct {
1080 inline fn foo(x: anytype) @TypeOf(x) {
1081 return switch (x) {
1082 1 => 1,
1083 else => unreachable,
1084 };
1085 }
1086 };
1087 try expect(S.foo(1) == 1);
1088}
test/behavior/struct.zig+22
......@@ -1336,3 +1336,25 @@ test "packed struct field access via pointer" {
13361336 try S.doTheTest();
13371337 comptime try S.doTheTest();
13381338}
1339
1340test "store to comptime field" {
1341 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1342
1343 {
1344 const S = struct {
1345 comptime a: [2]u32 = [2]u32{ 1, 2 },
1346 };
1347 var s: S = .{};
1348 s.a = [2]u32{ 1, 2 };
1349 s.a[0] = 1;
1350 }
1351 {
1352 const T = struct { a: u32, b: u32 };
1353 const S = struct {
1354 comptime a: T = T{ .a = 1, .b = 2 },
1355 };
1356 var s: S = .{};
1357 s.a = T{ .a = 1, .b = 2 };
1358 s.a.a = 1;
1359 }
1360}
test/cases/compile_errors/invalid_store_to_comptime_field.zig created+20
......@@ -0,0 +1,20 @@
1pub export fn entry() void {
2 const S = struct {
3 comptime a: [2]u32 = [2]u32{ 1, 2 },
4 };
5 var s: S = .{};
6 s.a = [2]u32{ 2, 2 };
7}
8pub export fn entry1() void {
9 const T = struct { a: u32, b: u32 };
10 const S = struct {
11 comptime a: T = T{ .a = 1, .b = 2 },
12 };
13 var s: S = .{};
14 s.a = T{ .a = 2, .b = 2 };
15}
16// error
17// backend=stage2,llvm
18//
19// :6:19: error: value stored in comptime field does not match the default value of the field
20// :14:19: error: value stored in comptime field does not match the default value of the field