From bb6ad1a6c21694b4ea9340c552962b5ea60712e4 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Sun, 3 Nov 2019 21:09:51 -0600
Subject: [PATCH 001/129] Remove StaticallyInitializedMutex
---
lib/std/statically_initialized_mutex.zig | 105 -----------------------
lib/std/std.zig | 1 -
2 files changed, 106 deletions(-)
delete mode 100644 lib/std/statically_initialized_mutex.zig
diff --git a/lib/std/statically_initialized_mutex.zig b/lib/std/statically_initialized_mutex.zig
deleted file mode 100644
index 2ad47b5d91..0000000000
--- a/lib/std/statically_initialized_mutex.zig
+++ /dev/null
@@ -1,105 +0,0 @@
-const std = @import("std.zig");
-const builtin = @import("builtin");
-const AtomicOrder = builtin.AtomicOrder;
-const AtomicRmwOp = builtin.AtomicRmwOp;
-const assert = std.debug.assert;
-const expect = std.testing.expect;
-const windows = std.os.windows;
-
-/// Lock may be held only once. If the same thread
-/// tries to acquire the same mutex twice, it deadlocks.
-/// This type is intended to be initialized statically. If you don't
-/// require static initialization, use std.Mutex.
-/// On Windows, this mutex allocates resources when it is
-/// first used, and the resources cannot be freed.
-/// On Linux, this is an alias of std.Mutex.
-pub const StaticallyInitializedMutex = switch (builtin.os) {
- builtin.Os.linux => std.Mutex,
- builtin.Os.windows => struct {
- lock: windows.CRITICAL_SECTION,
- init_once: windows.RTL_RUN_ONCE,
-
- pub const Held = struct {
- mutex: *StaticallyInitializedMutex,
-
- pub fn release(self: Held) void {
- windows.kernel32.LeaveCriticalSection(&self.mutex.lock);
- }
- };
-
- pub fn init() StaticallyInitializedMutex {
- return StaticallyInitializedMutex{
- .lock = undefined,
- .init_once = windows.INIT_ONCE_STATIC_INIT,
- };
- }
-
- extern fn initCriticalSection(
- InitOnce: *windows.RTL_RUN_ONCE,
- Parameter: ?*c_void,
- Context: ?*c_void,
- ) windows.BOOL {
- const lock = @ptrCast(*windows.CRITICAL_SECTION, @alignCast(@alignOf(windows.CRITICAL_SECTION), Parameter));
- windows.kernel32.InitializeCriticalSection(lock);
- return windows.TRUE;
- }
-
- /// TODO: once https://github.com/ziglang/zig/issues/287 is solved and std.Mutex has a better
- /// implementation of a runtime initialized mutex, remove this function.
- pub fn deinit(self: *StaticallyInitializedMutex) void {
- windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
- windows.kernel32.DeleteCriticalSection(&self.lock);
- }
-
- pub fn acquire(self: *StaticallyInitializedMutex) Held {
- windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
- windows.kernel32.EnterCriticalSection(&self.lock);
- return Held{ .mutex = self };
- }
- },
- else => std.Mutex,
-};
-
-test "std.StaticallyInitializedMutex" {
- const TestContext = struct {
- data: i128,
-
- const TestContext = @This();
- const incr_count = 10000;
-
- var mutex = StaticallyInitializedMutex.init();
-
- fn worker(ctx: *TestContext) void {
- var i: usize = 0;
- while (i != TestContext.incr_count) : (i += 1) {
- const held = mutex.acquire();
- defer held.release();
-
- ctx.data += 1;
- }
- }
- };
-
- var plenty_of_memory = try std.heap.direct_allocator.alloc(u8, 300 * 1024);
- defer std.heap.direct_allocator.free(plenty_of_memory);
-
- var fixed_buffer_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(plenty_of_memory);
- var a = &fixed_buffer_allocator.allocator;
-
- var context = TestContext{ .data = 0 };
-
- if (builtin.single_threaded) {
- TestContext.worker(&context);
- expect(context.data == TestContext.incr_count);
- } else {
- const thread_count = 10;
- var threads: [thread_count]*std.Thread = undefined;
- for (threads) |*t| {
- t.* = try std.Thread.spawn(&context, TestContext.worker);
- }
- for (threads) |t|
- t.wait();
-
- expect(context.data == thread_count * TestContext.incr_count);
- }
-}
diff --git a/lib/std/std.zig b/lib/std/std.zig
index ea6257009f..8ba67e79a2 100644
--- a/lib/std/std.zig
+++ b/lib/std/std.zig
@@ -19,7 +19,6 @@ pub const Progress = @import("progress.zig").Progress;
pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
pub const SpinLock = @import("spinlock.zig").SpinLock;
-pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
pub const StringHashMap = @import("hash_map.zig").StringHashMap;
pub const TailQueue = @import("linked_list.zig").TailQueue;
pub const Target = @import("target.zig").Target;
From 0d4f4aad9e44043b329de0f2e556c3b61cdaafa9 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 08:16:08 -0600
Subject: [PATCH 002/129] adaptive SpinLock
---
lib/std/os/windows/kernel32.zig | 2 ++
lib/std/spinlock.zig | 41 +++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig
index 736d81ae58..d466f9946d 100644
--- a/lib/std/os/windows/kernel32.zig
+++ b/lib/std/os/windows/kernel32.zig
@@ -184,6 +184,8 @@ pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask:
pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
+pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL;
+
pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD;
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 905460a2d0..894acd0fc4 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -1,8 +1,9 @@
const std = @import("std.zig");
const builtin = @import("builtin");
-const AtomicOrder = builtin.AtomicOrder;
-const AtomicRmwOp = builtin.AtomicRmwOp;
const assert = std.debug.assert;
+const time = std.time;
+const linux = std.os.linux;
+const windows = std.os.windows;
pub const SpinLock = struct {
lock: u8, // TODO use a bool or enum
@@ -11,7 +12,8 @@ pub const SpinLock = struct {
spinlock: *SpinLock,
pub fn release(self: Held) void {
- assert(@atomicRmw(u8, &self.spinlock.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
+ // TODO: @atomicStore() https://github.com/ziglang/zig/issues/2995
+ assert(@atomicRmw(u8, &self.spinlock.lock, .Xchg, 0, .Release) == 1);
}
};
@@ -19,10 +21,41 @@ pub const SpinLock = struct {
return SpinLock{ .lock = 0 };
}
+ // Hybrid spinning from
+ // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
pub fn acquire(self: *SpinLock) Held {
- while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
+ var backoff: usize = 0;
+ while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0) : (backoff +%= 1) {
+ if (backoff < 10) {
+ yieldCpu();
+ } else if (backoff < 20) {
+ for (([30]void)(undefined)) |_| yieldCpu();
+ } else if (backoff < 24) {
+ yieldThread();
+ } else if (backoff < 26) {
+ time.sleep(1 * time.millisecond);
+ } else {
+ time.sleep(10 * time.millisecond);
+ }
+ }
return Held{ .spinlock = self };
}
+
+ fn yieldCpu() void {
+ switch (builtin.arch) {
+ .i386, .x86_64 => asm volatile("pause" ::: "memory"),
+ .arm, .aarch64 => asm volatile("yield"),
+ else => time.sleep(0),
+ }
+ }
+
+ fn yieldThread() void {
+ switch (builtin.os) {
+ .linux => assert(linux.syscall0(linux.SYS_sched_yield) == 0),
+ .windows => _ = windows.kernel32.SwitchToThread(),
+ else => time.sleep(1 * time.microsecond),
+ }
+ }
};
test "spinlock" {
From 84e370d0b2ce2240356ebd0a6007aec8620dfa10 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 09:31:29 -0600
Subject: [PATCH 003/129] Move hybrid yielding into its own struct
---
lib/std/spinlock.zig | 44 ++++++++++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 894acd0fc4..8a485ef0fe 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -21,23 +21,10 @@ pub const SpinLock = struct {
return SpinLock{ .lock = 0 };
}
- // Hybrid spinning from
- // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
pub fn acquire(self: *SpinLock) Held {
- var backoff: usize = 0;
- while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0) : (backoff +%= 1) {
- if (backoff < 10) {
- yieldCpu();
- } else if (backoff < 20) {
- for (([30]void)(undefined)) |_| yieldCpu();
- } else if (backoff < 24) {
- yieldThread();
- } else if (backoff < 26) {
- time.sleep(1 * time.millisecond);
- } else {
- time.sleep(10 * time.millisecond);
- }
- }
+ var backoff = Backoff.init();
+ while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0)
+ backoff.yield();
return Held{ .spinlock = self };
}
@@ -56,6 +43,31 @@ pub const SpinLock = struct {
else => time.sleep(1 * time.microsecond),
}
}
+
+ const Backoff = struct {
+ iteration: usize,
+
+ fn init() @This() {
+ return @This(){ .iteration = 0 };
+ }
+
+ // Hybrid yielding from
+ // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
+ fn yield(self: *@This()) void {
+ defer self.iteration +%= 1;
+ if (self.iteration < 10) {
+ yieldCpu();
+ } else if (self.iteration < 20) {
+ for (([30]void)(undefined)) |_| yieldCpu();
+ } else if (self.iteration < 24) {
+ yieldThread();
+ } else if (self.iteration < 26) {
+ time.sleep(1 * time.millisecond);
+ } else {
+ time.sleep(10 * time.millisecond);
+ }
+ }
+ };
};
test "spinlock" {
From 14209cf615f2c218319e0c7a567484caf328dfe6 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 13:43:17 -0600
Subject: [PATCH 004/129] make SpinLock.Backoff pub
---
lib/std/spinlock.zig | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 8a485ef0fe..c45778cec1 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -44,16 +44,17 @@ pub const SpinLock = struct {
}
}
- const Backoff = struct {
+ /// Provides a method to incrementally yield longer each time its called.
+ pub const Backoff = struct {
iteration: usize,
- fn init() @This() {
+ pub fn init() @This() {
return @This(){ .iteration = 0 };
}
- // Hybrid yielding from
- // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
- fn yield(self: *@This()) void {
+ /// Hybrid yielding from
+ /// http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
+ pub fn yield(self: *@This()) void {
defer self.iteration +%= 1;
if (self.iteration < 10) {
yieldCpu();
From 465ebf494df070ddb7eab9ba7787aacec394b1cc Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 15:58:58 -0600
Subject: [PATCH 005/129] ThreadParker implementation
---
lib/std/os/windows/kernel32.zig | 4 +
lib/std/os/windows/ntdll.zig | 18 ++
lib/std/parker.zig | 340 ++++++++++++++++++++++++++++++++
lib/std/std.zig | 1 +
4 files changed, 363 insertions(+)
create mode 100644 lib/std/parker.zig
diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig
index d466f9946d..97c5a5b695 100644
--- a/lib/std/os/windows/kernel32.zig
+++ b/lib/std/os/windows/kernel32.zig
@@ -82,6 +82,8 @@ pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR
pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD;
+pub extern "kernel32" stdcallcc fn GetModuleHandleA(lpModuleName: ?[*]const CHAR) ?HMODULE;
+
pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE;
pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
@@ -204,6 +206,8 @@ pub extern "kernel32" stdcallcc fn WriteFile(
pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL;
+pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: [*]const u8) ?HMODULE;
+
pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE;
pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC;
diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig
index f914920093..293891123e 100644
--- a/lib/std/os/windows/ntdll.zig
+++ b/lib/std/os/windows/ntdll.zig
@@ -43,3 +43,21 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(
FileName: ?*UNICODE_STRING,
RestartScan: BOOLEAN,
) NTSTATUS;
+pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent(
+ KeyedEventHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: ?PVOID,
+ Flags: ULONG,
+) NTSTATUS;
+pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent(
+ EventHandle: HANDLE,
+ Key: *const c_void,
+ Alertable: BOOLEAN,
+ Timeout: ?*LARGE_INTEGER,
+) NTSTATUS;
+pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent(
+ EventHandle: HANDLE,
+ Key: *const c_void,
+ Alertable: BOOLEAN,
+ Timeout: ?*LARGE_INTEGER,
+) NTSTATUS;
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
new file mode 100644
index 0000000000..b6945fa000
--- /dev/null
+++ b/lib/std/parker.zig
@@ -0,0 +1,340 @@
+const std = @import("std.zig");
+const builtin = @import("builtin");
+const testing = std.testing;
+const assert = std.debug.assert;
+const SpinLock = std.SpinLock;
+const linux = std.os.linux;
+const windows = std.os.windows;
+
+pub const ThreadParker = switch (builtin.os) {
+ .macosx,
+ .tvos,
+ .ios,
+ .watchos,
+ .netbsd,
+ .openbsd,
+ .freebsd,
+ .kfreebsd,
+ .dragonfly,
+ .haiku,
+ .hermit,
+ .solaris,
+ .minix,
+ .fuchsia,
+ .emscripten => if (builtin.link_libc) PosixParker else SpinParker,
+ .linux => if (builtin.link_libc) PosixParker else LinuxParker,
+ .windows => WindowsParker,
+ else => SpinParker,
+};
+
+const SpinParker = struct {
+ pub fn init() SpinParker {
+ return SpinParker{};
+ }
+ pub fn deinit(self: *SpinParker) void {}
+
+ pub fn unpark(self: *SpinParker, ptr: *const u32) void {}
+
+ pub fn park(self: *SpinParker, ptr: *const u32, expected: u32) void {
+ var backoff = SpinLock.Backoff.init();
+ while (@atomicLoad(u32, ptr, .Acquire) == expected)
+ backoff.yield();
+ }
+};
+
+const LinuxParker = struct {
+ pub fn init() LinuxParker {
+ return LinuxParker{};
+ }
+ pub fn deinit(self: *LinuxParker) void {}
+
+ pub fn unpark(self: *LinuxParker, ptr: *const u32) void {
+ const rc = linux.futex_wake(@ptrCast(*const i32, ptr), linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, 1);
+ assert(linux.getErrno(rc) == 0);
+ }
+
+ pub fn park(self: *LinuxParker, ptr: *const u32, expected: u32) void {
+ const value = @intCast(i32, expected);
+ while (@atomicLoad(u32, ptr, .Acquire) == expected) {
+ const rc = linux.futex_wait(@ptrCast(*const i32, ptr), linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, value, null);
+ switch (linux.getErrno(rc)) {
+ 0, linux.EAGAIN => return,
+ linux.EINTR => continue,
+ linux.EINVAL => unreachable,
+ else => unreachable,
+ }
+ }
+ }
+};
+
+const WindowsParker = struct {
+ waiters: u32,
+
+ pub fn init() WindowsParker {
+ return WindowsParker{ .waiters = 0 };
+ }
+ pub fn deinit(self: *WindowsParker) void {}
+
+ pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
+ switch (Backend.get().*) {
+ .WaitAddress => |*backend| backend.unpark(ptr, &self.waiters),
+ .KeyedEvent => |*backend| backend.unpark(ptr, &self.waiters),
+ }
+ }
+
+ pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
+ switch (Backend.get().*) {
+ .WaitAddress => |*backend| backend.park(ptr, expected, &self.waiters),
+ .KeyedEvent => |*backend| backend.park(ptr, expected, &self.waiters),
+ }
+ }
+
+ const Backend = union(enum) {
+ WaitAddress: WaitAddress,
+ KeyedEvent: KeyedEvent,
+
+ var backend = std.lazyInit(Backend);
+
+ fn get() *const Backend {
+ return backend.get() orelse {
+ // Statically linking to the KeyedEvent functions should mean its supported.
+ // TODO: Maybe add a CreateSemaphore backend for systems older than Windows XP ?
+ backend.data = WaitAddress.init()
+ orelse KeyedEvent.init()
+ orelse unreachable;
+ backend.resolve();
+ return &backend.data;
+ };
+ }
+
+ const WaitAddress = struct {
+ WakeByAddressSingle: stdcallcc fn(Address: *const c_void) void,
+ WaitOnAddress: stdcallcc fn (
+ Address: *const c_void,
+ CompareAddress: *const c_void,
+ AddressSize: windows.SIZE_T,
+ dwMilliseconds: windows.DWORD,
+ ) windows.BOOL,
+
+ fn init() ?Backend {
+ const dll_name = c"api-ms-win-core-synch-l1-2-0";
+ const dll = windows.kernel32.GetModuleHandleA(dll_name)
+ orelse windows.kernel32.LoadLibraryA(dll_name)
+ orelse return null;
+
+ var self: WaitAddress = undefined;
+ const WaitOnAddress = windows.kernel32.GetProcAddress(dll, c"WaitOnAddress") orelse return null;
+ self.WaitOnAddress = @intToPtr(@typeOf(self.WaitOnAddress), @ptrToInt(WaitOnAddress));
+ const WakeByAddressSingle = windows.kernel32.GetProcAddress(dll, c"WakeByAddressSingle") orelse return null;
+ self.WakeByAddressSingle = @intToPtr(@typeOf(self.WakeByAddressSingle), @ptrToInt(WakeByAddressSingle));
+ return Backend{ .WaitAddress = self };
+ }
+
+ fn unpark(self: WaitAddress, ptr: *const u32, waiters: *u32) void {
+ const addr = @ptrCast(*const c_void, ptr);
+ self.WakeByAddressSingle(addr);
+ }
+
+ fn park(self: WaitAddress, ptr: *const u32, expected: u32, waiters: *u32) void {
+ var compare = expected;
+ const addr = @ptrCast(*const c_void, ptr);
+ const cmp = @ptrCast(*const c_void, &compare);
+ while (@atomicLoad(u32, ptr, .Acquire) == expected)
+ _ = self.WaitOnAddress(addr, cmp, @sizeOf(u32), windows.INFINITE);
+ }
+ };
+
+ const KeyedEvent = struct {
+ handle: windows.HANDLE,
+
+ fn init() ?Backend {
+ var self: KeyedEvent = undefined;
+ const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
+ if (windows.ntdll.NtCreateKeyedEvent(&self.handle, access_mask, null, 0) != 0)
+ return null;
+ return Backend{ .KeyedEvent = self };
+ }
+
+ fn unpark(self: KeyedEvent, ptr: *const u32, waiters: *u32) void {
+ const key = @ptrCast(*const c_void, ptr);
+ var waiting = @atomicLoad(u32, waiters, .Acquire);
+ while (waiting != 0) {
+ waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - 1, .AcqRel, .Monotonic) orelse {
+ const rc = windows.ntdll.NtReleaseKeyedEvent(self.handle, key, windows.FALSE, null);
+ assert(rc == 0);
+ return;
+ };
+ }
+ }
+
+ fn park(self: KeyedEvent, ptr: *const u32, expected: u32, waiters: *u32) void {
+ const key = @ptrCast(*const c_void, ptr);
+ while (@atomicLoad(u32, ptr, .Acquire) == expected) {
+ _ = @atomicRmw(u32, waiters, .Add, 1, .Release);
+ const rc = windows.ntdll.NtWaitForKeyedEvent(self.handle, key, windows.FALSE, null);
+ assert(rc == 0);
+ }
+ }
+ };
+ };
+};
+
+const PosixParker = struct {
+ cond: pthread_cond_t,
+ mutex: pthread_mutex_t,
+
+ pub fn init() PosixParker {
+ return PosixParker{
+ .cond = PTHREAD_COND_INITIALIZER,
+ .mutex = PTHREAD_MUTEX_INITIALIZER,
+ };
+ }
+
+ pub fn deinit(self: *PosixParker) void {
+ // On dragonfly, the destroy functions return EINVAL if they were initialized statically.
+ const retm = pthread_mutex_destroy(&self.mutex);
+ assert(retm == 0 or retm == (if (builtin.os == .dragonfly) os.EINVAL else 0));
+ const retc = pthread_cond_destroy(&self.cond);
+ assert(retc == 0 or retc == (if (builtin.os == .dragonfly) os.EINVAL else 0));
+ }
+
+ pub fn unpark(self: *PosixParker, ptr: *const u32) void {
+ assert(pthread_cond_signal(&self.cond) == 0);
+ }
+
+ pub fn park(self: *PosixParker, ptr: *const u32, expected: u32) void {
+ assert(pthread_mutex_lock(&self.mutex) == 0);
+ defer assert(pthread_mutex_unlock(&self.mutex) == 0);
+ while (@atomicLoad(u32, ptr, .Acquire) == expected)
+ assert(pthread_cond_wait(&self.cond, &self.mutex) == 0);
+ }
+
+ const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};
+ extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) c_int;
+ extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) c_int;
+ extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) c_int;
+
+ const PTHREAD_COND_INITIALIZER = pthread_cond_t{};
+ extern "c" fn pthread_cond_wait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t) c_int;
+ extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) c_int;
+ extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) c_int;
+
+ // https://github.com/rust-lang/libc
+ usingnamespace switch (builtin.os) {
+ .macosx, .tvos, .ios, .watchos => struct {
+ pub const pthread_mutex_t = extern struct {
+ __sig: c_long = 0x32AAABA7,
+ __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__,
+ };
+ pub const pthread_cond_t = extern struct {
+ __sig: c_long = 0x3CB0B1BB,
+ __opaque: [__PTHREAD_COND_SIZE__]u8 = [_]u8{0} ** __PTHREAD_COND_SIZE__,
+ };
+ const __PTHREAD_MUTEX_SIZE__ = if (@sizeOf(usize) == 8) 56 else 40;
+ const __PTHREAD_COND_SIZE__ = if (@sizeOf(usize) == 8) 40 else 24;
+ },
+ .netbsd => struct {
+ pub const pthread_mutex_t = extern struct {
+ ptm_magic: c_uint = 0x33330003,
+ ptm_errorcheck: padded_spin_t = 0,
+ ptm_unused: padded_spin_t = 0,
+ ptm_owner: usize = 0,
+ ptm_waiters: ?*u8 = null,
+ ptm_recursed: c_uint = 0,
+ ptm_spare2: ?*c_void = null,
+ };
+ pub const pthread_cond_t = extern struct {
+ ptc_magic: c_uint = 0x55550005,
+ ptc_lock: pthread_spin_t = 0,
+ ptc_waiters_first: ?*u8 = null,
+ ptc_waiters_last: ?*u8 = null,
+ ptc_mutex: ?*pthread_mutex_t = null,
+ ptc_private: ?*c_void = null,
+ };
+ const pthread_spin_t = if (builtin.arch == .arm or .arch == .powerpc) c_int else u8;
+ const padded_spin_t = switch (builtin.arch) {
+ .sparc, .sparcel, .sparcv9, .i386, .x86_64, .le64 => u32,
+ else => spin_t,
+ };
+ },
+ .openbsd, .freebsd, .kfreebsd, .dragonfly => struct {
+ pub const pthread_mutex_t = extern struct {
+ inner: ?*c_void = null,
+ };
+ pub const pthread_cond_t = extern struct {
+ inner: ?*c_void = null,
+ };
+ },
+ .haiku => struct {
+ pub const pthread_mutex_t = extern struct {
+ flags: u32 = 0,
+ lock: i32 = 0,
+ unused: i32 = -42,
+ owner: i32 = -1,
+ owner_count: i32 = 0,
+ };
+ pub const pthread_cond_t = extern struct {
+ flags: u32 = 0,
+ unused: i32 = -42,
+ mutex: ?*c_void = null,
+ waiter_count: i32 = 0,
+ lock: i32 = 0,
+ };
+ },
+ .hermit => struct {
+ pub const pthread_mutex_t = extern struct {
+ inner: usize = ~usize(0),
+ };
+ pub const pthread_cond_t = extern struct {
+ inner: usize = ~usize(0),
+ };
+ },
+ .solaris => struct {
+ pub const pthread_mutex_t = extern struct {
+ __pthread_mutex_flag1: u16 = 0,
+ __pthread_mutex_flag2: u8 = 0,
+ __pthread_mutex_ceiling: u8 = 0,
+ __pthread_mutex_type: u16 = 0,
+ __pthread_mutex_magic: u16 = 0x4d58,
+ __pthread_mutex_lock: u64 = 0,
+ __pthread_mutex_data: u64 = 0,
+ };
+ pub const pthread_cond_t = extern struct {
+ __pthread_cond_flag: u32 = 0,
+ __pthread_cond_type: u16 = 0,
+ __pthread_cond_magic: u16 = 0x4356,
+ __pthread_cond_data: u64 = 0,
+ };
+ },
+ .fuchsia, .minix, .linux => struct {
+ pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+ };
+ pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+ };
+ const __SIZEOF_PTHREAD_COND_T = 48;
+ const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os == .fuchsia) 40 else switch (builtin.abi) {
+ .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
+ .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
+ .aarch64 => 48,
+ .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
+ .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
+ else => if (@sizeOf(usize) == 8) 40 else 24,
+ },
+ else => unreachable,
+ };
+ },
+ .emscripten => struct {
+ pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(4) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+ };
+ pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+ };
+ const __SIZEOF_PTHREAD_COND_T = 48;
+ const __SIZEOF_PTHREAD_MUTEX_T = 28;
+ },
+ else => unreachable,
+ };
+};
diff --git a/lib/std/std.zig b/lib/std/std.zig
index 8ba67e79a2..78b7cc5b12 100644
--- a/lib/std/std.zig
+++ b/lib/std/std.zig
@@ -23,6 +23,7 @@ pub const StringHashMap = @import("hash_map.zig").StringHashMap;
pub const TailQueue = @import("linked_list.zig").TailQueue;
pub const Target = @import("target.zig").Target;
pub const Thread = @import("thread.zig").Thread;
+pub const ThreadParker = @import("parker.zig").ThreadParker;
pub const atomic = @import("atomic.zig");
pub const base64 = @import("base64.zig");
From c9db420a09ad894c1e521d1bdf1c99a3424aa9a6 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 16:14:43 -0600
Subject: [PATCH 006/129] Adaptive Mutex: - uses std.ThreadParker - supports
static initialization (deprecates StaticallyInitializedMutex)
---
lib/std/mutex.zig | 143 ++++++++++++++++++++-----------------------
lib/std/parker.zig | 38 +++++++++++-
lib/std/spinlock.zig | 4 +-
3 files changed, 105 insertions(+), 80 deletions(-)
diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig
index 5f3b9272d9..26f0142c7c 100644
--- a/lib/std/mutex.zig
+++ b/lib/std/mutex.zig
@@ -1,19 +1,13 @@
const std = @import("std.zig");
const builtin = @import("builtin");
-const AtomicOrder = builtin.AtomicOrder;
-const AtomicRmwOp = builtin.AtomicRmwOp;
const testing = std.testing;
const SpinLock = std.SpinLock;
-const linux = std.os.linux;
-const windows = std.os.windows;
+const ThreadParker = std.ThreadParker;
/// Lock may be held only once. If the same thread
/// tries to acquire the same mutex twice, it deadlocks.
-/// This type must be initialized at runtime, and then deinitialized when no
-/// longer needed, to free resources.
-/// If you need static initialization, use std.StaticallyInitializedMutex.
-/// The Linux implementation is based on mutex3 from
-/// https://www.akkadia.org/drepper/futex.pdf
+/// This type supports static initialization and is based off of Golang 1.13 runtime.lock_futex:
+/// https://github.com/golang/go/blob/master/src/runtime/lock_futex.go
/// When an application is built in single threaded release mode, all the functions are
/// no-ops. In single threaded debug mode, there is deadlock detection.
pub const Mutex = if (builtin.single_threaded)
@@ -43,83 +37,78 @@ pub const Mutex = if (builtin.single_threaded)
return Held{ .mutex = self };
}
}
-else switch (builtin.os) {
- builtin.Os.linux => struct {
- /// 0: unlocked
- /// 1: locked, no waiters
- /// 2: locked, one or more waiters
- lock: i32,
+else struct {
+ state: u32, // TODO: make this an enum
+ parker: ThreadParker,
- pub const Held = struct {
- mutex: *Mutex,
+ const Unlocked = 0;
+ const Sleeping = 1;
+ const Locked = 2;
- pub fn release(self: Held) void {
- const c = @atomicRmw(i32, &self.mutex.lock, AtomicRmwOp.Sub, 1, AtomicOrder.Release);
- if (c != 1) {
- _ = @atomicRmw(i32, &self.mutex.lock, AtomicRmwOp.Xchg, 0, AtomicOrder.Release);
- const rc = linux.futex_wake(&self.mutex.lock, linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, 1);
- switch (linux.getErrno(rc)) {
- 0 => {},
- linux.EINVAL => unreachable,
- else => unreachable,
- }
- }
- }
+ /// number of iterations to spin yielding the cpu
+ const SpinCpu = 4;
+ /// number of iterations to perform in the cpu yield loop
+ const SpinCpuCount = 30;
+ /// number of iterations to spin yielding the thread
+ const SpinThread = 1;
+
+ pub fn init() Mutex {
+ return Mutex{
+ .state = Unlocked,
+ .parker = ThreadParker.init(),
};
+ }
- pub fn init() Mutex {
- return Mutex{ .lock = 0 };
+ pub fn deinit(self: *Mutex) void {
+ self.parker.deinit();
+ }
+
+ pub const Held = struct {
+ mutex: *Mutex,
+
+ pub fn release(self: Held) void {
+ switch (@atomicRmw(u32, &self.mutex.state, .Xchg, Unlocked, .Release)) {
+ Locked => {},
+ Sleeping => self.mutex.parker.unpark(&self.mutex.state),
+ Unlocked => unreachable, // unlocking an unlocked mutex
+ else => unreachable, // should never be anything else
+ }
}
+ };
- pub fn deinit(self: *Mutex) void {}
+ pub fn acquire(self: *Mutex) Held {
+ // Try and speculatively grab the lock.
+ // If it fails, the state is either Locked or Sleeping
+ // depending on if theres a thread stuck sleeping below.
+ var state = @atomicRmw(u32, &self.state, .Xchg, Locked, .Acquire);
+ if (state == Unlocked)
+ return Held{ .mutex = self };
- pub fn acquire(self: *Mutex) Held {
- var c = @cmpxchgWeak(i32, &self.lock, 0, 1, AtomicOrder.Acquire, AtomicOrder.Monotonic) orelse
+ while (true) {
+ // try and acquire the lock using cpu spinning on failure
+ for (([SpinCpu]void)(undefined)) |_| {
+ var value = @atomicLoad(u32, &self.state, .Monotonic);
+ while (value == Unlocked)
+ value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ for (([SpinCpuCount]void)(undefined)) |_|
+ SpinLock.yieldCpu();
+ }
+
+ // try and acquire the lock using thread rescheduling on failure
+ for (([SpinThread]void)(undefined)) |_| {
+ var value = @atomicLoad(u32, &self.state, .Monotonic);
+ while (value == Unlocked)
+ value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ SpinLock.yieldThread();
+ }
+
+ // failed to acquire the lock, go to sleep until woken up by `Held.release()`
+ if (@atomicRmw(u32, &self.state, .Xchg, Sleeping, .Acquire) == Unlocked)
return Held{ .mutex = self };
- if (c != 2)
- c = @atomicRmw(i32, &self.lock, AtomicRmwOp.Xchg, 2, AtomicOrder.Acquire);
- while (c != 0) {
- const rc = linux.futex_wait(&self.lock, linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, 2, null);
- switch (linux.getErrno(rc)) {
- 0, linux.EINTR, linux.EAGAIN => {},
- linux.EINVAL => unreachable,
- else => unreachable,
- }
- c = @atomicRmw(i32, &self.lock, AtomicRmwOp.Xchg, 2, AtomicOrder.Acquire);
- }
- return Held{ .mutex = self };
+ state = Sleeping;
+ self.parker.park(&self.state, Sleeping);
}
- },
- // TODO once https://github.com/ziglang/zig/issues/287 (copy elision) is solved, we can make a
- // better implementation of this. The problem is we need the init() function to have access to
- // the address of the CRITICAL_SECTION, and then have it not move.
- builtin.Os.windows => std.StaticallyInitializedMutex,
- else => struct {
- /// TODO better implementation than spin lock.
- /// When changing this, one must also change the corresponding
- /// std.StaticallyInitializedMutex code, since it aliases this type,
- /// under the assumption that it works both statically and at runtime.
- lock: SpinLock,
-
- pub const Held = struct {
- mutex: *Mutex,
-
- pub fn release(self: Held) void {
- SpinLock.Held.release(SpinLock.Held{ .spinlock = &self.mutex.lock });
- }
- };
-
- pub fn init() Mutex {
- return Mutex{ .lock = SpinLock.init() };
- }
-
- pub fn deinit(self: *Mutex) void {}
-
- pub fn acquire(self: *Mutex) Held {
- _ = self.lock.acquire();
- return Held{ .mutex = self };
- }
- },
+ }
};
const TestContext = struct {
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index b6945fa000..8571c89423 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -159,7 +159,7 @@ const WindowsParker = struct {
const key = @ptrCast(*const c_void, ptr);
var waiting = @atomicLoad(u32, waiters, .Acquire);
while (waiting != 0) {
- waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - 1, .AcqRel, .Monotonic) orelse {
+ waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
const rc = windows.ntdll.NtReleaseKeyedEvent(self.handle, key, windows.FALSE, null);
assert(rc == 0);
return;
@@ -338,3 +338,39 @@ const PosixParker = struct {
else => unreachable,
};
};
+
+test "std.ThreadParker" {
+ const Context = struct {
+ parker: ThreadParker,
+ data: u32,
+
+ fn receiver(self: *@This()) void {
+ self.parker.park(&self.data, 0); // receives 1
+ assert(@atomicRmw(u32, &self.data, .Xchg, 2, .SeqCst) == 1); // sends 2
+ self.parker.unpark(&self.data); // wakes up waiters on 2
+ self.parker.park(&self.data, 2); // receives 3
+ assert(@atomicRmw(u32, &self.data, .Xchg, 4, .SeqCst) == 3); // sends 4
+ self.parker.unpark(&self.data); // wakes up waiters on 4
+ }
+
+ fn sender(self: *@This()) void {
+ assert(@atomicRmw(u32, &self.data, .Xchg, 1, .SeqCst) == 0); // sends 1
+ self.parker.unpark(&self.data); // wakes up waiters on 1
+ self.parker.park(&self.data, 1); // receives 2
+ assert(@atomicRmw(u32, &self.data, .Xchg, 3, .SeqCst) == 2); // sends 3
+ self.parker.unpark(&self.data); // wakes up waiters on 3
+ self.parker.park(&self.data, 3); // receives 4
+ }
+ };
+
+ var context = Context{
+ .parker = ThreadParker.init(),
+ .data = 0,
+ };
+ defer context.parker.deinit();
+
+ var receiver = try std.Thread.spawn(&context, Context.receiver);
+ defer receiver.wait();
+
+ context.sender();
+}
\ No newline at end of file
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index c45778cec1..3fd73ab8a3 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -28,7 +28,7 @@ pub const SpinLock = struct {
return Held{ .spinlock = self };
}
- fn yieldCpu() void {
+ pub fn yieldCpu() void {
switch (builtin.arch) {
.i386, .x86_64 => asm volatile("pause" ::: "memory"),
.arm, .aarch64 => asm volatile("yield"),
@@ -36,7 +36,7 @@ pub const SpinLock = struct {
}
}
- fn yieldThread() void {
+ pub fn yieldThread() void {
switch (builtin.os) {
.linux => assert(linux.syscall0(linux.SYS_sched_yield) == 0),
.windows => _ = windows.kernel32.SwitchToThread(),
From 4dbfc48ab3adee68ccb354b80f787a4d42a72c24 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Tue, 5 Nov 2019 16:16:03 -0600
Subject: [PATCH 007/129] Disable asm("yield") for arm in SpinLock.yieldCpu()
because of CI
---
lib/std/spinlock.zig | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 3fd73ab8a3..dadf96cef5 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -31,7 +31,10 @@ pub const SpinLock = struct {
pub fn yieldCpu() void {
switch (builtin.arch) {
.i386, .x86_64 => asm volatile("pause" ::: "memory"),
- .arm, .aarch64 => asm volatile("yield"),
+ // .arm, .aarch64 => asm volatile("yield"),
+ //
+ // Causes CI to fail
+ // See: https://github.com/ziglang/zig/pull/3585#issuecomment-549962765
else => time.sleep(0),
}
}
From ac6f0d245db4fece8982095825394586bd9a50e6 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Wed, 6 Nov 2019 12:43:33 +0200
Subject: [PATCH 008/129] fix NodeErrorSetDecl rendering
---
src/ast_render.cpp | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 18940c4b80..c016f629d1 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -1137,10 +1137,20 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
for (size_t i = 0; i < node->data.err_set_decl.decls.length; i += 1) {
AstNode *field_node = node->data.err_set_decl.decls.at(i);
- assert(field_node->type == NodeTypeSymbol);
- print_indent(ar);
- print_symbol(ar, field_node->data.symbol_expr.symbol);
- fprintf(ar->f, ",\n");
+ switch (field_node->type) {
+ case NodeTypeSymbol:
+ print_indent(ar);
+ print_symbol(ar, field_node->data.symbol_expr.symbol);
+ fprintf(ar->f, ",\n");
+ break;
+ case NodeTypeErrorSetField:
+ print_indent(ar);
+ print_symbol(ar, field_node->data.err_set_field.field_name->data.symbol_expr.symbol);
+ fprintf(ar->f, ",\n");
+ break;
+ default:
+ zig_unreachable();
+ }
}
ar->indent -= ar->indent_size;
From f81f36e2ff348b83ace8ccb4ffd949f3d7c266c9 Mon Sep 17 00:00:00 2001
From: Sebastian Keller
Date: Mon, 28 Oct 2019 21:33:40 +0100
Subject: [PATCH 009/129] std.json.Value: added dumpStream(), utilize
WriteStream for dump()
---
lib/std/debug.zig | 5 ++
lib/std/json.zig | 124 ++++++----------------------------
lib/std/json/write_stream.zig | 6 +-
3 files changed, 32 insertions(+), 103 deletions(-)
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 61b492c20d..cd0c3863ff 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -45,6 +45,7 @@ var stderr_file_out_stream: File.OutStream = undefined;
var stderr_stream: ?*io.OutStream(File.WriteError) = null;
var stderr_mutex = std.Mutex.init();
+
pub fn warn(comptime fmt: []const u8, args: ...) void {
const held = stderr_mutex.acquire();
defer held.release();
@@ -64,6 +65,10 @@ pub fn getStderrStream() !*io.OutStream(File.WriteError) {
}
}
+pub fn getStderrMutex() *std.Mutex {
+ return &stderr_mutex;
+}
+
/// TODO multithreaded awareness
var self_debug_info: ?DebugInfo = null;
diff --git a/lib/std/json.zig b/lib/std/json.zig
index e126f103ae..6cd032806e 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -1012,119 +1012,39 @@ pub const Value = union(enum) {
Object: ObjectMap,
pub fn dump(self: Value) void {
- switch (self) {
- Value.Null => {
- debug.warn("null");
- },
- Value.Bool => |inner| {
- debug.warn("{}", inner);
- },
- Value.Integer => |inner| {
- debug.warn("{}", inner);
- },
- Value.Float => |inner| {
- debug.warn("{:.5}", inner);
- },
- Value.String => |inner| {
- debug.warn("\"{}\"", inner);
- },
- Value.Array => |inner| {
- var not_first = false;
- debug.warn("[");
- for (inner.toSliceConst()) |value| {
- if (not_first) {
- debug.warn(",");
- }
- not_first = true;
- value.dump();
- }
- debug.warn("]");
- },
- Value.Object => |inner| {
- var not_first = false;
- debug.warn("{{");
- var it = inner.iterator();
+ var held = std.debug.getStderrMutex().acquire();
+ defer held.release();
- while (it.next()) |entry| {
- if (not_first) {
- debug.warn(",");
- }
- not_first = true;
- debug.warn("\"{}\":", entry.key);
- entry.value.dump();
- }
- debug.warn("}}");
- },
- }
+ const stderr = std.debug.getStderrStream() catch return;
+ self.dumpStream(stderr, 1024) catch return;
}
- pub fn dumpIndent(self: Value, indent: usize) void {
+ pub fn dumpIndent(self: Value, comptime indent: usize) void {
if (indent == 0) {
self.dump();
} else {
- self.dumpIndentLevel(indent, 0);
+ var held = std.debug.getStderrMutex().acquire();
+ defer held.release();
+
+ const stderr = std.debug.getStderrStream() catch return;
+ self.dumpStreamIndent(indent, stderr, 1024) catch return;
}
}
- fn dumpIndentLevel(self: Value, indent: usize, level: usize) void {
- switch (self) {
- Value.Null => {
- debug.warn("null");
- },
- Value.Bool => |inner| {
- debug.warn("{}", inner);
- },
- Value.Integer => |inner| {
- debug.warn("{}", inner);
- },
- Value.Float => |inner| {
- debug.warn("{:.5}", inner);
- },
- Value.String => |inner| {
- debug.warn("\"{}\"", inner);
- },
- Value.Array => |inner| {
- var not_first = false;
- debug.warn("[\n");
-
- for (inner.toSliceConst()) |value| {
- if (not_first) {
- debug.warn(",\n");
- }
- not_first = true;
- padSpace(level + indent);
- value.dumpIndentLevel(indent, level + indent);
- }
- debug.warn("\n");
- padSpace(level);
- debug.warn("]");
- },
- Value.Object => |inner| {
- var not_first = false;
- debug.warn("{{\n");
- var it = inner.iterator();
-
- while (it.next()) |entry| {
- if (not_first) {
- debug.warn(",\n");
- }
- not_first = true;
- padSpace(level + indent);
- debug.warn("\"{}\": ", entry.key);
- entry.value.dumpIndentLevel(indent, level + indent);
- }
- debug.warn("\n");
- padSpace(level);
- debug.warn("}}");
- },
- }
+ pub fn dumpStream(self: @This(), stream: var, comptime max_depth: usize) !void {
+ var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
+ w.newline = "";
+ w.one_indent = "";
+ w.space = "";
+ try w.emitJson(self);
}
- fn padSpace(indent: usize) void {
- var i: usize = 0;
- while (i < indent) : (i += 1) {
- debug.warn(" ");
- }
+ pub fn dumpStreamIndent(self: @This(), comptime indent: usize, stream: var, comptime max_depth: usize) !void {
+ var one_indent = " " ** indent;
+
+ var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
+ w.one_indent = one_indent;
+ try w.emitJson(self);
}
};
diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig
index 0702a3e9f5..fbf860965f 100644
--- a/lib/std/json/write_stream.zig
+++ b/lib/std/json/write_stream.zig
@@ -27,6 +27,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
/// The string used as a newline character.
newline: []const u8 = "\n",
+ /// The string used as spacing.
+ space: []const u8 = " ",
+
stream: *OutStream,
state_index: usize,
state: [max_depth]State,
@@ -87,7 +90,8 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
self.pushState(.Value);
try self.indent();
try self.writeEscapedString(name);
- try self.stream.write(": ");
+ try self.stream.write(":");
+ try self.stream.write(self.space);
},
}
}
From 7277670843d259d19093c8900b1f8445e41202ae Mon Sep 17 00:00:00 2001
From: shiimizu
Date: Thu, 31 Oct 2019 10:23:02 -0700
Subject: [PATCH 010/129] Add error when too few arguments are provided to
std.fmt
---
lib/std/fmt.zig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index d3d795bf9d..3c860bc595 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -167,6 +167,10 @@ pub fn format(
'}' => {
const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
+ if (arg_to_print >= args.len) {
+ @compileError("Too few arguments");
+ }
+
try formatType(
args[arg_to_print],
fmt[0..0],
From 7045f1e875eba3ec9cd5bd051aee059d34776bed Mon Sep 17 00:00:00 2001
From: kprotty
Date: Wed, 6 Nov 2019 17:23:44 -0600
Subject: [PATCH 011/129] skip std.ThreadParker test on single-threaded
---
lib/std/parker.zig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 8571c89423..2dc38d2b38 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -340,6 +340,9 @@ const PosixParker = struct {
};
test "std.ThreadParker" {
+ if (builtin.single_threaded)
+ return error.SkipZigTest;
+
const Context = struct {
parker: ThreadParker,
data: u32,
From 6ee3cabe5cc0b2c9af30b1fa0233381faa18e700 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Nov 2019 20:43:13 -0500
Subject: [PATCH 012/129] allow type coercion from *[0]T to E![]const T
This is an unambiguous, safe cast.
---
lib/std/fs/path.zig | 2 +-
lib/std/heap.zig | 8 +--
lib/std/mem.zig | 6 +-
src/ir.cpp | 110 +++++++++++++++++++++++++++++++++-
test/stage1/behavior/cast.zig | 21 +++++++
5 files changed, 135 insertions(+), 12 deletions(-)
diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig
index 1c9e3e100b..6a24055667 100644
--- a/lib/std/fs/path.zig
+++ b/lib/std/fs/path.zig
@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) bool {
/// This is different from mem.join in that the separator will not be repeated if
/// it is found at the end or beginning of a pair of consecutive paths.
fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u8 {
- if (paths.len == 0) return (([*]u8)(undefined))[0..0];
+ if (paths.len == 0) return &[0]u8{};
const total_len = blk: {
var sum: usize = paths[0].len;
diff --git a/lib/std/heap.zig b/lib/std/heap.zig
index 8723c7eab6..ccdab8d332 100644
--- a/lib/std/heap.zig
+++ b/lib/std/heap.zig
@@ -41,8 +41,7 @@ var direct_allocator_state = Allocator{
const DirectAllocator = struct {
fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
- if (n == 0)
- return (([*]u8)(undefined))[0..0];
+ if (n == 0) return &[0]u8{};
if (builtin.os == .windows) {
const w = os.windows;
@@ -261,8 +260,7 @@ pub const HeapAllocator = switch (builtin.os) {
fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
- if (n == 0)
- return (([*]u8)(undefined))[0..0];
+ if (n == 0) return &[0]u8{};
const amt = n + alignment + @sizeOf(usize);
const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);
@@ -677,7 +675,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type {
) catch {
const result = try self.fallback_allocator.reallocFn(
self.fallback_allocator,
- ([*]u8)(undefined)[0..0],
+ &[0]u8{},
undefined,
new_size,
new_align,
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index bf8f7b8be7..8924828378 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -122,7 +122,7 @@ pub const Allocator = struct {
}
const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
- const byte_slice = try self.reallocFn(self, ([*]u8)(undefined)[0..0], undefined, byte_count, a);
+ const byte_slice = try self.reallocFn(self, &[0]u8{}, undefined, byte_count, a);
assert(byte_slice.len == byte_count);
@memset(byte_slice.ptr, undefined, byte_slice.len);
if (alignment == null) {
@@ -976,7 +976,7 @@ pub const SplitIterator = struct {
/// Naively combines a series of slices with a separator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {
- if (slices.len == 0) return (([*]u8)(undefined))[0..0];
+ if (slices.len == 0) return &[0]u8{};
const total_len = blk: {
var sum: usize = separator.len * (slices.len - 1);
@@ -1011,7 +1011,7 @@ test "mem.join" {
/// Copies each T from slices into a new slice that exactly holds all the elements.
pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T) ![]T {
- if (slices.len == 0) return (([*]T)(undefined))[0..0];
+ if (slices.len == 0) return &[0]T{};
const total_len = blk: {
var sum: usize = 0;
diff --git a/src/ir.cpp b/src/ir.cpp
index d4687e5adb..dae759ed84 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10494,6 +10494,50 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
continue;
}
+ // *[N]T to []T
+ // *[N]T to E![]T
+ if (cur_type->id == ZigTypeIdPointer &&
+ cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
+ ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) ||
+ is_slice(prev_type)))
+ {
+ ZigType *array_type = cur_type->data.pointer.child_type;
+ ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ?
+ prev_type->data.error_union.payload_type : prev_type;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
+ types_match_const_cast_only(ira,
+ slice_ptr_type->data.pointer.child_type,
+ array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
+ {
+ convert_to_const_slice = false;
+ continue;
+ }
+ }
+
+ // *[N]T to []T
+ // *[N]T to E![]T
+ if (prev_type->id == ZigTypeIdPointer &&
+ prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
+ ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) ||
+ is_slice(cur_type)))
+ {
+ ZigType *array_type = prev_type->data.pointer.child_type;
+ ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ?
+ cur_type->data.error_union.payload_type : cur_type;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
+ types_match_const_cast_only(ira,
+ slice_ptr_type->data.pointer.child_type,
+ array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
+ {
+ prev_inst = cur_inst;
+ convert_to_const_slice = false;
+ continue;
+ }
+ }
+
+ // [N]T to []T
if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) &&
(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
cur_type->data.array.len == 0) &&
@@ -10505,6 +10549,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
continue;
}
+ // [N]T to []T
if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) &&
(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
prev_type->data.array.len == 0) &&
@@ -12642,12 +12687,71 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
// *[N]T to []T
- if (is_slice(wanted_type) &&
+ // *[N]T to E![]T
+ if ((is_slice(wanted_type) ||
+ (wanted_type->id == ZigTypeIdErrorUnion &&
+ is_slice(wanted_type->data.error_union.payload_type))) &&
actual_type->id == ZigTypeIdPointer &&
actual_type->data.pointer.ptr_len == PtrLenSingle &&
actual_type->data.pointer.child_type->id == ZigTypeIdArray)
{
- ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ?
+ wanted_type->data.error_union.payload_type : wanted_type;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ assert(slice_ptr_type->id == ZigTypeIdPointer);
+ ZigType *array_type = actual_type->data.pointer.child_type;
+ bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
+ || !actual_type->data.pointer.is_const);
+ if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
+ array_type->data.array.child_type, source_node,
+ !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ // If the pointers both have ABI align, it works.
+ // Or if the array length is 0, alignment doesn't matter.
+ bool ok_align = array_type->data.array.len == 0 ||
+ (slice_ptr_type->data.pointer.explicit_alignment == 0 &&
+ actual_type->data.pointer.explicit_alignment == 0);
+ if (!ok_align) {
+ // If either one has non ABI align, we have to resolve them both
+ if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+ if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+ ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);
+ }
+ if (ok_align) {
+ if (wanted_type->id == ZigTypeIdErrorUnion) {
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value, nullptr);
+ if (type_is_invalid(cast1->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
+ if (type_is_invalid(cast2->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return cast2;
+ } else {
+ return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, result_loc);
+ }
+ }
+ }
+ }
+
+ // *[N]T to E![]T
+ if (wanted_type->id == ZigTypeIdErrorUnion &&
+ is_slice(wanted_type->data.error_union.payload_type) &&
+ actual_type->id == ZigTypeIdPointer &&
+ actual_type->data.pointer.ptr_len == PtrLenSingle &&
+ actual_type->data.pointer.child_type->id == ZigTypeIdArray)
+ {
+ ZigType *slice_type = wanted_type->data.error_union.payload_type;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
assert(slice_ptr_type->id == ZigTypeIdPointer);
ZigType *array_type = actual_type->data.pointer.child_type;
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
@@ -12674,7 +12778,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);
}
if (ok_align) {
- return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
+ return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, result_loc);
}
}
}
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 8176f5cf83..6bc8540b7d 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -538,3 +538,24 @@ test "implicit cast comptime_int to comptime_float" {
comptime expect(comptime_float(10) == f32(10));
expect(2 == 2.0);
}
+
+test "implicit cast *[0]T to E![]const u8" {
+ var x = (anyerror![]const u8)(&[0]u8{});
+ expect((x catch unreachable).len == 0);
+}
+
+test "peer cast *[0]T to E![]const T" {
+ var buffer: [5]u8 = "abcde";
+ var buf: anyerror![]const u8 = buffer[0..];
+ var b = false;
+ var y = if (b) &[0]u8{} else buf;
+ expect(mem.eql(u8, "abcde", y catch unreachable));
+}
+
+test "peer cast *[0]T to []const T" {
+ var buffer: [5]u8 = "abcde";
+ var buf: []const u8 = buffer[0..];
+ var b = false;
+ var y = if (b) &[0]u8{} else buf;
+ expect(mem.eql(u8, "abcde", y));
+}
From f4767186dd34118a27c205fe481b42c33e7ba0d3 Mon Sep 17 00:00:00 2001
From: Nick Erdmann
Date: Mon, 28 Oct 2019 23:12:28 +0100
Subject: [PATCH 013/129] std/os/uefi: loading images
---
lib/std/os/uefi/protocols.zig | 4 ++
.../uefi/protocols/device_path_protocol.zig | 17 +++++++++
.../uefi/protocols/loaded_image_protocol.zig | 36 ++++++++++++++++++
lib/std/os/uefi/tables/boot_services.zig | 37 +++++++++++++++++--
lib/std/os/uefi/tables/runtime_services.zig | 8 ++++
5 files changed, 98 insertions(+), 4 deletions(-)
create mode 100644 lib/std/os/uefi/protocols/device_path_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/loaded_image_protocol.zig
diff --git a/lib/std/os/uefi/protocols.zig b/lib/std/os/uefi/protocols.zig
index ff0040860b..b8a39d1815 100644
--- a/lib/std/os/uefi/protocols.zig
+++ b/lib/std/os/uefi/protocols.zig
@@ -1,3 +1,7 @@
+pub const LoadedImageProtocol = @import("protocols/loaded_image_protocol.zig").LoadedImageProtocol;
+
+pub const DevicePathProtocol = @import("protocols/device_path_protocol.zig").DevicePathProtocol;
+
pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;
diff --git a/lib/std/os/uefi/protocols/device_path_protocol.zig b/lib/std/os/uefi/protocols/device_path_protocol.zig
new file mode 100644
index 0000000000..a945608f88
--- /dev/null
+++ b/lib/std/os/uefi/protocols/device_path_protocol.zig
@@ -0,0 +1,17 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+
+pub const DevicePathProtocol = extern struct {
+ type: u8,
+ subtype: u8,
+ length: u16,
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x09576e91,
+ .time_mid = 0x6d3f,
+ .time_high_and_version = 0x11d2,
+ .clock_seq_high_and_reserved = 0x8e,
+ .clock_seq_low = 0x39,
+ .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
+ };
+};
diff --git a/lib/std/os/uefi/protocols/loaded_image_protocol.zig b/lib/std/os/uefi/protocols/loaded_image_protocol.zig
new file mode 100644
index 0000000000..b7b281e249
--- /dev/null
+++ b/lib/std/os/uefi/protocols/loaded_image_protocol.zig
@@ -0,0 +1,36 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+const Handle = uefi.Handle;
+const SystemTable = uefi.tables.SystemTable;
+const MemoryType = uefi.tables.MemoryType;
+const DevicePathProtocol = uefi.protocols.DevicePathProtocol;
+
+pub const LoadedImageProtocol = extern struct {
+ revision: u32,
+ parent_handle: Handle,
+ system_table: *SystemTable,
+ device_handle: ?Handle,
+ file_path: *DevicePathProtocol,
+ reserved: *c_void,
+ load_options_size: u32,
+ load_options: *c_void,
+ image_base: [*]u8,
+ image_size: u64,
+ image_code_type: MemoryType,
+ image_data_type: MemoryType,
+ _unload: extern fn (*const LoadedImageProtocol, Handle) usize,
+
+ /// Unloads an image from memory.
+ pub fn unload(self: *const LoadedImageProtocol, handle: Handle) usize {
+ return self._unload(self, handle);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x5b1b31a1,
+ .time_mid = 0x9562,
+ .time_high_and_version = 0x11d2,
+ .clock_seq_high_and_reserved = 0x8e,
+ .clock_seq_low = 0x3f,
+ .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
+ };
+};
diff --git a/lib/std/os/uefi/tables/boot_services.zig b/lib/std/os/uefi/tables/boot_services.zig
index 18fb082235..e6c37936b9 100644
--- a/lib/std/os/uefi/tables/boot_services.zig
+++ b/lib/std/os/uefi/tables/boot_services.zig
@@ -3,6 +3,7 @@ const Event = uefi.Event;
const Guid = uefi.Guid;
const Handle = uefi.Handle;
const TableHeader = uefi.tables.TableHeader;
+const DevicePathProtocol = uefi.protocols.DevicePathProtocol;
/// Boot services are services provided by the system's firmware until the operating system takes
/// over control over the hardware by calling exitBootServices.
@@ -17,47 +18,73 @@ const TableHeader = uefi.tables.TableHeader;
/// As the boot_services table may grow with new UEFI versions, it is important to check hdr.header_size.
pub const BootServices = extern struct {
hdr: TableHeader,
+
raiseTpl: usize, // TODO
restoreTpl: usize, // TODO
allocatePages: usize, // TODO
freePages: usize, // TODO
+
/// Returns the current memory map.
getMemoryMap: extern fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) usize,
+
/// Allocates pool memory.
allocatePool: extern fn (MemoryType, usize, *align(8) [*]u8) usize,
+
freePool: usize, // TODO
+
/// Creates an event.
createEvent: extern fn (u32, usize, ?extern fn (Event, ?*const c_void) void, ?*const c_void, *Event) usize,
+
/// Sets the type of timer and the trigger time for a timer event.
setTimer: extern fn (Event, TimerDelay, u64) usize,
+
/// Stops execution until an event is signaled.
waitForEvent: extern fn (usize, [*]const Event, *usize) usize,
+
/// Signals an event.
signalEvent: extern fn (Event) usize,
+
/// Closes an event.
closeEvent: extern fn (Event) usize,
+
checkEvent: usize, // TODO
installProtocolInterface: usize, // TODO
reinstallProtocolInterface: usize, // TODO
uninstallProtocolInterface: usize, // TODO
- handleProtocol: usize, // TODO
+
+ /// Queries a handle to determine if it supports a specified protocol.
+ handleProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void) usize,
+
reserved: *c_void,
+
registerProtocolNotify: usize, // TODO
locateHandle: usize, // TODO
locateDevicePath: usize, // TODO
installConfigurationTable: usize, // TODO
- imageLoad: usize, // TODO
- imageStart: usize, // TODO
+
+ /// Loads an EFI image into memory.
+ loadImage: extern fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) usize,
+
+ /// Transfers control to a loaded image's entry point.
+ startImage: extern fn (Handle, ?*usize, ?*[*]u16) usize,
+
/// Terminates a loaded EFI image and returns control to boot services.
exit: extern fn (Handle, usize, usize, ?*const c_void) usize,
- imageUnload: usize, // TODO
+
+ /// Unloads an image.
+ unloadImage: extern fn (Handle) usize,
+
/// Terminates all boot services.
exitBootServices: extern fn (Handle, usize) usize,
+
getNextMonotonicCount: usize, // TODO
+
/// Induces a fine-grained stall.
stall: extern fn (usize) usize,
+
/// Sets the system's watchdog timer.
setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) usize,
+
connectController: usize, // TODO
disconnectController: usize, // TODO
openProtocol: usize, // TODO
@@ -65,8 +92,10 @@ pub const BootServices = extern struct {
openProtocolInformation: usize, // TODO
protocolsPerHandle: usize, // TODO
locateHandleBuffer: usize, // TODO
+
/// Returns the first protocol instance that matches the given protocol.
locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) usize,
+
installMultipleProtocolInterfaces: usize, // TODO
uninstallMultipleProtocolInterfaces: usize, // TODO
calculateCrc32: usize, // TODO
diff --git a/lib/std/os/uefi/tables/runtime_services.zig b/lib/std/os/uefi/tables/runtime_services.zig
index 89231b51a8..39d1aa2e3e 100644
--- a/lib/std/os/uefi/tables/runtime_services.zig
+++ b/lib/std/os/uefi/tables/runtime_services.zig
@@ -14,22 +14,30 @@ const TimeCapabilities = uefi.TimeCapabilities;
/// Some functions may not be called while other functions are running.
pub const RuntimeServices = extern struct {
hdr: TableHeader,
+
/// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.
getTime: extern fn (*uefi.Time, ?*TimeCapabilities) usize,
+
setTime: usize, // TODO
getWakeupTime: usize, // TODO
setWakeupTime: usize, // TODO
setVirtualAddressMap: usize, // TODO
convertPointer: usize, // TODO
+
/// Returns the value of a variable.
getVariable: extern fn ([*]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) usize,
+
/// Enumerates the current variable names.
getNextVariableName: extern fn (*usize, [*]u16, *align(8) Guid) usize,
+
/// Sets the value of a variable.
setVariable: extern fn ([*]const u16, *align(8) const Guid, u32, usize, *c_void) usize,
+
getNextHighMonotonicCount: usize, // TODO
+
/// Resets the entire platform.
resetSystem: extern fn (ResetType, usize, usize, ?*const c_void) noreturn,
+
updateCapsule: usize, // TODO
queryCapsuleCapabilities: usize, // TODO
queryVariableInfo: usize, // TODO
From cef51eaffb8fdb7257bc08a61f4fdc7eb7bac457 Mon Sep 17 00:00:00 2001
From: Nick Erdmann
Date: Thu, 7 Nov 2019 02:47:57 +0100
Subject: [PATCH 014/129] std/os/uefi: snp, mnp, ip6, and udp6 support
---
lib/std/os/uefi/protocols.zig | 40 ++++
.../os/uefi/protocols/ip6_config_protocol.zig | 45 +++++
lib/std/os/uefi/protocols/ip6_protocol.zig | 143 +++++++++++++++
.../ip6_service_binding_protocol.zig | 25 +++
.../protocols/managed_network_protocol.zig | 126 +++++++++++++
...naged_network_service_binding_protocol.zig | 25 +++
.../protocols/simple_network_protocol.zig | 172 ++++++++++++++++++
lib/std/os/uefi/protocols/udp6_protocol.zig | 112 ++++++++++++
.../udp6_service_binding_protocol.zig | 25 +++
9 files changed, 713 insertions(+)
create mode 100644 lib/std/os/uefi/protocols/ip6_config_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/ip6_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/managed_network_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/simple_network_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/udp6_protocol.zig
create mode 100644 lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
diff --git a/lib/std/os/uefi/protocols.zig b/lib/std/os/uefi/protocols.zig
index b8a39d1815..f3c3747e1e 100644
--- a/lib/std/os/uefi/protocols.zig
+++ b/lib/std/os/uefi/protocols.zig
@@ -33,6 +33,46 @@ pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").Edi
pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;
pub const EdidOverrideProtocolAttributes = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocolAttributes;
+pub const SimpleNetworkProtocol = @import("protocols/simple_network_protocol.zig").SimpleNetworkProtocol;
+pub const MacAddress = @import("protocols/simple_network_protocol.zig").MacAddress;
+pub const SimpleNetworkMode = @import("protocols/simple_network_protocol.zig").SimpleNetworkMode;
+pub const SimpleNetworkReceiveFilter = @import("protocols/simple_network_protocol.zig").SimpleNetworkReceiveFilter;
+pub const SimpleNetworkState = @import("protocols/simple_network_protocol.zig").SimpleNetworkState;
+pub const NetworkStatistics = @import("protocols/simple_network_protocol.zig").NetworkStatistics;
+pub const SimpleNetworkInterruptStatus = @import("protocols/simple_network_protocol.zig").SimpleNetworkInterruptStatus;
+
+pub const ManagedNetworkServiceBindingProtocol = @import("protocols/managed_network_service_binding_protocol.zig").ManagedNetworkServiceBindingProtocol;
+pub const ManagedNetworkProtocol = @import("protocols/managed_network_protocol.zig").ManagedNetworkProtocol;
+pub const ManagedNetworkConfigData = @import("protocols/managed_network_protocol.zig").ManagedNetworkConfigData;
+pub const ManagedNetworkCompletionToken = @import("protocols/managed_network_protocol.zig").ManagedNetworkCompletionToken;
+pub const ManagedNetworkReceiveData = @import("protocols/managed_network_protocol.zig").ManagedNetworkReceiveData;
+pub const ManagedNetworkTransmitData = @import("protocols/managed_network_protocol.zig").ManagedNetworkTransmitData;
+pub const ManagedNetworkFragmentData = @import("protocols/managed_network_protocol.zig").ManagedNetworkFragmentData;
+
+pub const Ip6ServiceBindingProtocol = @import("protocols/ip6_service_binding_protocol.zig").Ip6ServiceBindingProtocol;
+pub const Ip6Protocol = @import("protocols/ip6_protocol.zig").Ip6Protocol;
+pub const Ip6ModeData = @import("protocols/ip6_protocol.zig").Ip6ModeData;
+pub const Ip6ConfigData = @import("protocols/ip6_protocol.zig").Ip6ConfigData;
+pub const Ip6Address = @import("protocols/ip6_protocol.zig").Ip6Address;
+pub const Ip6AddressInfo = @import("protocols/ip6_protocol.zig").Ip6AddressInfo;
+pub const Ip6RouteTable = @import("protocols/ip6_protocol.zig").Ip6RouteTable;
+pub const Ip6NeighborState = @import("protocols/ip6_protocol.zig").Ip6NeighborState;
+pub const Ip6NeighborCache = @import("protocols/ip6_protocol.zig").Ip6NeighborCache;
+pub const Ip6IcmpType = @import("protocols/ip6_protocol.zig").Ip6IcmpType;
+pub const Ip6CompletionToken = @import("protocols/ip6_protocol.zig").Ip6CompletionToken;
+
+pub const Ip6ConfigProtocol = @import("protocols/ip6_config_protocol.zig").Ip6ConfigProtocol;
+pub const Ip6ConfigDataType = @import("protocols/ip6_config_protocol.zig").Ip6ConfigDataType;
+
+pub const Udp6ServiceBindingProtocol = @import("protocols/udp6_service_binding_protocol.zig").Udp6ServiceBindingProtocol;
+pub const Udp6Protocol = @import("protocols/udp6_protocol.zig").Udp6Protocol;
+pub const Udp6ConfigData = @import("protocols/udp6_protocol.zig").Udp6ConfigData;
+pub const Udp6CompletionToken = @import("protocols/udp6_protocol.zig").Udp6CompletionToken;
+pub const Udp6ReceiveData = @import("protocols/udp6_protocol.zig").Udp6ReceiveData;
+pub const Udp6TransmitData = @import("protocols/udp6_protocol.zig").Udp6TransmitData;
+pub const Udp6SessionData = @import("protocols/udp6_protocol.zig").Udp6SessionData;
+pub const Udp6FragmentData = @import("protocols/udp6_protocol.zig").Udp6FragmentData;
+
pub const hii = @import("protocols/hii.zig");
pub const HIIDatabaseProtocol = @import("protocols/hii_database_protocol.zig").HIIDatabaseProtocol;
pub const HIIPopupProtocol = @import("protocols/hii_popup_protocol.zig").HIIPopupProtocol;
diff --git a/lib/std/os/uefi/protocols/ip6_config_protocol.zig b/lib/std/os/uefi/protocols/ip6_config_protocol.zig
new file mode 100644
index 0000000000..a86e2cbba2
--- /dev/null
+++ b/lib/std/os/uefi/protocols/ip6_config_protocol.zig
@@ -0,0 +1,45 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+const Event = uefi.Event;
+
+pub const Ip6ConfigProtocol = extern struct {
+ _set_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) usize,
+ _get_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) usize,
+ _register_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) usize,
+ _unregister_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) usize,
+
+ pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) usize {
+ return self._set_data(self, data_type, data_size, data);
+ }
+
+ pub fn getData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: *usize, data: ?*const c_void) usize {
+ return self._get_data(self, data_type, data_size, data);
+ }
+
+ pub fn registerDataNotify(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, event: Event) usize {
+ return self._register_data_notify(self, data_type, event);
+ }
+
+ pub fn unregisterDataNotify(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, event: Event) usize {
+ return self._unregister_data_notify(self, data_type, event);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x937fe521,
+ .time_mid = 0x95ae,
+ .time_high_and_version = 0x4d1a,
+ .clock_seq_high_and_reserved = 0x89,
+ .clock_seq_low = 0x29,
+ .node = [_]u8{ 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a },
+ };
+};
+
+pub const Ip6ConfigDataType = extern enum(u32) {
+ InterfaceInfo,
+ AltInterfaceId,
+ Policy,
+ DupAddrDetectTransmits,
+ ManualAddress,
+ Gateway,
+ DnsServer,
+};
diff --git a/lib/std/os/uefi/protocols/ip6_protocol.zig b/lib/std/os/uefi/protocols/ip6_protocol.zig
new file mode 100644
index 0000000000..a412dc3c7b
--- /dev/null
+++ b/lib/std/os/uefi/protocols/ip6_protocol.zig
@@ -0,0 +1,143 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+const Event = uefi.Event;
+const MacAddress = uefi.protocols.MacAddress;
+const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
+const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
+
+pub const Ip6Protocol = extern struct {
+ _get_mode_data: extern fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
+ _configure: extern fn (*const Ip6Protocol, ?*const Ip6ConfigData) usize,
+ _groups: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address) usize,
+ _routes: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) usize,
+ _neighbors: extern fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) usize,
+ _transmit: extern fn (*const Ip6Protocol, *Ip6CompletionToken) usize,
+ _receive: extern fn (*const Ip6Protocol, *Ip6CompletionToken) usize,
+ _cancel: extern fn (*const Ip6Protocol, ?*Ip6CompletionToken) usize,
+ _poll: extern fn (*const Ip6Protocol) usize,
+
+ /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
+ pub fn getModeData(self: *const Ip6Protocol, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
+ return self._get_mode_data(self, ip6_mode_data, mnp_config_data, snp_mode_data);
+ }
+
+ /// Assign IPv6 address and other configuration parameter to this EFI IPv6 Protocol driver instance.
+ pub fn configure(self: *const Ip6Protocol, ip6_config_data: ?*const Ip6ConfigData) usize {
+ return self._configure(self, ip6_config_data);
+ }
+
+ /// Joins and leaves multicast groups.
+ pub fn groups(self: *const Ip6Protocol, join_flag: bool, group_address: ?*const Ip6Address) usize {
+ return self._groups(self, join_flag, group_address);
+ }
+
+ /// Adds and deletes routing table entries.
+ pub fn routes(self: *const Ip6Protocol, delete_route: bool, destination: ?*const Ip6Address, prefix_length: u8, gateway_address: ?*const Ip6Address) usize {
+ return self._routes(self, delete_route, destination, prefix_length, gateway_address);
+ }
+
+ /// Add or delete Neighbor cache entries.
+ pub fn neighbors(self: *const Ip6Protocol, delete_flag: bool, target_ip6_address: *const Ip6Address, target_link_address: ?*const MacAddress, timeout: u32, override: bool) usize {
+ return self._neighbors(self, delete_flag, target_ip6_address, target_link_address, timeout, override);
+ }
+
+ /// Places outgoing data packets into the transmit queue.
+ pub fn transmit(self: *const Ip6Protocol, token: *Ip6CompletionToken) usize {
+ return self._transmit(self, token);
+ }
+
+ /// Places a receiving request into the receiving queue.
+ pub fn receive(self: *const Ip6Protocol, token: *Ip6CompletionToken) usize {
+ return self._receive(self, token);
+ }
+
+ /// Abort an asynchronous transmits or receive request.
+ pub fn cancel(self: *const Ip6Protocol, token: ?*Ip6CompletionToken) usize {
+ return self._cancel(self, token);
+ }
+
+ /// Polls for incoming data packets and processes outgoing data packets.
+ pub fn poll(self: *const Ip6Protocol) usize {
+ return self._poll(self);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x2c8759d5,
+ .time_mid = 0x5c2d,
+ .time_high_and_version = 0x66ef,
+ .clock_seq_high_and_reserved = 0x92,
+ .clock_seq_low = 0x5f,
+ .node = [_]u8{ 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 },
+ };
+};
+
+pub const Ip6ModeData = extern struct {
+ is_started: bool,
+ max_packet_size: u32,
+ config_data: Ip6ConfigData,
+ is_configured: bool,
+ address_count: u32,
+ address_list: [*]Ip6AddressInfo,
+ group_count: u32,
+ group_table: [*]Ip6Address,
+ route_count: u32,
+ route_table: [*]Ip6RouteTable,
+ neighbor_count: u32,
+ neighbor_cache: [*]Ip6NeighborCache,
+ prefix_count: u32,
+ prefix_table: [*]Ip6AddressInfo,
+ icmp_type_count: u32,
+ icmp_type_list: [*]Ip6IcmpType,
+};
+
+pub const Ip6ConfigData = extern struct {
+ default_protocol: u8,
+ accept_any_protocol: bool,
+ accept_icmp_errors: bool,
+ accept_promiscuous: bool,
+ destination_address: Ip6Address,
+ station_address: Ip6Address,
+ traffic_class: u8,
+ hop_limit: u8,
+ flow_label: u32,
+ receive_timeout: u32,
+ transmit_timeout: u32,
+};
+
+pub const Ip6Address = [16]u8;
+
+pub const Ip6AddressInfo = extern struct {
+ address: Ip6Address,
+ prefix_length: u8,
+};
+
+pub const Ip6RouteTable = extern struct {
+ gateway: Ip6Address,
+ destination: Ip6Address,
+ prefix_length: u8,
+};
+
+pub const Ip6NeighborState = extern enum(u32) {
+ Incomplete,
+ Reachable,
+ Stale,
+ Delay,
+ Probe,
+};
+
+pub const Ip6NeighborCache = extern struct {
+ neighbor: Ip6Address,
+ link_address: MacAddress,
+ state: Ip6NeighborState,
+};
+
+pub const Ip6IcmpType = extern struct {
+ type: u8,
+ code: u8,
+};
+
+pub const Ip6CompletionToken = extern struct {
+ event: Event,
+ status: usize,
+ packet: *c_void, // union TODO
+};
diff --git a/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
new file mode 100644
index 0000000000..9ecbb29607
--- /dev/null
+++ b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
@@ -0,0 +1,25 @@
+const uefi = @import("std").os.uefi;
+const Handle = uefi.Handle;
+const Guid = uefi.Guid;
+
+pub const Ip6ServiceBindingProtocol = extern struct {
+ _create_child: extern fn (*const Ip6ServiceBindingProtocol, *?Handle) usize,
+ _destroy_child: extern fn (*const Ip6ServiceBindingProtocol, Handle) usize,
+
+ pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) usize {
+ return self._create_child(self, handle);
+ }
+
+ pub fn destroyChild(self: *const Ip6ServiceBindingProtocol, handle: Handle) usize {
+ return self._destroy_child(self, handle);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0xec835dd3,
+ .time_mid = 0xfe0f,
+ .time_high_and_version = 0x617b,
+ .clock_seq_high_and_reserved = 0xa6,
+ .clock_seq_low = 0x21,
+ .node = [_]u8{ 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 },
+ };
+};
diff --git a/lib/std/os/uefi/protocols/managed_network_protocol.zig b/lib/std/os/uefi/protocols/managed_network_protocol.zig
new file mode 100644
index 0000000000..a2cf6e2eca
--- /dev/null
+++ b/lib/std/os/uefi/protocols/managed_network_protocol.zig
@@ -0,0 +1,126 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+const Event = uefi.Event;
+const Time = uefi.Time;
+const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
+const MacAddress = uefi.protocols.MacAddress;
+
+pub const ManagedNetworkProtocol = extern struct {
+ _get_mode_data: extern fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
+ _configure: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) usize,
+ _mcast_ip_to_mac: extern fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) usize,
+ _groups: extern fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) usize,
+ _transmit: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) usize,
+ _receive: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) usize,
+ _cancel: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) usize,
+ _poll: extern fn (*const ManagedNetworkProtocol) usize,
+
+ /// Returns the operational parameters for the current MNP child driver.
+ /// May also support returning the underlying SNP driver mode data.
+ pub fn getModeData(self: *const ManagedNetworkProtocol, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
+ return self._get_mode_data(self, mnp_config_data, snp_mode_data);
+ }
+
+ /// Sets or clears the operational parameters for the MNP child driver.
+ pub fn configure(self: *const ManagedNetworkProtocol, mnp_config_data: ?*const ManagedNetworkConfigData) usize {
+ return self._configure(self, mnp_config_data);
+ }
+
+ /// Translates an IP multicast address to a hardware (MAC) multicast address.
+ /// This function may be unsupported in some MNP implementations.
+ pub fn mcastIpToMac(self: *const ManagedNetworkProtocol, ipv6flag: bool, ipaddress: *const c_void, mac_address: *MacAddress) usize {
+ return self._mcast_ip_to_mac(self, ipv6flag, ipaddress);
+ }
+
+ /// Enables and disables receive filters for multicast address.
+ /// This function may be unsupported in some MNP implementations.
+ pub fn groups(self: *const ManagedNetworkProtocol, join_flag: bool, mac_address: ?*const MacAddress) usiz {
+ return self._groups(self, join_flag, mac_address);
+ }
+
+ /// Places asynchronous outgoing data packets into the transmit queue.
+ pub fn transmit(self: *const ManagedNetworkProtocol, token: *const ManagedNetworkCompletionToken) usize {
+ return self._transmit(self, token);
+ }
+
+ /// Places an asynchronous receiving request into the receiving queue.
+ pub fn receive(self: *const ManagedNetworkProtocol, token: *const ManagedNetworkCompletionToken) usize {
+ return self._receive(self, token);
+ }
+
+ /// Aborts an asynchronous transmit or receive request.
+ pub fn cancel(self: *const ManagedNetworkProtocol, token: ?*const ManagedNetworkCompletionToken) usize {
+ return self._cancel(self, token);
+ }
+
+ /// Polls for incoming data packets and processes outgoing data packets.
+ pub fn poll(self: *const ManagedNetworkProtocol) usize {
+ return self._poll(self);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x7ab33a91,
+ .time_mid = 0xace5,
+ .time_high_and_version = 0x4326,
+ .clock_seq_high_and_reserved = 0xb5,
+ .clock_seq_low = 0x72,
+ .node = [_]u8{ 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16 },
+ };
+};
+
+pub const ManagedNetworkConfigData = extern struct {
+ received_queue_timeout_value: u32,
+ transmit_queue_timeout_value: u32,
+ protocol_type_filter: u16,
+ enable_unicast_receive: bool,
+ enable_multicast_receive: bool,
+ enable_broadcast_receive: bool,
+ enable_promiscuous_receive: bool,
+ flush_queues_on_reset: bool,
+ enable_receive_timestamps: bool,
+ disable_background_polling: bool,
+};
+
+pub const ManagedNetworkCompletionToken = extern struct {
+ event: Event,
+ status: usize,
+ packet: extern union {
+ RxData: *ManagedNetworkReceiveData,
+ TxData: *ManagedNetworkTransmitData,
+ },
+};
+
+pub const ManagedNetworkReceiveData = extern struct {
+ timestamp: Time,
+ recycle_event: Event,
+ packet_length: u32,
+ header_length: u32,
+ address_length: u32,
+ data_length: u32,
+ broadcast_flag: bool,
+ multicast_flag: bool,
+ promiscuous_flag: bool,
+ protocol_type: u16,
+ destination_address: [*]u8,
+ source_address: [*]u8,
+ media_header: [*]u8,
+ packet_data: [*]u8,
+};
+
+pub const ManagedNetworkTransmitData = extern struct {
+ destination_address: ?*MacAddress,
+ source_address: ?*MacAddress,
+ protocol_type: u16,
+ data_length: u32,
+ header_length: u16,
+ fragment_count: u16,
+
+ pub fn getFragments(self: *ManagedNetworkTransmitData) []ManagedNetworkFragmentData {
+ return @ptrCast([*]ManagedNetworkFragmentData, @ptrCast([*]u8, self) + @sizeOf(ManagedNetworkTransmitData))[0..self.fragment_count];
+ }
+};
+
+pub const ManagedNetworkFragmentData = extern struct {
+ fragment_length: u32,
+ fragment_buffer: [*]u8,
+};
diff --git a/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
new file mode 100644
index 0000000000..492fe450ba
--- /dev/null
+++ b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
@@ -0,0 +1,25 @@
+const uefi = @import("std").os.uefi;
+const Handle = uefi.Handle;
+const Guid = uefi.Guid;
+
+pub const ManagedNetworkServiceBindingProtocol = extern struct {
+ _create_child: extern fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) usize,
+ _destroy_child: extern fn (*const ManagedNetworkServiceBindingProtocol, Handle) usize,
+
+ pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) usize {
+ return self._create_child(self, handle);
+ }
+
+ pub fn destroyChild(self: *const ManagedNetworkServiceBindingProtocol, handle: Handle) usize {
+ return self._destroy_child(self, handle);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0xf36ff770,
+ .time_mid = 0xa7e1,
+ .time_high_and_version = 0x42cf,
+ .clock_seq_high_and_reserved = 0x9e,
+ .clock_seq_low = 0xd2,
+ .node = [_]u8{ 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c },
+ };
+};
diff --git a/lib/std/os/uefi/protocols/simple_network_protocol.zig b/lib/std/os/uefi/protocols/simple_network_protocol.zig
new file mode 100644
index 0000000000..f5e62734b6
--- /dev/null
+++ b/lib/std/os/uefi/protocols/simple_network_protocol.zig
@@ -0,0 +1,172 @@
+const uefi = @import("std").os.uefi;
+const Event = uefi.Event;
+const Guid = uefi.Guid;
+
+pub const SimpleNetworkProtocol = extern struct {
+ revision: u64,
+ _start: extern fn (*const SimpleNetworkProtocol) usize,
+ _stop: extern fn (*const SimpleNetworkProtocol) usize,
+ _initialize: extern fn (*const SimpleNetworkProtocol, usize, usize) usize,
+ _reset: extern fn (*const SimpleNetworkProtocol, bool) usize,
+ _shutdown: extern fn (*const SimpleNetworkProtocol) usize,
+ _receive_filters: extern fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) usize,
+ _station_address: extern fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) usize,
+ _statistics: extern fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) usize,
+ _mcast_ip_to_mac: extern fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) usize,
+ _nvdata: extern fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) usize,
+ _get_status: extern fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) usize,
+ _transmit: extern fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) usize,
+ _receive: extern fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) usize,
+ wait_for_packet: Event,
+ mode: *SimpleNetworkMode,
+
+ /// Changes the state of a network interface from "stopped" to "started".
+ pub fn start(self: *const SimpleNetworkProtocol) usize {
+ return self._start(self);
+ }
+
+ /// Changes the state of a network interface from "started" to "stopped".
+ pub fn stop(self: *const SimpleNetworkProtocol) usize {
+ return self._stop(self);
+ }
+
+ /// Resets a network adapter and allocates the transmit and receive buffers required by the network interface.
+ pub fn initialize(self: *const SimpleNetworkProtocol, extra_rx_buffer_size: usize, extra_tx_buffer_size: usize) usize {
+ return self._initialize(self, extra_rx_buffer_size, extra_tx_buffer_size);
+ }
+
+ /// Resets a network adapter and reinitializes it with the parameters that were provided in the previous call to initialize().
+ pub fn reset(self: *const SimpleNetworkProtocol, extended_verification: bool) usize {
+ return self._reset(self, extended_verification);
+ }
+
+ /// Resets a network adapter and leaves it in a state that is safe for another driver to initialize.
+ pub fn shutdown(self: *const SimpleNetworkProtocol) usize {
+ return self._shutdown(self);
+ }
+
+ /// Manages the multicast receive filters of a network interface.
+ pub fn receiveFilters(self: *const SimpleNetworkProtocol, enable: SimpleNetworkReceiveFilter, disable: SimpleNetworkReceiveFilter, reset_mcast_filter: bool, mcast_filter_cnt: usize, mcast_filter: ?[*]const MacAddress) usize {
+ return self._receive_filters(self, enable, disable, reset_mcast_filter, mcast_filter_cnt, mcast_filter);
+ }
+
+ /// Modifies or resets the current station address, if supported.
+ pub fn stationAddress(self: *const SimpleNetworkProtocol, reset: bool, new: ?*const MacAddress) usize {
+ return self._station_address(self, reset, new);
+ }
+
+ /// Resets or collects the statistics on a network interface.
+ pub fn statistics(self: *const SimpleNetworkProtocol, reset_: bool, statistics_size: ?*usize, statistics_table: ?*NetworkStatistics) usize {
+ return self._statistics(self, reset_, statistics_size, statistics_table);
+ }
+
+ /// Converts a multicast IP address to a multicast HW MAC address.
+ pub fn mcastIpToMac(self: *const SimpleNetworkProtocol, ipv6: bool, ip: *const c_void, mac: *MacAddress) usize {
+ return self._mcast_ip_to_mac(self, ipv6, ip, mac);
+ }
+
+ /// Performs read and write operations on the NVRAM device attached to a network interface.
+ pub fn nvdata(self: *const SimpleNetworkProtocol, read_write: bool, offset: usize, buffer_size: usize, buffer: [*]u8) usize {
+ return self._nvdata(self, read_write, offset, buffer_size, buffer);
+ }
+
+ /// Reads the current interrupt status and recycled transmit buffer status from a network interface.
+ pub fn getStatus(self: *const SimpleNetworkProtocol, interrupt_status: *SimpleNetworkInterruptStatus, tx_buf: ?*?[*]u8) usize {
+ return self._get_status(self, interrupt_status, tx_buf);
+ }
+
+ /// Places a packet in the transmit queue of a network interface.
+ pub fn transmit(self: *const SimpleNetworkProtocol, header_size: usize, buffer_size: usize, buffer: [*]const u8, src_addr: ?*const MacAddress, dest_addr: ?*const MacAddress, protocol: ?*const u16) usize {
+ return self._transmit(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol);
+ }
+
+ /// Receives a packet from a network interface.
+ pub fn receive(self: *const SimpleNetworkProtocol, header_size: ?*usize, buffer_size: *usize, buffer: [*]u8, src_addr: ?*MacAddress, dest_addr: ?*MacAddress, protocol: ?*u16) usize {
+ return self._receive(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0xa19832b9,
+ .time_mid = 0xac25,
+ .time_high_and_version = 0x11d3,
+ .clock_seq_high_and_reserved = 0x9a,
+ .clock_seq_low = 0x2d,
+ .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
+ };
+};
+
+pub const MacAddress = [32]u8;
+
+pub const SimpleNetworkMode = extern struct {
+ state: SimpleNetworkState,
+ hw_address_size: u32,
+ media_header_size: u32,
+ max_packet_size: u32,
+ nvram_size: u32,
+ nvram_access_size: u32,
+ receive_filter_mask: SimpleNetworkReceiveFilter,
+ receive_filter_setting: SimpleNetworkReceiveFilter,
+ max_mcast_filter_count: u32,
+ mcast_filter_count: u32,
+ mcast_filter: [16]MacAddress,
+ current_address: MacAddress,
+ broadcast_address: MacAddress,
+ permanent_address: MacAddress,
+ if_type: u8,
+ mac_address_changeable: bool,
+ multiple_tx_supported: bool,
+ media_present_supported: bool,
+ media_present: bool,
+};
+
+pub const SimpleNetworkReceiveFilter = packed struct {
+ receive_unicast: bool,
+ receive_multicast: bool,
+ receive_broadcast: bool,
+ receive_promiscuous: bool,
+ receive_promiscuous_multicast: bool,
+ _pad: u27 = undefined,
+};
+
+pub const SimpleNetworkState = extern enum(u32) {
+ Stopped,
+ Started,
+ Initialized,
+};
+
+pub const NetworkStatistics = extern struct {
+ rx_total_frames: u64,
+ rx_good_frames: u64,
+ rx_undersize_frames: u64,
+ rx_oversize_frames: u64,
+ rx_dropped_frames: u64,
+ rx_unicast_frames: u64,
+ rx_broadcast_frames: u64,
+ rx_multicast_frames: u64,
+ rx_crc_error_frames: u64,
+ rx_total_bytes: u64,
+ tx_total_frames: u64,
+ tx_good_frames: u64,
+ tx_undersize_frames: u64,
+ tx_oversize_frames: u64,
+ tx_dropped_frames: u64,
+ tx_unicast_frames: u64,
+ tx_broadcast_frames: u64,
+ tx_multicast_frames: u64,
+ tx_crc_error_frames: u64,
+ tx_total_bytes: u64,
+ collisions: u64,
+ unsupported_protocol: u64,
+ rx_duplicated_frames: u64,
+ rx_decryptError_frames: u64,
+ tx_error_frames: u64,
+ tx_retry_frames: u64,
+};
+
+pub const SimpleNetworkInterruptStatus = packed struct {
+ receive_interrupt: bool,
+ transmit_interrupt: bool,
+ command_interrupt: bool,
+ software_interrupt: bool,
+ _pad: u28,
+};
diff --git a/lib/std/os/uefi/protocols/udp6_protocol.zig b/lib/std/os/uefi/protocols/udp6_protocol.zig
new file mode 100644
index 0000000000..266f2964f9
--- /dev/null
+++ b/lib/std/os/uefi/protocols/udp6_protocol.zig
@@ -0,0 +1,112 @@
+const uefi = @import("std").os.uefi;
+const Guid = uefi.Guid;
+const Event = uefi.Event;
+const Time = uefi.Time;
+const Ip6ModeData = uefi.protocols.Ip6ModeData;
+const Ip6Address = uefi.protocols.Ip6Address;
+const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
+const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
+
+pub const Udp6Protocol = extern struct {
+ _get_mode_data: extern fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
+ _configure: extern fn (*const Udp6Protocol, ?*const Udp6ConfigData) usize,
+ _groups: extern fn (*const Udp6Protocol, bool, ?*const Ip6Address) usize,
+ _transmit: extern fn (*const Udp6Protocol, *Udp6CompletionToken) usize,
+ _receive: extern fn (*const Udp6Protocol, *Udp6CompletionToken) usize,
+ _cancel: extern fn (*const Udp6Protocol, ?*Udp6CompletionToken) usize,
+ _poll: extern fn (*const Udp6Protocol) usize,
+
+ pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
+ return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data);
+ }
+
+ pub fn configure(self: *const Udp6Protocol, udp6_config_data: ?*const Udp6ConfigData) usize {
+ return self._configure(self, udp6_config_data);
+ }
+
+ pub fn groups(self: *const Udp6Protocol, join_flag: bool, multicast_address: ?*const Ip6Address) usize {
+ return self._groups(self, join_flag, multicast_address);
+ }
+
+ pub fn transmit(self: *const Udp6Protocol, token: *Udp6CompletionToken) usize {
+ return self._transmit(self, token);
+ }
+
+ pub fn receive(self: *const Udp6Protocol, token: *Udp6CompletionToken) usize {
+ return self._receive(self, token);
+ }
+
+ pub fn cancel(self: *const Udp6Protocol, token: ?*Udp6CompletionToken) usize {
+ return self._cancel(self, token);
+ }
+
+ pub fn poll(self: *const Udp6Protocol) usize {
+ return self._poll(self);
+ }
+
+ pub const guid align(8) = uefi.Guid{
+ .time_low = 0x4f948815,
+ .time_mid = 0xb4b9,
+ .time_high_and_version = 0x43cb,
+ .clock_seq_high_and_reserved = 0x8a,
+ .clock_seq_low = 0x33,
+ .node = [_]u8{ 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 },
+ };
+};
+
+pub const Udp6ConfigData = extern struct {
+ accept_promiscuous: bool,
+ accept_any_port: bool,
+ allow_duplicate_port: bool,
+ traffic_class: u8,
+ hop_limit: u8,
+ receive_timeout: u32,
+ transmit_timeout: u32,
+ station_address: Ip6Address,
+ station_port: u16,
+ remote_address: Ip6Address,
+ remote_port: u16,
+};
+
+pub const Udp6CompletionToken = extern struct {
+ event: Event,
+ status: usize,
+ packet: extern union {
+ RxData: *Udp6ReceiveData,
+ TxData: *Udp6TransmitData,
+ },
+};
+
+pub const Udp6ReceiveData = extern struct {
+ timestamp: Time,
+ recycle_signal: Event,
+ udp6_session: Udp6SessionData,
+ data_length: u32,
+ fragment_count: u32,
+
+ pub fn getFragments(self: *Udp6ReceiveData) []Udp6FragmentData {
+ return @ptrCast([*]Udp6FragmentData, @ptrCast([*]u8, self) + @sizeOf(Udp6ReceiveData))[0..self.fragment_count];
+ }
+};
+
+pub const Udp6TransmitData = extern struct {
+ udp6_session_data: ?*Udp6SessionData,
+ data_length: u32,
+ fragment_count: u32,
+
+ pub fn getFragments(self: *Udp6TransmitData) []Udp6FragmentData {
+ return @ptrCast([*]Udp6FragmentData, @ptrCast([*]u8, self) + @sizeOf(Udp6TransmitData))[0..self.fragment_count];
+ }
+};
+
+pub const Udp6SessionData = extern struct {
+ source_address: Ip6Address,
+ source_port: u16,
+ destination_address: Ip6Address,
+ destination_port: u16,
+};
+
+pub const Udp6FragmentData = extern struct {
+ fragment_length: u32,
+ fragment_buffer: [*]u8,
+};
diff --git a/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
new file mode 100644
index 0000000000..2f499b50c6
--- /dev/null
+++ b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
@@ -0,0 +1,25 @@
+const uefi = @import("std").os.uefi;
+const Handle = uefi.Handle;
+const Guid = uefi.Guid;
+
+pub const Udp6ServiceBindingProtocol = extern struct {
+ _create_child: extern fn (*const Udp6ServiceBindingProtocol, *?Handle) usize,
+ _destroy_child: extern fn (*const Udp6ServiceBindingProtocol, Handle) usize,
+
+ pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) usize {
+ return self._create_child(self, handle);
+ }
+
+ pub fn destroyChild(self: *const Udp6ServiceBindingProtocol, handle: Handle) usize {
+ return self._destroy_child(self, handle);
+ }
+
+ pub const guid align(8) = Guid{
+ .time_low = 0x66ed4721,
+ .time_mid = 0x3c98,
+ .time_high_and_version = 0x4d3e,
+ .clock_seq_high_and_reserved = 0x81,
+ .clock_seq_low = 0xe3,
+ .node = [_]u8{ 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 },
+ };
+};
From 78b54d9c96c84e286b20a2a144eca0b9ddc3fba5 Mon Sep 17 00:00:00 2001
From: Nick Erdmann
Date: Thu, 7 Nov 2019 02:49:45 +0100
Subject: [PATCH 015/129] std/os/uefi: protocol handling improvements
---
lib/std/os/uefi/tables.zig | 3 ++
lib/std/os/uefi/tables/boot_services.zig | 49 ++++++++++++++++++++----
lib/std/os/uefi/tables/system_table.zig | 1 +
3 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/lib/std/os/uefi/tables.zig b/lib/std/os/uefi/tables.zig
index c66a50802a..d34408dfba 100644
--- a/lib/std/os/uefi/tables.zig
+++ b/lib/std/os/uefi/tables.zig
@@ -1,8 +1,11 @@
pub const BootServices = @import("tables/boot_services.zig").BootServices;
pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;
pub const global_variable align(8) = @import("tables/runtime_services.zig").global_variable;
+pub const LocateSearchType = @import("tables/boot_services.zig").LocateSearchType;
pub const MemoryDescriptor = @import("tables/boot_services.zig").MemoryDescriptor;
pub const MemoryType = @import("tables/boot_services.zig").MemoryType;
+pub const OpenProtocolAttributes = @import("tables/boot_services.zig").OpenProtocolAttributes;
+pub const ProtocolInformationEntry = @import("tables/boot_services.zig").ProtocolInformationEntry;
pub const ResetType = @import("tables/runtime_services.zig").ResetType;
pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;
pub const SystemTable = @import("tables/system_table.zig").SystemTable;
diff --git a/lib/std/os/uefi/tables/boot_services.zig b/lib/std/os/uefi/tables/boot_services.zig
index e6c37936b9..2358b4f842 100644
--- a/lib/std/os/uefi/tables/boot_services.zig
+++ b/lib/std/os/uefi/tables/boot_services.zig
@@ -30,10 +30,11 @@ pub const BootServices = extern struct {
/// Allocates pool memory.
allocatePool: extern fn (MemoryType, usize, *align(8) [*]u8) usize,
- freePool: usize, // TODO
+ /// Returns pool memory to the system.
+ freePool: extern fn ([*]align(8) u8) usize,
/// Creates an event.
- createEvent: extern fn (u32, usize, ?extern fn (Event, ?*const c_void) void, ?*const c_void, *Event) usize,
+ createEvent: extern fn (u32, usize, ?extern fn (Event, ?*c_void) void, ?*const c_void, *Event) usize,
/// Sets the type of timer and the trigger time for a timer event.
setTimer: extern fn (Event, TimerDelay, u64) usize,
@@ -47,7 +48,9 @@ pub const BootServices = extern struct {
/// Closes an event.
closeEvent: extern fn (Event) usize,
- checkEvent: usize, // TODO
+ /// Checks whether an event is in the signaled state.
+ checkEvent: extern fn (Event) usize,
+
installProtocolInterface: usize, // TODO
reinstallProtocolInterface: usize, // TODO
uninstallProtocolInterface: usize, // TODO
@@ -87,11 +90,20 @@ pub const BootServices = extern struct {
connectController: usize, // TODO
disconnectController: usize, // TODO
- openProtocol: usize, // TODO
- closeProtocol: usize, // TODO
- openProtocolInformation: usize, // TODO
+
+ /// Queries a handle to determine if it supports a specified protocol.
+ openProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) usize,
+
+ /// Closes a protocol on a handle that was opened using openProtocol().
+ closeProtocol: extern fn (Handle, *align(8) const Guid, Handle, ?Handle) usize,
+
+ /// Retrieves the list of agents that currently have a protocol interface opened.
+ openProtocolInformation: extern fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) usize,
+
protocolsPerHandle: usize, // TODO
- locateHandleBuffer: usize, // TODO
+
+ /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.
+ locateHandleBuffer: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) usize,
/// Returns the first protocol instance that matches the given protocol.
locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) usize,
@@ -167,3 +179,26 @@ pub const MemoryDescriptor = extern struct {
memory_runtime: bool,
},
};
+
+pub const LocateSearchType = extern enum(u32) {
+ AllHandles,
+ ByRegisterNotify,
+ ByProtocol,
+};
+
+pub const OpenProtocolAttributes = packed struct {
+ by_handle_protocol: bool,
+ get_protocol: bool,
+ test_protocol: bool,
+ by_child_controller: bool,
+ by_driver: bool,
+ exclusive: bool,
+ _pad: u26,
+};
+
+pub const ProtocolInformationEntry = extern struct {
+ agent_handle: ?Handle,
+ controller_handle: ?Handle,
+ attributes: OpenProtocolAttributes,
+ open_count: u32,
+};
diff --git a/lib/std/os/uefi/tables/system_table.zig b/lib/std/os/uefi/tables/system_table.zig
index 6ace8e4001..3e0fd589e3 100644
--- a/lib/std/os/uefi/tables/system_table.zig
+++ b/lib/std/os/uefi/tables/system_table.zig
@@ -17,6 +17,7 @@ const TableHeader = uefi.tables.TableHeader;
/// hdr.crc32 must be recomputed.
pub const SystemTable = extern struct {
hdr: TableHeader,
+
/// A null-terminated string that identifies the vendor that produces the system firmware of the platform.
firmware_vendor: [*]u16,
firmware_revision: u32,
From 528908a06e9663a5e6595fc5ff80e017c663dc76 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Wed, 6 Nov 2019 22:49:24 +0100
Subject: [PATCH 016/129] Fix ptrCast of array references to fn
Closes #3607
---
src/codegen.cpp | 12 ++++--------
test/stage1/behavior/cast.zig | 6 ++++++
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 154c21893a..7d3ae656fb 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -7050,16 +7050,12 @@ check: switch (const_val->special) {
case ZigTypeIdEnum:
return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_enum_tag);
case ZigTypeIdFn:
- if (const_val->data.x_ptr.special == ConstPtrSpecialFunction) {
- assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
- return fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry);
- } else if (const_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
- uint64_t addr = const_val->data.x_ptr.data.hard_coded_addr.addr;
- return LLVMConstIntToPtr(LLVMConstInt(usize_type_ref, addr, false), get_llvm_type(g, type_entry));
- } else {
+ if (const_val->data.x_ptr.special == ConstPtrSpecialFunction &&
+ const_val->data.x_ptr.mut != ConstPtrMutComptimeConst) {
zig_unreachable();
}
+ // Treat it the same as we do for pointers
+ return gen_const_val_ptr(g, const_val, name);
case ZigTypeIdPointer:
return gen_const_val_ptr(g, const_val, name);
case ZigTypeIdErrorUnion:
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 6bc8540b7d..e5650bc3fc 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -559,3 +559,9 @@ test "peer cast *[0]T to []const T" {
var y = if (b) &[0]u8{} else buf;
expect(mem.eql(u8, "abcde", y));
}
+
+var global_array: [4]u8 = undefined;
+test "cast from array reference to fn" {
+ const f = @ptrCast(extern fn () void, &global_array);
+ expect(@ptrToInt(f) == @ptrToInt(&global_array));
+}
From cf6fb89ced7d0f03b511dba19f02af4a87a70b62 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Wed, 6 Nov 2019 23:15:19 +0100
Subject: [PATCH 017/129] Add small tokenizer test case for #3468
---
lib/std/zig/tokenizer.zig | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index 672bd482da..19488ba873 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -1625,6 +1625,16 @@ test "tokenizer - UTF-8 BOM is recognized and skipped" {
});
}
+test "correctly parse pointer assignment" {
+ testTokenize("b.*=3;\n", [_]Token.Id{
+ Token.Id.Identifier,
+ Token.Id.PeriodAsterisk,
+ Token.Id.Equal,
+ Token.Id.IntegerLiteral,
+ Token.Id.Semicolon,
+ });
+}
+
fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
var tokenizer = Tokenizer.init(source);
for (expected_tokens) |expected_token_id| {
From 2e52fafac50b545b5ef7dce42d0827e8077a8698 Mon Sep 17 00:00:00 2001
From: Shawn Landden
Date: Wed, 6 Nov 2019 20:00:39 -0800
Subject: [PATCH 018/129] correctly use llvm undef in release modes
---
src/codegen.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 7d3ae656fb..89c41b61cc 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -5128,7 +5128,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
bool val_is_undef = value_is_all_undef(g, &instruction->byte->value);
LLVMValueRef fill_char;
- if (val_is_undef) {
+ if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.scope)) {
fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
} else {
fill_char = ir_llvm_value(g, instruction->byte);
From 92dac89d019fcd91aa043a116d6a6e166da8c4b2 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 09:23:02 -0600
Subject: [PATCH 019/129] lock the mutex on pthread_cond_signal()
---
lib/std/parker.zig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 2dc38d2b38..8df6dcaa92 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -199,6 +199,8 @@ const PosixParker = struct {
}
pub fn unpark(self: *PosixParker, ptr: *const u32) void {
+ assert(pthread_mutex_lock(&self.mutex) == 0);
+ defer assert(pthread_mutex_unlock(&self.mutex) == 0);
assert(pthread_cond_signal(&self.cond) == 0);
}
From 3858a526e32cc661f7b0fdd0f40edb184d7c9209 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Thu, 7 Nov 2019 17:02:21 +0200
Subject: [PATCH 020/129] make callMainAsync async
---
lib/std/special/start.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/special/start.zig b/lib/std/special/start.zig
index 5c4d77b694..c56d50d7c4 100644
--- a/lib/std/special/start.zig
+++ b/lib/std/special/start.zig
@@ -214,7 +214,7 @@ inline fn initEventLoopAndCallMain() u8 {
return @inlineCall(callMain);
}
-fn callMainAsync(loop: *std.event.Loop) u8 {
+async fn callMainAsync(loop: *std.event.Loop) u8 {
// This prevents the event loop from terminating at least until main() has returned.
loop.beginOneEvent();
defer loop.finishOneEvent();
From 459a364a33def68dbd46bce0f25bbf41eb4b7d22 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Thu, 7 Nov 2019 09:06:22 +0200
Subject: [PATCH 021/129] allow Group to optionally manage function frames'
memory
---
lib/std/event/group.zig | 41 ++++++++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/lib/std/event/group.zig b/lib/std/event/group.zig
index f073bb3df2..77dd2cd1aa 100644
--- a/lib/std/event/group.zig
+++ b/lib/std/event/group.zig
@@ -8,7 +8,7 @@ const Allocator = std.mem.Allocator;
pub fn Group(comptime ReturnType: type) type {
return struct {
frame_stack: Stack,
- alloc_stack: Stack,
+ alloc_stack: AllocStack,
lock: Lock,
allocator: *Allocator,
@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {
else => void,
};
const Stack = std.atomic.Stack(anyframe->ReturnType);
+ const AllocStack = std.atomic.Stack(Node);
+
+ pub const Node = struct {
+ bytes: []const u8 = [0]u8{},
+ handle: anyframe->ReturnType,
+ };
pub fn init(allocator: *Allocator) Self {
return Self{
.frame_stack = Stack.init(),
- .alloc_stack = Stack.init(),
+ .alloc_stack = AllocStack.init(),
.lock = Lock.init(),
.allocator = allocator,
};
@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {
/// Add a frame to the group. Thread-safe.
pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {
- const node = try self.allocator.create(Stack.Node);
- node.* = Stack.Node{
+ const node = try self.allocator.create(AllocStack.Node);
+ node.* = AllocStack.Node{
.next = undefined,
- .data = handle,
+ .data = Node{
+ .handle = handle,
+ },
};
self.alloc_stack.push(node);
}
@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {
self.frame_stack.push(node);
}
+ /// This is equivalent to adding a frame to the group but the memory of its frame is
+ /// allocated by the group and freed by `wait`.
+ /// `func` must be async and have return type `ReturnType`.
+ /// Thread-safe.
+ pub fn call(self: *Self, comptime func: var, args: ...) error{OutOfMemory}!void {
+ var frame = try self.allocator.create(@Frame(func));
+ const node = try self.allocator.create(AllocStack.Node);
+ node.* = AllocStack.Node{
+ .next = undefined,
+ .data = Node{
+ .handle = frame,
+ .bytes = @sliceToBytes((*[1]@Frame(func))(frame)[0..]),
+ },
+ };
+ frame.* = async func(args);
+ self.alloc_stack.push(node);
+ }
+
/// Wait for all the calls and promises of the group to complete.
/// Thread-safe.
/// Safe to call any number of times.
@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {
}
}
while (self.alloc_stack.pop()) |node| {
- const handle = node.data;
- self.allocator.destroy(node);
+ const handle = node.data.handle;
if (Error == void) {
await handle;
} else {
@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {
result = err;
};
}
+ self.allocator.free(node.data.bytes);
+ self.allocator.destroy(node);
}
return result;
}
From e2a0bea65fb4ce1fe3d3ff41c98d8fb5cead3c9d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 13:48:38 -0500
Subject: [PATCH 022/129] ci: bump ubuntu from 16.04 to 18.04
---
ci/azure/pipelines.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ci/azure/pipelines.yml b/ci/azure/pipelines.yml
index d2cd30cc7c..5dbfe5a338 100644
--- a/ci/azure/pipelines.yml
+++ b/ci/azure/pipelines.yml
@@ -14,7 +14,7 @@ jobs:
displayName: 'Build and test'
- job: BuildLinux
pool:
- vmImage: 'ubuntu-16.04'
+ vmImage: 'ubuntu-18.04'
timeoutInMinutes: 360
@@ -53,7 +53,7 @@ jobs:
strategy:
maxParallel: 1
pool:
- vmImage: 'ubuntu-16.04'
+ vmImage: 'ubuntu-18.04'
variables:
version: $[ dependencies.BuildLinux.outputs['main.version'] ]
steps:
From b535e86cc0e86e76471aebd731566ae140098a07 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 15:32:20 -0600
Subject: [PATCH 023/129] move SpinLock definitions around
---
lib/std/c.zig | 1 +
lib/std/mutex.zig | 17 +++++++++--------
lib/std/os.zig | 10 ++++++++++
lib/std/os/linux.zig | 4 ++++
lib/std/spinlock.zig | 37 +++++++++++++++----------------------
5 files changed, 39 insertions(+), 30 deletions(-)
diff --git a/lib/std/c.zig b/lib/std/c.zig
index 71e111a61d..201aa6b103 100644
--- a/lib/std/c.zig
+++ b/lib/std/c.zig
@@ -158,6 +158,7 @@ pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_self() pthread_t;
+pub extern "c" fn pthread_yield() c_int;
pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
pub extern "c" fn kqueue() c_int;
diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig
index 26f0142c7c..110f581f5e 100644
--- a/lib/std/mutex.zig
+++ b/lib/std/mutex.zig
@@ -46,11 +46,11 @@ else struct {
const Locked = 2;
/// number of iterations to spin yielding the cpu
- const SpinCpu = 4;
+ const SPIN_CPU = 4;
/// number of iterations to perform in the cpu yield loop
- const SpinCpuCount = 30;
+ const SPIN_CPU_COUNT = 30;
/// number of iterations to spin yielding the thread
- const SpinThread = 1;
+ const SPIN_THREAD = 1;
pub fn init() Mutex {
return Mutex{
@@ -86,20 +86,21 @@ else struct {
while (true) {
// try and acquire the lock using cpu spinning on failure
- for (([SpinCpu]void)(undefined)) |_| {
+ var spin: usize = 0;
+ while (spin < SPIN_CPU) : (spin += 1) {
var value = @atomicLoad(u32, &self.state, .Monotonic);
while (value == Unlocked)
value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
- for (([SpinCpuCount]void)(undefined)) |_|
- SpinLock.yieldCpu();
+ SpinLock.yield(SPIN_CPU_COUNT);
}
// try and acquire the lock using thread rescheduling on failure
- for (([SpinThread]void)(undefined)) |_| {
+ spin = 0;
+ while (spin < SPIN_THREAD) : (spin += 1) {
var value = @atomicLoad(u32, &self.state, .Monotonic);
while (value == Unlocked)
value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
- SpinLock.yieldThread();
+ std.os.yield();
}
// failed to acquire the lock, go to sleep until woken up by `Held.release()`
diff --git a/lib/std/os.zig b/lib/std/os.zig
index efddc9aafb..72dd2a7196 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -3169,3 +3169,13 @@ pub fn dn_expand(
}
return error.InvalidDnsPacket;
}
+
+pub fn yield() void {
+ switch (builtin.os) {
+ .windows => _ = windows.kernel32.SwitchToThread(),
+ .linux => _ = assert(linux.sched_yield() == 0),
+ else => if (builtin.link_libc) {
+ assert(std.c.pthread_yield() == 0);
+ },
+ }
+}
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index d9f1f4e311..a7dedefb43 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -954,6 +954,10 @@ pub fn fremovexattr(fd: usize, name: [*]const u8) usize {
return syscall2(SYS_fremovexattr, fd, @ptrToInt(name));
}
+pub fn sched_yield() usize {
+ return syscall0(SYS_sched_yield);
+}
+
pub fn sched_getaffinity(pid: i32, size: usize, set: *cpu_set_t) usize {
const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, isize(pid)), size, @ptrToInt(set));
if (@bitCast(isize, rc) < 0) return rc;
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index dadf96cef5..55b92f51d1 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -28,22 +28,17 @@ pub const SpinLock = struct {
return Held{ .spinlock = self };
}
- pub fn yieldCpu() void {
- switch (builtin.arch) {
- .i386, .x86_64 => asm volatile("pause" ::: "memory"),
- // .arm, .aarch64 => asm volatile("yield"),
- //
- // Causes CI to fail
- // See: https://github.com/ziglang/zig/pull/3585#issuecomment-549962765
- else => time.sleep(0),
- }
- }
-
- pub fn yieldThread() void {
- switch (builtin.os) {
- .linux => assert(linux.syscall0(linux.SYS_sched_yield) == 0),
- .windows => _ = windows.kernel32.SwitchToThread(),
- else => time.sleep(1 * time.microsecond),
+ pub fn yield(iterations: usize) void {
+ var i = iterations;
+ while (i != 0) : (i -= 1) {
+ switch (builtin.arch) {
+ .i386, .x86_64 => asm volatile("pause" ::: "memory"),
+ // .arm, .aarch64 => asm volatile("yield"),
+ //
+ // Causes CI to fail
+ // See: https://github.com/ziglang/zig/pull/3585#issuecomment-549962765
+ else => time.sleep(0),
+ }
}
}
@@ -55,16 +50,14 @@ pub const SpinLock = struct {
return @This(){ .iteration = 0 };
}
- /// Hybrid yielding from
+ /// Modified hybrid yielding from
/// http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
pub fn yield(self: *@This()) void {
defer self.iteration +%= 1;
- if (self.iteration < 10) {
- yieldCpu();
- } else if (self.iteration < 20) {
- for (([30]void)(undefined)) |_| yieldCpu();
+ if (self.iteration < 20) {
+ SpinLock.yield(self.iteration);
} else if (self.iteration < 24) {
- yieldThread();
+ os.yield();
} else if (self.iteration < 26) {
time.sleep(1 * time.millisecond);
} else {
From b5d84635f20a891cea55174771b630099bb3860d Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 15:46:57 -0600
Subject: [PATCH 024/129] remove WaitOnAddress backend in std.ThreadParker
---
lib/std/os/windows/kernel32.zig | 4 --
lib/std/parker.zig | 116 +++++++-------------------------
2 files changed, 24 insertions(+), 96 deletions(-)
diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig
index 97c5a5b695..d466f9946d 100644
--- a/lib/std/os/windows/kernel32.zig
+++ b/lib/std/os/windows/kernel32.zig
@@ -82,8 +82,6 @@ pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR
pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD;
-pub extern "kernel32" stdcallcc fn GetModuleHandleA(lpModuleName: ?[*]const CHAR) ?HMODULE;
-
pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE;
pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
@@ -206,8 +204,6 @@ pub extern "kernel32" stdcallcc fn WriteFile(
pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL;
-pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: [*]const u8) ?HMODULE;
-
pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE;
pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC;
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 8df6dcaa92..7c0a7a65f8 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -76,107 +76,39 @@ const WindowsParker = struct {
pub fn deinit(self: *WindowsParker) void {}
pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
- switch (Backend.get().*) {
- .WaitAddress => |*backend| backend.unpark(ptr, &self.waiters),
- .KeyedEvent => |*backend| backend.unpark(ptr, &self.waiters),
+ const handle = getEventHandlePtr().*;
+ const key = @ptrCast(*const c_void, ptr);
+ var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
+ while (waiting != 0) {
+ waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
+ const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
+ assert(rc == 0);
+ return;
+ };
}
}
pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
- switch (Backend.get().*) {
- .WaitAddress => |*backend| backend.park(ptr, expected, &self.waiters),
- .KeyedEvent => |*backend| backend.park(ptr, expected, &self.waiters),
+ const handle = getEventHandlePtr().*;
+ const key = @ptrCast(*const c_void, ptr);
+ while (@atomicLoad(u32, ptr, .Acquire) == expected) {
+ _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
+ const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
+ assert(rc == 0);
}
}
- const Backend = union(enum) {
- WaitAddress: WaitAddress,
- KeyedEvent: KeyedEvent,
+ var event_handle = std.lazyInit(windows.HANDLE);
- var backend = std.lazyInit(Backend);
-
- fn get() *const Backend {
- return backend.get() orelse {
- // Statically linking to the KeyedEvent functions should mean its supported.
- // TODO: Maybe add a CreateSemaphore backend for systems older than Windows XP ?
- backend.data = WaitAddress.init()
- orelse KeyedEvent.init()
- orelse unreachable;
- backend.resolve();
- return &backend.data;
- };
- }
-
- const WaitAddress = struct {
- WakeByAddressSingle: stdcallcc fn(Address: *const c_void) void,
- WaitOnAddress: stdcallcc fn (
- Address: *const c_void,
- CompareAddress: *const c_void,
- AddressSize: windows.SIZE_T,
- dwMilliseconds: windows.DWORD,
- ) windows.BOOL,
-
- fn init() ?Backend {
- const dll_name = c"api-ms-win-core-synch-l1-2-0";
- const dll = windows.kernel32.GetModuleHandleA(dll_name)
- orelse windows.kernel32.LoadLibraryA(dll_name)
- orelse return null;
-
- var self: WaitAddress = undefined;
- const WaitOnAddress = windows.kernel32.GetProcAddress(dll, c"WaitOnAddress") orelse return null;
- self.WaitOnAddress = @intToPtr(@typeOf(self.WaitOnAddress), @ptrToInt(WaitOnAddress));
- const WakeByAddressSingle = windows.kernel32.GetProcAddress(dll, c"WakeByAddressSingle") orelse return null;
- self.WakeByAddressSingle = @intToPtr(@typeOf(self.WakeByAddressSingle), @ptrToInt(WakeByAddressSingle));
- return Backend{ .WaitAddress = self };
- }
-
- fn unpark(self: WaitAddress, ptr: *const u32, waiters: *u32) void {
- const addr = @ptrCast(*const c_void, ptr);
- self.WakeByAddressSingle(addr);
- }
-
- fn park(self: WaitAddress, ptr: *const u32, expected: u32, waiters: *u32) void {
- var compare = expected;
- const addr = @ptrCast(*const c_void, ptr);
- const cmp = @ptrCast(*const c_void, &compare);
- while (@atomicLoad(u32, ptr, .Acquire) == expected)
- _ = self.WaitOnAddress(addr, cmp, @sizeOf(u32), windows.INFINITE);
- }
+ fn getEventHandlePtr() *const windows.HANDLE {
+ return event_handle.get() orelse {
+ const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
+ if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
+ @panic("Failed to setup an NT Keyed Event handle for the process");
+ event_handle.resolve();
+ return &event_handle.data;
};
-
- const KeyedEvent = struct {
- handle: windows.HANDLE,
-
- fn init() ?Backend {
- var self: KeyedEvent = undefined;
- const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
- if (windows.ntdll.NtCreateKeyedEvent(&self.handle, access_mask, null, 0) != 0)
- return null;
- return Backend{ .KeyedEvent = self };
- }
-
- fn unpark(self: KeyedEvent, ptr: *const u32, waiters: *u32) void {
- const key = @ptrCast(*const c_void, ptr);
- var waiting = @atomicLoad(u32, waiters, .Acquire);
- while (waiting != 0) {
- waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
- const rc = windows.ntdll.NtReleaseKeyedEvent(self.handle, key, windows.FALSE, null);
- assert(rc == 0);
- return;
- };
- }
- }
-
- fn park(self: KeyedEvent, ptr: *const u32, expected: u32, waiters: *u32) void {
- const key = @ptrCast(*const c_void, ptr);
- while (@atomicLoad(u32, ptr, .Acquire) == expected) {
- _ = @atomicRmw(u32, waiters, .Add, 1, .Release);
- const rc = windows.ntdll.NtWaitForKeyedEvent(self.handle, key, windows.FALSE, null);
- assert(rc == 0);
- }
- }
- };
- };
+ }
};
const PosixParker = struct {
From f41e58d015eec5fa595b4df8af3cf6a2b598bb02 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 15:51:20 -0600
Subject: [PATCH 025/129] fix SpinLock.yield for pull/3626
---
lib/std/spinlock.zig | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 55b92f51d1..f69aae1bec 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -32,11 +32,8 @@ pub const SpinLock = struct {
var i = iterations;
while (i != 0) : (i -= 1) {
switch (builtin.arch) {
- .i386, .x86_64 => asm volatile("pause" ::: "memory"),
- // .arm, .aarch64 => asm volatile("yield"),
- //
- // Causes CI to fail
- // See: https://github.com/ziglang/zig/pull/3585#issuecomment-549962765
+ .i386, .x86_64 => asm volatile("pause"),
+ .arm, .aarch64 => asm volatile("yield"),
else => time.sleep(0),
}
}
From 12e68cbeb636c920475b2420314c23de37689509 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 16:33:25 -0600
Subject: [PATCH 026/129] pthread_sched_yield -> sched_yield
---
lib/std/c.zig | 3 ++-
lib/std/mutex.zig | 2 +-
lib/std/os.zig | 14 +++++++-------
lib/std/spinlock.zig | 2 +-
4 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/std/c.zig b/lib/std/c.zig
index 201aa6b103..26fa71fe68 100644
--- a/lib/std/c.zig
+++ b/lib/std/c.zig
@@ -158,7 +158,6 @@ pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_self() pthread_t;
-pub extern "c" fn pthread_yield() c_int;
pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
pub extern "c" fn kqueue() c_int;
@@ -201,3 +200,5 @@ pub extern "c" fn dn_expand(
exp_dn: [*]u8,
length: c_int,
) c_int;
+
+pub extern "c" fn sched_yield() c_int;
diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig
index 110f581f5e..5387bd4b15 100644
--- a/lib/std/mutex.zig
+++ b/lib/std/mutex.zig
@@ -100,7 +100,7 @@ else struct {
var value = @atomicLoad(u32, &self.state, .Monotonic);
while (value == Unlocked)
value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
- std.os.yield();
+ std.os.sched_yield();
}
// failed to acquire the lock, go to sleep until woken up by `Held.release()`
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 72dd2a7196..2f19ee2a7d 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -3170,12 +3170,12 @@ pub fn dn_expand(
return error.InvalidDnsPacket;
}
-pub fn yield() void {
- switch (builtin.os) {
- .windows => _ = windows.kernel32.SwitchToThread(),
- .linux => _ = assert(linux.sched_yield() == 0),
- else => if (builtin.link_libc) {
- assert(std.c.pthread_yield() == 0);
- },
+pub fn sched_yield() void {
+ if (builtin.os == .windows) {
+ _ = windows.kernel32.SwitchToThread();
+ } else if (builtin.os == .linux and !builtin.link_libc) {
+ assert(linux.sched_yield() == 0);
+ } else if (builtin.link_libc) {
+ assert(std.c.sched_yield() == 0);
}
}
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index f69aae1bec..f2f2833875 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -54,7 +54,7 @@ pub const SpinLock = struct {
if (self.iteration < 20) {
SpinLock.yield(self.iteration);
} else if (self.iteration < 24) {
- os.yield();
+ os.sched_yield();
} else if (self.iteration < 26) {
time.sleep(1 * time.millisecond);
} else {
From bb4abfdc78b527b315950ce9f233518cdaa6a72a Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 16:36:33 -0600
Subject: [PATCH 027/129] Use `system` instead of `builtin.link_libc`
---
lib/std/os.zig | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 2f19ee2a7d..d9355490f7 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -3171,11 +3171,8 @@ pub fn dn_expand(
}
pub fn sched_yield() void {
- if (builtin.os == .windows) {
- _ = windows.kernel32.SwitchToThread();
- } else if (builtin.os == .linux and !builtin.link_libc) {
- assert(linux.sched_yield() == 0);
- } else if (builtin.link_libc) {
- assert(std.c.sched_yield() == 0);
+ switch (builtin.os) {
+ .windows => _ = windows.kernel32.SwitchToThread(),
+ else => assert(system.sched_yield() == 0),
}
}
From fe8c1cf804c3c39e57ca291baf005b862fc3ba94 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 17:14:08 -0600
Subject: [PATCH 028/129] missing `os` declaration
---
lib/std/spinlock.zig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index f2f2833875..b374eba3eb 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -2,8 +2,7 @@ const std = @import("std.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
const time = std.time;
-const linux = std.os.linux;
-const windows = std.os.windows;
+const os = std.os;
pub const SpinLock = struct {
lock: u8, // TODO use a bool or enum
From 9b0536e6f43ba916b2b488377f1e87d0ecf4ccf9 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 19:00:52 -0500
Subject: [PATCH 029/129] ci: add srht oauth token to drone cloud script
---
ci/drone/drone.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ci/drone/drone.yml b/ci/drone/drone.yml
index 474f5b6d09..8fff358a93 100644
--- a/ci/drone/drone.yml
+++ b/ci/drone/drone.yml
@@ -9,6 +9,8 @@ steps:
- name: build-and-test
image: ziglang/static-base:llvm9-1
environment:
+ SRHT_OAUTH_TOKEN:
+ from_secret: SRHT_OAUTH_TOKEN
AWS_ACCESS_KEY_ID:
from_secret: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
From 43900011f7379e61564196141a687a2b8352d27f Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 18:56:43 -0600
Subject: [PATCH 030/129] handle NtCreateKeyedEvent failure by spinning to
ensure correctness
---
lib/std/parker.zig | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 7c0a7a65f8..11d3f749de 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -1,5 +1,6 @@
const std = @import("std.zig");
const builtin = @import("builtin");
+const time = std.time;
const testing = std.testing;
const assert = std.debug.assert;
const SpinLock = std.SpinLock;
@@ -76,12 +77,13 @@ const WindowsParker = struct {
pub fn deinit(self: *WindowsParker) void {}
pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
- const handle = getEventHandlePtr().*;
const key = @ptrCast(*const c_void, ptr);
+ const handle_ptr = getEventHandlePtr() orelse return;
+
var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
while (waiting != 0) {
waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
- const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
+ const rc = windows.ntdll.NtReleaseKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
assert(rc == 0);
return;
};
@@ -89,22 +91,27 @@ const WindowsParker = struct {
}
pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
- const handle = getEventHandlePtr().*;
+ var spin = SpinLock.Backoff.init();
const key = @ptrCast(*const c_void, ptr);
+
while (@atomicLoad(u32, ptr, .Acquire) == expected) {
- _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
- const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
- assert(rc == 0);
+ if (getEventHandlePtr()) |handle_ptr| {
+ _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
+ const rc = windows.ntdll.NtWaitForKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
+ assert(rc == 0);
+ } else {
+ spin.yield();
+ }
}
}
var event_handle = std.lazyInit(windows.HANDLE);
- fn getEventHandlePtr() *const windows.HANDLE {
+ fn getEventHandlePtr() ?*const windows.HANDLE {
return event_handle.get() orelse {
const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
- @panic("Failed to setup an NT Keyed Event handle for the process");
+ return null;
event_handle.resolve();
return &event_handle.data;
};
From e2189b6e5d5a5644eb937b682cdfe4e658fe27e8 Mon Sep 17 00:00:00 2001
From: kprotty
Date: Thu, 7 Nov 2019 19:37:53 -0600
Subject: [PATCH 031/129] cleanup getEventHandle
---
lib/std/parker.zig | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 11d3f749de..036fe160ce 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -78,12 +78,12 @@ const WindowsParker = struct {
pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
const key = @ptrCast(*const c_void, ptr);
- const handle_ptr = getEventHandlePtr() orelse return;
+ const handle = getEventHandle() orelse return;
var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
while (waiting != 0) {
waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
- const rc = windows.ntdll.NtReleaseKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
+ const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0);
return;
};
@@ -92,12 +92,13 @@ const WindowsParker = struct {
pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
var spin = SpinLock.Backoff.init();
+ const ev_handle = getEventHandle();
const key = @ptrCast(*const c_void, ptr);
- while (@atomicLoad(u32, ptr, .Acquire) == expected) {
- if (getEventHandlePtr()) |handle_ptr| {
+ while (@atomicLoad(u32, ptr, .Monotonic) == expected) {
+ if (ev_handle) |handle| {
_ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
- const rc = windows.ntdll.NtWaitForKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
+ const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0);
} else {
spin.yield();
@@ -107,14 +108,15 @@ const WindowsParker = struct {
var event_handle = std.lazyInit(windows.HANDLE);
- fn getEventHandlePtr() ?*const windows.HANDLE {
- return event_handle.get() orelse {
- const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
- if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
- return null;
- event_handle.resolve();
- return &event_handle.data;
- };
+ fn getEventHandle() ?windows.HANDLE {
+ if (event_handle.get()) |handle_ptr|
+ return handle_ptr.*;
+ defer event_handle.resolve();
+
+ const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
+ if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
+ return null;
+ return event_handle.data;
}
};
From 2723ffc2b2d837aec8185f86814a6e6aba45c34d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Nov 2019 01:52:23 -0500
Subject: [PATCH 032/129] fixups and zig fmt
---
lib/std/c.zig | 22 +++-
lib/std/c/darwin.zig | 16 +++
lib/std/c/dragonfly.zig | 13 ++-
lib/std/c/emscripten.zig | 8 ++
lib/std/c/freebsd.zig | 12 ++
lib/std/c/fuchsia.zig | 8 ++
lib/std/c/haiku.zig | 14 +++
lib/std/c/hermit.zig | 6 +
lib/std/c/linux.zig | 23 ++++
lib/std/c/minix.zig | 18 +++
lib/std/c/netbsd.zig | 29 +++++
lib/std/c/openbsd.zig | 6 +
lib/std/c/solaris.zig | 15 +++
lib/std/mutex.zig | 131 ++++++++++-----------
lib/std/os.zig | 20 +++-
lib/std/os/bits.zig | 3 -
lib/std/os/bits/darwin.zig | 5 -
lib/std/os/bits/dragonfly.zig | 11 +-
lib/std/os/bits/freebsd.zig | 5 -
lib/std/os/bits/linux.zig | 5 -
lib/std/os/bits/netbsd.zig | 6 -
lib/std/parker.zig | 206 ++++++----------------------------
lib/std/spinlock.zig | 6 +-
23 files changed, 309 insertions(+), 279 deletions(-)
create mode 100644 lib/std/c/emscripten.zig
create mode 100644 lib/std/c/fuchsia.zig
create mode 100644 lib/std/c/haiku.zig
create mode 100644 lib/std/c/hermit.zig
create mode 100644 lib/std/c/minix.zig
create mode 100644 lib/std/c/openbsd.zig
create mode 100644 lib/std/c/solaris.zig
diff --git a/lib/std/c.zig b/lib/std/c.zig
index f70c7e30c4..3fd39b26f5 100644
--- a/lib/std/c.zig
+++ b/lib/std/c.zig
@@ -8,9 +8,16 @@ pub usingnamespace switch (builtin.os) {
.linux => @import("c/linux.zig"),
.windows => @import("c/windows.zig"),
.macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),
- .freebsd => @import("c/freebsd.zig"),
+ .freebsd, .kfreebsd => @import("c/freebsd.zig"),
.netbsd => @import("c/netbsd.zig"),
.dragonfly => @import("c/dragonfly.zig"),
+ .openbsd => @import("c/openbsd.zig"),
+ .haiku => @import("c/haiku.zig"),
+ .hermit => @import("c/hermit.zig"),
+ .solaris => @import("c/solaris.zig"),
+ .fuchsia => @import("c/fuchsia.zig"),
+ .minix => @import("c/minix.zig"),
+ .emscripten => @import("c/emscripten.zig"),
else => struct {},
};
@@ -205,3 +212,16 @@ pub extern "c" fn dn_expand(
) c_int;
pub extern "c" fn sched_yield() c_int;
+
+pub const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};
+pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) c_int;
+pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) c_int;
+pub extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) c_int;
+
+pub const PTHREAD_COND_INITIALIZER = pthread_cond_t{};
+pub extern "c" fn pthread_cond_wait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t) c_int;
+pub extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) c_int;
+pub extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) c_int;
+
+pub const pthread_t = *@OpaqueType();
+pub const FILE = @OpaqueType();
diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig
index f3cd77ec6f..eaccb1dcfd 100644
--- a/lib/std/c/darwin.zig
+++ b/lib/std/c/darwin.zig
@@ -112,3 +112,19 @@ pub const EAI_PROTOCOL = 13;
/// argument buffer overflow
pub const EAI_OVERFLOW = 14;
pub const EAI_MAX = 15;
+
+pub const pthread_mutex_t = extern struct {
+ __sig: c_long = 0x32AAABA7,
+ __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__,
+};
+pub const pthread_cond_t = extern struct {
+ __sig: c_long = 0x3CB0B1BB,
+ __opaque: [__PTHREAD_COND_SIZE__]u8 = [_]u8{0} ** __PTHREAD_COND_SIZE__,
+};
+const __PTHREAD_MUTEX_SIZE__ = if (@sizeOf(usize) == 8) 56 else 40;
+const __PTHREAD_COND_SIZE__ = if (@sizeOf(usize) == 8) 40 else 24;
+
+pub const pthread_attr_t = extern struct {
+ __sig: c_long,
+ __opaque: [56]u8,
+};
diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig
index bd44a25514..a271b2e869 100644
--- a/lib/std/c/dragonfly.zig
+++ b/lib/std/c/dragonfly.zig
@@ -1,6 +1,5 @@
const std = @import("../std.zig");
usingnamespace std.c;
-
extern "c" threadlocal var errno: c_int;
pub fn _errno() *c_int {
return &errno;
@@ -12,3 +11,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize
pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
+
+pub const pthread_mutex_t = extern struct {
+ inner: ?*c_void = null,
+};
+pub const pthread_cond_t = extern struct {
+ inner: ?*c_void = null,
+};
+
+pub const pthread_attr_t = extern struct { // copied from freebsd
+ __size: [56]u8,
+ __align: c_long,
+};
diff --git a/lib/std/c/emscripten.zig b/lib/std/c/emscripten.zig
new file mode 100644
index 0000000000..e91e1421c7
--- /dev/null
+++ b/lib/std/c/emscripten.zig
@@ -0,0 +1,8 @@
+pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(4) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+};
+pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+};
+const __SIZEOF_PTHREAD_COND_T = 48;
+const __SIZEOF_PTHREAD_MUTEX_T = 28;
diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig
index 550b5a59b1..4f18df15fd 100644
--- a/lib/std/c/freebsd.zig
+++ b/lib/std/c/freebsd.zig
@@ -10,3 +10,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize
pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
+
+pub const pthread_mutex_t = extern struct {
+ inner: ?*c_void = null,
+};
+pub const pthread_cond_t = extern struct {
+ inner: ?*c_void = null,
+};
+
+pub const pthread_attr_t = extern struct {
+ __size: [56]u8,
+ __align: c_long,
+};
diff --git a/lib/std/c/fuchsia.zig b/lib/std/c/fuchsia.zig
new file mode 100644
index 0000000000..4f52b8900d
--- /dev/null
+++ b/lib/std/c/fuchsia.zig
@@ -0,0 +1,8 @@
+pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+};
+pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+};
+const __SIZEOF_PTHREAD_COND_T = 48;
+const __SIZEOF_PTHREAD_MUTEX_T = 40;
diff --git a/lib/std/c/haiku.zig b/lib/std/c/haiku.zig
new file mode 100644
index 0000000000..eb1e52a618
--- /dev/null
+++ b/lib/std/c/haiku.zig
@@ -0,0 +1,14 @@
+pub const pthread_mutex_t = extern struct {
+ flags: u32 = 0,
+ lock: i32 = 0,
+ unused: i32 = -42,
+ owner: i32 = -1,
+ owner_count: i32 = 0,
+};
+pub const pthread_cond_t = extern struct {
+ flags: u32 = 0,
+ unused: i32 = -42,
+ mutex: ?*c_void = null,
+ waiter_count: i32 = 0,
+ lock: i32 = 0,
+};
diff --git a/lib/std/c/hermit.zig b/lib/std/c/hermit.zig
new file mode 100644
index 0000000000..b9be76c3ba
--- /dev/null
+++ b/lib/std/c/hermit.zig
@@ -0,0 +1,6 @@
+pub const pthread_mutex_t = extern struct {
+ inner: usize = ~usize(0),
+};
+pub const pthread_cond_t = extern struct {
+ inner: usize = ~usize(0),
+};
diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig
index a1db162e20..07fdceec9a 100644
--- a/lib/std/c/linux.zig
+++ b/lib/std/c/linux.zig
@@ -75,3 +75,26 @@ pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
+
+pub const pthread_attr_t = extern struct {
+ __size: [56]u8,
+ __align: c_long,
+};
+
+pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+};
+pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+};
+const __SIZEOF_PTHREAD_COND_T = 48;
+const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os == .fuchsia) 40 else switch (builtin.abi) {
+ .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
+ .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
+ .aarch64 => 48,
+ .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
+ .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
+ else => if (@sizeOf(usize) == 8) 40 else 24,
+ },
+ else => unreachable,
+};
diff --git a/lib/std/c/minix.zig b/lib/std/c/minix.zig
new file mode 100644
index 0000000000..98ec087a93
--- /dev/null
+++ b/lib/std/c/minix.zig
@@ -0,0 +1,18 @@
+const builtin = @import("builtin");
+pub const pthread_mutex_t = extern struct {
+ size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
+};
+pub const pthread_cond_t = extern struct {
+ size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
+};
+const __SIZEOF_PTHREAD_COND_T = 48;
+const __SIZEOF_PTHREAD_MUTEX_T = switch (builtin.abi) {
+ .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
+ .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
+ .aarch64 => 48,
+ .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
+ .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
+ else => if (@sizeOf(usize) == 8) 40 else 24,
+ },
+ else => unreachable,
+};
diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig
index 417c78db69..c253362ac1 100644
--- a/lib/std/c/netbsd.zig
+++ b/lib/std/c/netbsd.zig
@@ -6,3 +6,32 @@ pub const _errno = __errno;
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
+
+pub const pthread_mutex_t = extern struct {
+ ptm_magic: c_uint = 0x33330003,
+ ptm_errorcheck: padded_spin_t = 0,
+ ptm_unused: padded_spin_t = 0,
+ ptm_owner: usize = 0,
+ ptm_waiters: ?*u8 = null,
+ ptm_recursed: c_uint = 0,
+ ptm_spare2: ?*c_void = null,
+};
+pub const pthread_cond_t = extern struct {
+ ptc_magic: c_uint = 0x55550005,
+ ptc_lock: pthread_spin_t = 0,
+ ptc_waiters_first: ?*u8 = null,
+ ptc_waiters_last: ?*u8 = null,
+ ptc_mutex: ?*pthread_mutex_t = null,
+ ptc_private: ?*c_void = null,
+};
+const pthread_spin_t = if (builtin.arch == .arm or .arch == .powerpc) c_int else u8;
+const padded_spin_t = switch (builtin.arch) {
+ .sparc, .sparcel, .sparcv9, .i386, .x86_64, .le64 => u32,
+ else => spin_t,
+};
+
+pub const pthread_attr_t = extern struct {
+ pta_magic: u32,
+ pta_flags: c_int,
+ pta_private: *c_void,
+};
diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig
new file mode 100644
index 0000000000..22963b08c3
--- /dev/null
+++ b/lib/std/c/openbsd.zig
@@ -0,0 +1,6 @@
+pub const pthread_mutex_t = extern struct {
+ inner: ?*c_void = null,
+};
+pub const pthread_cond_t = extern struct {
+ inner: ?*c_void = null,
+};
diff --git a/lib/std/c/solaris.zig b/lib/std/c/solaris.zig
new file mode 100644
index 0000000000..7c70a01fc4
--- /dev/null
+++ b/lib/std/c/solaris.zig
@@ -0,0 +1,15 @@
+pub const pthread_mutex_t = extern struct {
+ __pthread_mutex_flag1: u16 = 0,
+ __pthread_mutex_flag2: u8 = 0,
+ __pthread_mutex_ceiling: u8 = 0,
+ __pthread_mutex_type: u16 = 0,
+ __pthread_mutex_magic: u16 = 0x4d58,
+ __pthread_mutex_lock: u64 = 0,
+ __pthread_mutex_data: u64 = 0,
+};
+pub const pthread_cond_t = extern struct {
+ __pthread_cond_flag: u32 = 0,
+ __pthread_cond_type: u16 = 0,
+ __pthread_cond_magic: u16 = 0x4356,
+ __pthread_cond_data: u64 = 0,
+};
diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig
index 5387bd4b15..9b44e2edc3 100644
--- a/lib/std/mutex.zig
+++ b/lib/std/mutex.zig
@@ -37,81 +37,84 @@ pub const Mutex = if (builtin.single_threaded)
return Held{ .mutex = self };
}
}
-else struct {
- state: u32, // TODO: make this an enum
- parker: ThreadParker,
+else
+ struct {
+ state: u32, // TODO: make this an enum
+ parker: ThreadParker,
- const Unlocked = 0;
- const Sleeping = 1;
- const Locked = 2;
+ const Unlocked = 0;
+ const Sleeping = 1;
+ const Locked = 2;
- /// number of iterations to spin yielding the cpu
- const SPIN_CPU = 4;
- /// number of iterations to perform in the cpu yield loop
- const SPIN_CPU_COUNT = 30;
- /// number of iterations to spin yielding the thread
- const SPIN_THREAD = 1;
+ /// number of iterations to spin yielding the cpu
+ const SPIN_CPU = 4;
- pub fn init() Mutex {
- return Mutex{
- .state = Unlocked,
- .parker = ThreadParker.init(),
+ /// number of iterations to perform in the cpu yield loop
+ const SPIN_CPU_COUNT = 30;
+
+ /// number of iterations to spin yielding the thread
+ const SPIN_THREAD = 1;
+
+ pub fn init() Mutex {
+ return Mutex{
+ .state = Unlocked,
+ .parker = ThreadParker.init(),
+ };
+ }
+
+ pub fn deinit(self: *Mutex) void {
+ self.parker.deinit();
+ }
+
+ pub const Held = struct {
+ mutex: *Mutex,
+
+ pub fn release(self: Held) void {
+ switch (@atomicRmw(u32, &self.mutex.state, .Xchg, Unlocked, .Release)) {
+ Locked => {},
+ Sleeping => self.mutex.parker.unpark(&self.mutex.state),
+ Unlocked => unreachable, // unlocking an unlocked mutex
+ else => unreachable, // should never be anything else
+ }
+ }
};
- }
- pub fn deinit(self: *Mutex) void {
- self.parker.deinit();
- }
+ pub fn acquire(self: *Mutex) Held {
+ // Try and speculatively grab the lock.
+ // If it fails, the state is either Locked or Sleeping
+ // depending on if theres a thread stuck sleeping below.
+ var state = @atomicRmw(u32, &self.state, .Xchg, Locked, .Acquire);
+ if (state == Unlocked)
+ return Held{ .mutex = self };
- pub const Held = struct {
- mutex: *Mutex,
+ while (true) {
+ // try and acquire the lock using cpu spinning on failure
+ var spin: usize = 0;
+ while (spin < SPIN_CPU) : (spin += 1) {
+ var value = @atomicLoad(u32, &self.state, .Monotonic);
+ while (value == Unlocked)
+ value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ SpinLock.yield(SPIN_CPU_COUNT);
+ }
- pub fn release(self: Held) void {
- switch (@atomicRmw(u32, &self.mutex.state, .Xchg, Unlocked, .Release)) {
- Locked => {},
- Sleeping => self.mutex.parker.unpark(&self.mutex.state),
- Unlocked => unreachable, // unlocking an unlocked mutex
- else => unreachable, // should never be anything else
+ // try and acquire the lock using thread rescheduling on failure
+ spin = 0;
+ while (spin < SPIN_THREAD) : (spin += 1) {
+ var value = @atomicLoad(u32, &self.state, .Monotonic);
+ while (value == Unlocked)
+ value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ std.os.sched_yield() catch std.time.sleep(1);
+ }
+
+ // failed to acquire the lock, go to sleep until woken up by `Held.release()`
+ if (@atomicRmw(u32, &self.state, .Xchg, Sleeping, .Acquire) == Unlocked)
+ return Held{ .mutex = self };
+ state = Sleeping;
+ self.parker.park(&self.state, Sleeping);
}
}
};
- pub fn acquire(self: *Mutex) Held {
- // Try and speculatively grab the lock.
- // If it fails, the state is either Locked or Sleeping
- // depending on if theres a thread stuck sleeping below.
- var state = @atomicRmw(u32, &self.state, .Xchg, Locked, .Acquire);
- if (state == Unlocked)
- return Held{ .mutex = self };
-
- while (true) {
- // try and acquire the lock using cpu spinning on failure
- var spin: usize = 0;
- while (spin < SPIN_CPU) : (spin += 1) {
- var value = @atomicLoad(u32, &self.state, .Monotonic);
- while (value == Unlocked)
- value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
- SpinLock.yield(SPIN_CPU_COUNT);
- }
-
- // try and acquire the lock using thread rescheduling on failure
- spin = 0;
- while (spin < SPIN_THREAD) : (spin += 1) {
- var value = @atomicLoad(u32, &self.state, .Monotonic);
- while (value == Unlocked)
- value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
- std.os.sched_yield();
- }
-
- // failed to acquire the lock, go to sleep until woken up by `Held.release()`
- if (@atomicRmw(u32, &self.state, .Xchg, Sleeping, .Acquire) == Unlocked)
- return Held{ .mutex = self };
- state = Sleeping;
- self.parker.park(&self.state, Sleeping);
- }
- }
-};
-
const TestContext = struct {
mutex: *Mutex,
data: i128,
diff --git a/lib/std/os.zig b/lib/std/os.zig
index cf97a5ee45..6803006bf1 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -3172,9 +3172,21 @@ pub fn dn_expand(
return error.InvalidDnsPacket;
}
-pub fn sched_yield() void {
- switch (builtin.os) {
- .windows => _ = windows.kernel32.SwitchToThread(),
- else => assert(system.sched_yield() == 0),
+pub const SchedYieldError = error{
+ /// The system is not configured to allow yielding
+ SystemCannotYield,
+};
+
+pub fn sched_yield() SchedYieldError!void {
+ if (builtin.os == .windows) {
+ // The return value has to do with how many other threads there are; it is not
+ // an error condition on Windows.
+ _ = windows.kernel32.SwitchToThread();
+ return;
+ }
+ switch (errno(system.sched_yield())) {
+ 0 => return,
+ ENOSYS => return error.SystemCannotYield,
+ else => return error.SystemCannotYield,
}
}
diff --git a/lib/std/os/bits.zig b/lib/std/os/bits.zig
index 6d6163b8fa..7dd968e473 100644
--- a/lib/std/os/bits.zig
+++ b/lib/std/os/bits.zig
@@ -14,9 +14,6 @@ pub usingnamespace switch (builtin.os) {
else => struct {},
};
-pub const pthread_t = *@OpaqueType();
-pub const FILE = @OpaqueType();
-
pub const iovec = extern struct {
iov_base: [*]u8,
iov_len: usize,
diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig
index ca7f663661..335f296dd6 100644
--- a/lib/std/os/bits/darwin.zig
+++ b/lib/std/os/bits/darwin.zig
@@ -133,11 +133,6 @@ pub const dirent = extern struct {
}
};
-pub const pthread_attr_t = extern struct {
- __sig: c_long,
- __opaque: [56]u8,
-};
-
/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
pub const Kevent = extern struct {
ident: usize,
diff --git a/lib/std/os/bits/dragonfly.zig b/lib/std/os/bits/dragonfly.zig
index d1b65707f4..87d89df7d8 100644
--- a/lib/std/os/bits/dragonfly.zig
+++ b/lib/std/os/bits/dragonfly.zig
@@ -360,11 +360,6 @@ pub const Kevent = extern struct {
udata: usize,
};
-pub const pthread_attr_t = extern struct { // copied from freebsd
- __size: [56]u8,
- __align: c_long,
-};
-
pub const EVFILT_FS = -10;
pub const EVFILT_USER = -9;
pub const EVFILT_EXCEPT = -8;
@@ -515,13 +510,13 @@ pub const sigset_t = extern struct {
pub const sig_atomic_t = c_int;
pub const Sigaction = extern struct {
__sigaction_u: extern union {
- __sa_handler: ?extern fn(c_int) void,
- __sa_sigaction: ?extern fn(c_int, [*c]siginfo_t, ?*c_void) void,
+ __sa_handler: ?extern fn (c_int) void,
+ __sa_sigaction: ?extern fn (c_int, [*c]siginfo_t, ?*c_void) void,
},
sa_flags: c_int,
sa_mask: sigset_t,
};
-pub const sig_t = [*c]extern fn(c_int) void;
+pub const sig_t = [*c]extern fn (c_int) void;
pub const sigvec = extern struct {
sv_handler: [*c]__sighandler_t,
diff --git a/lib/std/os/bits/freebsd.zig b/lib/std/os/bits/freebsd.zig
index b0506ad0e1..a7a2536133 100644
--- a/lib/std/os/bits/freebsd.zig
+++ b/lib/std/os/bits/freebsd.zig
@@ -15,11 +15,6 @@ pub const Kevent = extern struct {
// TODO ext
};
-pub const pthread_attr_t = extern struct {
- __size: [56]u8,
- __align: c_long,
-};
-
pub const dl_phdr_info = extern struct {
dlpi_addr: usize,
dlpi_name: ?[*]const u8,
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig
index 0cf30920e4..0fd528b0c0 100644
--- a/lib/std/os/bits/linux.zig
+++ b/lib/std/os/bits/linux.zig
@@ -1000,11 +1000,6 @@ pub const dl_phdr_info = extern struct {
dlpi_phnum: u16,
};
-pub const pthread_attr_t = extern struct {
- __size: [56]u8,
- __align: c_long,
-};
-
pub const CPU_SETSIZE = 128;
pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
pub const cpu_count_t = @IntType(false, std.math.log2(CPU_SETSIZE * 8));
diff --git a/lib/std/os/bits/netbsd.zig b/lib/std/os/bits/netbsd.zig
index f93bbbf106..497c4a0344 100644
--- a/lib/std/os/bits/netbsd.zig
+++ b/lib/std/os/bits/netbsd.zig
@@ -14,12 +14,6 @@ pub const Kevent = extern struct {
udata: usize,
};
-pub const pthread_attr_t = extern struct {
- pta_magic: u32,
- pta_flags: c_int,
- pta_private: *c_void,
-};
-
pub const dl_phdr_info = extern struct {
dlpi_addr: usize,
dlpi_name: ?[*]const u8,
diff --git a/lib/std/parker.zig b/lib/std/parker.zig
index 036fe160ce..4ba0100b9e 100644
--- a/lib/std/parker.zig
+++ b/lib/std/parker.zig
@@ -8,24 +8,9 @@ const linux = std.os.linux;
const windows = std.os.windows;
pub const ThreadParker = switch (builtin.os) {
- .macosx,
- .tvos,
- .ios,
- .watchos,
- .netbsd,
- .openbsd,
- .freebsd,
- .kfreebsd,
- .dragonfly,
- .haiku,
- .hermit,
- .solaris,
- .minix,
- .fuchsia,
- .emscripten => if (builtin.link_libc) PosixParker else SpinParker,
.linux => if (builtin.link_libc) PosixParker else LinuxParker,
.windows => WindowsParker,
- else => SpinParker,
+ else => if (builtin.link_libc) PosixParker else SpinParker,
};
const SpinParker = struct {
@@ -62,7 +47,7 @@ const LinuxParker = struct {
0, linux.EAGAIN => return,
linux.EINTR => continue,
linux.EINVAL => unreachable,
- else => unreachable,
+ else => continue,
}
}
}
@@ -94,7 +79,7 @@ const WindowsParker = struct {
var spin = SpinLock.Backoff.init();
const ev_handle = getEventHandle();
const key = @ptrCast(*const c_void, ptr);
-
+
while (@atomicLoad(u32, ptr, .Monotonic) == expected) {
if (ev_handle) |handle| {
_ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
@@ -121,191 +106,64 @@ const WindowsParker = struct {
};
const PosixParker = struct {
- cond: pthread_cond_t,
- mutex: pthread_mutex_t,
+ cond: c.pthread_cond_t,
+ mutex: c.pthread_mutex_t,
+
+ const c = std.c;
pub fn init() PosixParker {
return PosixParker{
- .cond = PTHREAD_COND_INITIALIZER,
- .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .cond = c.PTHREAD_COND_INITIALIZER,
+ .mutex = c.PTHREAD_MUTEX_INITIALIZER,
};
}
pub fn deinit(self: *PosixParker) void {
// On dragonfly, the destroy functions return EINVAL if they were initialized statically.
- const retm = pthread_mutex_destroy(&self.mutex);
+ const retm = c.pthread_mutex_destroy(&self.mutex);
assert(retm == 0 or retm == (if (builtin.os == .dragonfly) os.EINVAL else 0));
- const retc = pthread_cond_destroy(&self.cond);
+ const retc = c.pthread_cond_destroy(&self.cond);
assert(retc == 0 or retc == (if (builtin.os == .dragonfly) os.EINVAL else 0));
}
pub fn unpark(self: *PosixParker, ptr: *const u32) void {
- assert(pthread_mutex_lock(&self.mutex) == 0);
- defer assert(pthread_mutex_unlock(&self.mutex) == 0);
- assert(pthread_cond_signal(&self.cond) == 0);
+ assert(c.pthread_mutex_lock(&self.mutex) == 0);
+ defer assert(c.pthread_mutex_unlock(&self.mutex) == 0);
+ assert(c.pthread_cond_signal(&self.cond) == 0);
}
pub fn park(self: *PosixParker, ptr: *const u32, expected: u32) void {
- assert(pthread_mutex_lock(&self.mutex) == 0);
- defer assert(pthread_mutex_unlock(&self.mutex) == 0);
+ assert(c.pthread_mutex_lock(&self.mutex) == 0);
+ defer assert(c.pthread_mutex_unlock(&self.mutex) == 0);
while (@atomicLoad(u32, ptr, .Acquire) == expected)
- assert(pthread_cond_wait(&self.cond, &self.mutex) == 0);
+ assert(c.pthread_cond_wait(&self.cond, &self.mutex) == 0);
}
-
- const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};
- extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) c_int;
- extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) c_int;
- extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) c_int;
-
- const PTHREAD_COND_INITIALIZER = pthread_cond_t{};
- extern "c" fn pthread_cond_wait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t) c_int;
- extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) c_int;
- extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) c_int;
-
- // https://github.com/rust-lang/libc
- usingnamespace switch (builtin.os) {
- .macosx, .tvos, .ios, .watchos => struct {
- pub const pthread_mutex_t = extern struct {
- __sig: c_long = 0x32AAABA7,
- __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__,
- };
- pub const pthread_cond_t = extern struct {
- __sig: c_long = 0x3CB0B1BB,
- __opaque: [__PTHREAD_COND_SIZE__]u8 = [_]u8{0} ** __PTHREAD_COND_SIZE__,
- };
- const __PTHREAD_MUTEX_SIZE__ = if (@sizeOf(usize) == 8) 56 else 40;
- const __PTHREAD_COND_SIZE__ = if (@sizeOf(usize) == 8) 40 else 24;
- },
- .netbsd => struct {
- pub const pthread_mutex_t = extern struct {
- ptm_magic: c_uint = 0x33330003,
- ptm_errorcheck: padded_spin_t = 0,
- ptm_unused: padded_spin_t = 0,
- ptm_owner: usize = 0,
- ptm_waiters: ?*u8 = null,
- ptm_recursed: c_uint = 0,
- ptm_spare2: ?*c_void = null,
- };
- pub const pthread_cond_t = extern struct {
- ptc_magic: c_uint = 0x55550005,
- ptc_lock: pthread_spin_t = 0,
- ptc_waiters_first: ?*u8 = null,
- ptc_waiters_last: ?*u8 = null,
- ptc_mutex: ?*pthread_mutex_t = null,
- ptc_private: ?*c_void = null,
- };
- const pthread_spin_t = if (builtin.arch == .arm or .arch == .powerpc) c_int else u8;
- const padded_spin_t = switch (builtin.arch) {
- .sparc, .sparcel, .sparcv9, .i386, .x86_64, .le64 => u32,
- else => spin_t,
- };
- },
- .openbsd, .freebsd, .kfreebsd, .dragonfly => struct {
- pub const pthread_mutex_t = extern struct {
- inner: ?*c_void = null,
- };
- pub const pthread_cond_t = extern struct {
- inner: ?*c_void = null,
- };
- },
- .haiku => struct {
- pub const pthread_mutex_t = extern struct {
- flags: u32 = 0,
- lock: i32 = 0,
- unused: i32 = -42,
- owner: i32 = -1,
- owner_count: i32 = 0,
- };
- pub const pthread_cond_t = extern struct {
- flags: u32 = 0,
- unused: i32 = -42,
- mutex: ?*c_void = null,
- waiter_count: i32 = 0,
- lock: i32 = 0,
- };
- },
- .hermit => struct {
- pub const pthread_mutex_t = extern struct {
- inner: usize = ~usize(0),
- };
- pub const pthread_cond_t = extern struct {
- inner: usize = ~usize(0),
- };
- },
- .solaris => struct {
- pub const pthread_mutex_t = extern struct {
- __pthread_mutex_flag1: u16 = 0,
- __pthread_mutex_flag2: u8 = 0,
- __pthread_mutex_ceiling: u8 = 0,
- __pthread_mutex_type: u16 = 0,
- __pthread_mutex_magic: u16 = 0x4d58,
- __pthread_mutex_lock: u64 = 0,
- __pthread_mutex_data: u64 = 0,
- };
- pub const pthread_cond_t = extern struct {
- __pthread_cond_flag: u32 = 0,
- __pthread_cond_type: u16 = 0,
- __pthread_cond_magic: u16 = 0x4356,
- __pthread_cond_data: u64 = 0,
- };
- },
- .fuchsia, .minix, .linux => struct {
- pub const pthread_mutex_t = extern struct {
- size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
- };
- pub const pthread_cond_t = extern struct {
- size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
- };
- const __SIZEOF_PTHREAD_COND_T = 48;
- const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os == .fuchsia) 40 else switch (builtin.abi) {
- .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
- .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
- .aarch64 => 48,
- .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
- .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
- else => if (@sizeOf(usize) == 8) 40 else 24,
- },
- else => unreachable,
- };
- },
- .emscripten => struct {
- pub const pthread_mutex_t = extern struct {
- size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(4) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
- };
- pub const pthread_cond_t = extern struct {
- size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
- };
- const __SIZEOF_PTHREAD_COND_T = 48;
- const __SIZEOF_PTHREAD_MUTEX_T = 28;
- },
- else => unreachable,
- };
};
test "std.ThreadParker" {
if (builtin.single_threaded)
return error.SkipZigTest;
-
+
const Context = struct {
parker: ThreadParker,
data: u32,
fn receiver(self: *@This()) void {
- self.parker.park(&self.data, 0); // receives 1
- assert(@atomicRmw(u32, &self.data, .Xchg, 2, .SeqCst) == 1); // sends 2
- self.parker.unpark(&self.data); // wakes up waiters on 2
- self.parker.park(&self.data, 2); // receives 3
- assert(@atomicRmw(u32, &self.data, .Xchg, 4, .SeqCst) == 3); // sends 4
- self.parker.unpark(&self.data); // wakes up waiters on 4
+ self.parker.park(&self.data, 0); // receives 1
+ assert(@atomicRmw(u32, &self.data, .Xchg, 2, .SeqCst) == 1); // sends 2
+ self.parker.unpark(&self.data); // wakes up waiters on 2
+ self.parker.park(&self.data, 2); // receives 3
+ assert(@atomicRmw(u32, &self.data, .Xchg, 4, .SeqCst) == 3); // sends 4
+ self.parker.unpark(&self.data); // wakes up waiters on 4
}
fn sender(self: *@This()) void {
- assert(@atomicRmw(u32, &self.data, .Xchg, 1, .SeqCst) == 0); // sends 1
- self.parker.unpark(&self.data); // wakes up waiters on 1
- self.parker.park(&self.data, 1); // receives 2
- assert(@atomicRmw(u32, &self.data, .Xchg, 3, .SeqCst) == 2); // sends 3
- self.parker.unpark(&self.data); // wakes up waiters on 3
- self.parker.park(&self.data, 3); // receives 4
+ assert(@atomicRmw(u32, &self.data, .Xchg, 1, .SeqCst) == 0); // sends 1
+ self.parker.unpark(&self.data); // wakes up waiters on 1
+ self.parker.park(&self.data, 1); // receives 2
+ assert(@atomicRmw(u32, &self.data, .Xchg, 3, .SeqCst) == 2); // sends 3
+ self.parker.unpark(&self.data); // wakes up waiters on 3
+ self.parker.park(&self.data, 3); // receives 4
}
};
@@ -314,9 +172,9 @@ test "std.ThreadParker" {
.data = 0,
};
defer context.parker.deinit();
-
+
var receiver = try std.Thread.spawn(&context, Context.receiver);
defer receiver.wait();
context.sender();
-}
\ No newline at end of file
+}
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index b374eba3eb..3bed3d3891 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -31,8 +31,8 @@ pub const SpinLock = struct {
var i = iterations;
while (i != 0) : (i -= 1) {
switch (builtin.arch) {
- .i386, .x86_64 => asm volatile("pause"),
- .arm, .aarch64 => asm volatile("yield"),
+ .i386, .x86_64 => asm volatile ("pause"),
+ .arm, .aarch64 => asm volatile ("yield"),
else => time.sleep(0),
}
}
@@ -53,7 +53,7 @@ pub const SpinLock = struct {
if (self.iteration < 20) {
SpinLock.yield(self.iteration);
} else if (self.iteration < 24) {
- os.sched_yield();
+ os.sched_yield() catch time.sleep(1);
} else if (self.iteration < 26) {
time.sleep(1 * time.millisecond);
} else {
From 2a6fbbd8fba30b8d24aa966606372f595c102d55 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Nov 2019 23:21:31 -0500
Subject: [PATCH 033/129] introduce `@as` builtin for type coercion
This commit also hooks up type coercion (previously called implicit
casting) into the result location mechanism, and additionally hooks up
variable declarations, maintaining the property that:
var a: T = b;
is semantically equivalent to:
var a = @as(T, b);
See #1757
---
src/all_types.hpp | 25 ++++--
src/codegen.cpp | 1 +
src/ir.cpp | 190 ++++++++++++++++++++++++++++++++++------------
src/ir_print.cpp | 23 ++++--
4 files changed, 175 insertions(+), 64 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 42f14539f3..8ba2bfc503 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -48,6 +48,7 @@ struct ResultLoc;
struct ResultLocPeer;
struct ResultLocPeerParent;
struct ResultLocBitCast;
+struct ResultLocCast;
struct ResultLocReturn;
enum PtrLen {
@@ -1691,6 +1692,7 @@ enum BuiltinFnId {
BuiltinFnIdFrameType,
BuiltinFnIdFrameHandle,
BuiltinFnIdFrameSize,
+ BuiltinFnIdAs,
};
struct BuiltinFnEntry {
@@ -3458,6 +3460,13 @@ struct IrInstructionPtrCastGen {
bool safety_check_on;
};
+struct IrInstructionImplicitCast {
+ IrInstruction base;
+
+ IrInstruction *operand;
+ ResultLocCast *result_loc_cast;
+};
+
struct IrInstructionBitCastSrc {
IrInstruction base;
@@ -3823,14 +3832,6 @@ struct IrInstructionEndExpr {
ResultLoc *result_loc;
};
-struct IrInstructionImplicitCast {
- IrInstruction base;
-
- IrInstruction *dest_type;
- IrInstruction *target;
- ResultLoc *result_loc;
-};
-
// This one is for writing through the result pointer.
struct IrInstructionResolveResult {
IrInstruction base;
@@ -3928,6 +3929,7 @@ enum ResultLocId {
ResultLocIdPeerParent,
ResultLocIdInstruction,
ResultLocIdBitCast,
+ ResultLocIdCast,
};
// Additions to this struct may need to be handled in
@@ -3995,6 +3997,13 @@ struct ResultLocBitCast {
ResultLoc *parent;
};
+// The source_instruction is the destination type
+struct ResultLocCast {
+ ResultLoc base;
+
+ ResultLoc *parent;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 89c41b61cc..4861def16c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8070,6 +8070,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdFrameType, "Frame", 1);
create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0);
create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1);
+ create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
}
static const char *bool_to_str(bool b) {
diff --git a/src/ir.cpp b/src/ir.cpp
index dae759ed84..ae5987d030 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -200,6 +200,8 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo
static void ir_reset_result(ResultLoc *result_loc);
static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,
Scope *scope, AstNode *source_node, Buf *out_bare_name);
+static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
+ ResultLoc *parent_result_loc);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -2766,6 +2768,18 @@ static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *sourc
return &instruction->base;
}
+static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *operand, ResultLocCast *result_loc_cast)
+{
+ IrInstructionImplicitCast *instruction = ir_build_instruction(irb, scope, source_node);
+ instruction->operand = operand;
+ instruction->result_loc_cast = result_loc_cast;
+
+ ir_ref_instruction(operand, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast)
{
@@ -3063,20 +3077,6 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
-static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc)
-{
- IrInstructionImplicitCast *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->dest_type = dest_type;
- instruction->target = target;
- instruction->result_loc = result_loc;
-
- ir_ref_instruction(dest_type, irb->current_basic_block);
- ir_ref_instruction(target, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
ResultLoc *result_loc, IrInstruction *ty)
{
@@ -5374,6 +5374,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);
return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);
}
+ case BuiltinFnIdAs:
+ {
+ AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope);
+ if (dest_type == irb->codegen->invalid_instruction)
+ return dest_type;
+
+ ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc);
+
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
+ IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
+ &result_loc_cast->base);
+ if (arg1_value == irb->codegen->invalid_instruction)
+ return arg1_value;
+
+ IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast);
+ return ir_lval_wrap(irb, scope, result, lval, result_loc);
+ }
case BuiltinFnIdIntToPtr:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -6214,6 +6232,20 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo
return result_loc_var;
}
+static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
+ ResultLoc *parent_result_loc)
+{
+ ResultLocCast *result_loc_cast = allocate(1);
+ result_loc_cast->base.id = ResultLocIdCast;
+ result_loc_cast->base.source_instruction = dest_type;
+ ir_ref_instruction(dest_type, irb->current_basic_block);
+ result_loc_cast->parent = parent_result_loc;
+
+ ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base);
+
+ return result_loc_cast;
+}
+
static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var,
IrInstruction *init, const char *name_hint, IrInstruction *is_comptime)
{
@@ -6282,7 +6314,15 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
// Create a result location for the initialization expression.
ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);
- ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr;
+ ResultLoc *init_result_loc;
+ ResultLocCast *result_loc_cast;
+ if (type_instruction != nullptr) {
+ result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base);
+ init_result_loc = &result_loc_cast->base;
+ } else {
+ result_loc_cast = nullptr;
+ init_result_loc = &result_loc_var->base;
+ }
Scope *init_scope = is_comptime_scalar ?
create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope;
@@ -6298,9 +6338,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
if (init_value == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
- if (type_instruction != nullptr) {
- IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value,
- &result_loc_var->base);
+ if (result_loc_cast != nullptr) {
+ IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast);
ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
}
@@ -15435,6 +15474,7 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspe
case ResultLocIdNone:
case ResultLocIdVar:
case ResultLocIdBitCast:
+ case ResultLocIdCast:
return nullptr;
case ResultLocIdInstruction:
return result_loc->source_instruction->child->value.type;
@@ -15489,6 +15529,7 @@ static bool ir_result_has_type(ResultLoc *result_loc) {
case ResultLocIdReturn:
case ResultLocIdInstruction:
case ResultLocIdBitCast:
+ case ResultLocIdCast:
return true;
case ResultLocIdVar:
return reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
@@ -15668,6 +15709,61 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
result_loc->resolved_loc = parent_result_loc;
return result_loc->resolved_loc;
}
+ case ResultLocIdCast: {
+ ResultLocCast *result_cast = reinterpret_cast(result_loc);
+ ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
+ if (type_is_invalid(dest_type))
+ return ira->codegen->invalid_instruction;
+
+ ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type,
+ result_cast->base.source_instruction->source_node, false);
+ if (const_cast_result.id == ConstCastResultIdInvalid)
+ return ira->codegen->invalid_instruction;
+ if (const_cast_result.id != ConstCastResultIdOk) {
+ // We will not be able to provide a result location for this value. Allow the
+ // code to create a new result location and then type coerce to the old one.
+ return nullptr;
+ }
+
+ // In this case we can pointer cast the result location.
+ IrInstruction *casted_value;
+ if (value != nullptr) {
+ casted_value = ir_implicit_cast(ira, value, dest_type);
+ } else {
+ casted_value = nullptr;
+ }
+
+ if (casted_value == nullptr || type_is_invalid(casted_value->value.type)) {
+ return casted_value;
+ }
+
+ IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent,
+ dest_type, casted_value, force_runtime, non_null_comptime, true);
+ if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
+ parent_result_loc->value.type->id == ZigTypeIdUnreachable)
+ {
+ return parent_result_loc;
+ }
+ ZigType *parent_ptr_type = parent_result_loc->value.type;
+ assert(parent_ptr_type->id == ZigTypeIdPointer);
+ if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+ uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type);
+ if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) {
+ return ira->codegen->invalid_instruction;
+ }
+ ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type,
+ parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
+ parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
+
+ result_loc->written = true;
+ result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
+ ptr_type, result_cast->base.source_instruction, false);
+ return result_loc->resolved_loc;
+ }
case ResultLocIdBitCast: {
ResultLocBitCast *result_bit_cast = reinterpret_cast(result_loc);
ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child);
@@ -15790,18 +15886,6 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
return result_loc;
}
-static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {
- ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);
- if (type_is_invalid(dest_type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *target = instruction->target->child;
- if (type_is_invalid(target->value.type))
- return ira->codegen->invalid_instruction;
-
- return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc);
-}
-
static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
if (type_is_invalid(implicit_elem_type))
@@ -15864,6 +15948,7 @@ static void ir_reset_result(ResultLoc *result_loc) {
case ResultLocIdNone:
case ResultLocIdInstruction:
case ResultLocIdBitCast:
+ case ResultLocIdCast:
break;
}
}
@@ -16903,25 +16988,14 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
if (is_comptime || instr_is_comptime(fn_ref)) {
if (fn_ref->value.type->id == ZigTypeIdMetaType) {
- ZigType *dest_type = ir_resolve_type(ira, fn_ref);
- if (type_is_invalid(dest_type))
+ ZigType *ty = ir_resolve_type(ira, fn_ref);
+ if (ty == nullptr)
return ira->codegen->invalid_instruction;
-
- size_t actual_param_count = call_instruction->arg_count;
-
- if (actual_param_count != 1) {
- ir_add_error_node(ira, call_instruction->base.source_node,
- buf_sprintf("cast expression expects exactly one parameter"));
- return ira->codegen->invalid_instruction;
- }
-
- IrInstruction *arg = call_instruction->args[0]->child;
-
- IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg,
- call_instruction->result_loc);
- if (type_is_invalid(cast_instruction->value.type))
- return ira->codegen->invalid_instruction;
- return ir_finish_anal(ira, cast_instruction);
+ ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node,
+ buf_sprintf("type '%s' not a function", buf_ptr(&ty->name)));
+ add_error_note(ira->codegen, msg, call_instruction->base.source_node,
+ buf_sprintf("use @as builtin for type coercion"));
+ return ira->codegen->invalid_instruction;
} else if (fn_ref->value.type->id == ZigTypeIdFn) {
ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref);
ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value.type;
@@ -25958,6 +26032,26 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
return ir_const_void(ira, &instruction->base);
}
+static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {
+ IrInstruction *operand = instruction->operand->child;
+ if (type_is_invalid(operand->value.type))
+ return operand;
+
+ IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
+ &instruction->result_loc_cast->base, operand->value.type, operand, false, false, true);
+ if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
+ return result_loc;
+
+ if (instruction->result_loc_cast->parent->gen_instruction != nullptr) {
+ return instruction->result_loc_cast->parent->gen_instruction;
+ }
+
+ ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);
+ if (type_is_invalid(dest_type))
+ return ira->codegen->invalid_instruction;
+ return ir_implicit_cast(ira, operand, dest_type);
+}
+
static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {
IrInstruction *operand = instruction->operand->child;
if (type_is_invalid(operand->value.type))
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index aa53b11e03..85b58faefc 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -601,6 +601,12 @@ static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_
fprintf(irp->f, ")");
}
+static void ir_print_result_loc_cast(IrPrint *irp, ResultLocCast *result_loc_cast) {
+ fprintf(irp->f, "cast(ty=");
+ ir_print_other_instruction(irp, result_loc_cast->base.source_instruction);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
switch (result_loc->id) {
case ResultLocIdInvalid:
@@ -619,6 +625,8 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
case ResultLocIdBitCast:
return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc);
+ case ResultLocIdCast:
+ return ir_print_result_loc_cast(irp, (ResultLocCast *)result_loc);
case ResultLocIdPeerParent:
fprintf(irp->f, "peer_parent");
return;
@@ -1484,6 +1492,13 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc
fprintf(irp->f, ")");
}
+static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
+ fprintf(irp->f, "@implicitCast(");
+ ir_print_other_instruction(irp, instruction->operand);
+ fprintf(irp->f, ")result=");
+ ir_print_result_loc(irp, &instruction->result_loc_cast->base);
+}
+
static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {
fprintf(irp->f, "@bitCast(");
ir_print_other_instruction(irp, instruction->operand);
@@ -1739,14 +1754,6 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio
fprintf(irp->f, ")");
}
-static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
- fprintf(irp->f, "@implicitCast(");
- ir_print_other_instruction(irp, instruction->dest_type);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->target);
- fprintf(irp->f, ")");
-}
-
static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {
fprintf(irp->f, "ResolveResult(");
ir_print_result_loc(irp, instruction->result_loc);
From e0db54e89d6f4e9f56800ddb1017e30be1b7d58a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Nov 2019 23:25:57 -0500
Subject: [PATCH 034/129] update the codebase to use `@as`
---
build.zig | 2 +-
lib/std/array_list.zig | 16 +-
lib/std/ascii.zig | 22 +-
lib/std/atomic/queue.zig | 4 +-
lib/std/atomic/stack.zig | 6 +-
lib/std/bloom_filter.zig | 6 +-
lib/std/c/darwin.zig | 2 +-
lib/std/child_process.zig | 2 +-
lib/std/crypto/aes.zig | 20 +-
lib/std/crypto/blake2.zig | 16 +-
lib/std/crypto/chacha20.zig | 8 +-
lib/std/crypto/gimli.zig | 8 +-
lib/std/crypto/md5.zig | 8 +-
lib/std/crypto/poly1305.zig | 12 +-
lib/std/crypto/sha1.zig | 30 +--
lib/std/crypto/sha2.zig | 38 ++--
lib/std/crypto/sha3.zig | 2 +-
lib/std/crypto/x25519.zig | 20 +-
lib/std/debug.zig | 23 ++-
lib/std/debug/leb128.zig | 4 +-
lib/std/dynamic_library.zig | 4 +-
lib/std/elf.zig | 24 +--
lib/std/event/fs.zig | 4 +-
lib/std/fifo.zig | 26 +--
lib/std/fmt.zig | 102 +++++-----
lib/std/fmt/errol.zig | 4 +-
lib/std/fmt/parse_float.zig | 14 +-
lib/std/fs/file.zig | 6 +-
lib/std/hash/auto_hash.zig | 14 +-
lib/std/hash/cityhash.zig | 8 +-
lib/std/hash/crc.zig | 8 +-
lib/std/hash/murmur.zig | 2 +-
lib/std/hash/siphash.zig | 14 +-
lib/std/hash_map.zig | 2 +-
lib/std/heap.zig | 2 +-
lib/std/http/headers.zig | 10 +-
lib/std/io.zig | 4 +-
lib/std/io/out_stream.zig | 4 +-
lib/std/io/test.zig | 40 ++--
lib/std/json.zig | 4 +-
lib/std/math.zig | 136 ++++++-------
lib/std/math/acos.zig | 4 +-
lib/std/math/acosh.zig | 4 +-
lib/std/math/asin.zig | 4 +-
lib/std/math/asinh.zig | 4 +-
lib/std/math/atan.zig | 4 +-
lib/std/math/atanh.zig | 4 +-
lib/std/math/big/int.zig | 2 +-
lib/std/math/cbrt.zig | 10 +-
lib/std/math/ceil.zig | 6 +-
lib/std/math/complex/ldexp.zig | 2 +-
lib/std/math/complex/sqrt.zig | 4 +-
lib/std/math/complex/tanh.zig | 2 +-
lib/std/math/copysign.zig | 6 +-
lib/std/math/cos.zig | 4 +-
lib/std/math/cosh.zig | 4 +-
lib/std/math/exp.zig | 4 +-
lib/std/math/exp2.zig | 6 +-
lib/std/math/expm1.zig | 4 +-
lib/std/math/expo2.zig | 2 +-
lib/std/math/fabs.zig | 8 +-
lib/std/math/floor.zig | 10 +-
lib/std/math/fma.zig | 2 +-
lib/std/math/frexp.zig | 4 +-
lib/std/math/hypot.zig | 2 +-
lib/std/math/ilogb.zig | 6 +-
lib/std/math/isfinite.zig | 12 +-
lib/std/math/isinf.zig | 48 ++---
lib/std/math/isnan.zig | 8 +-
lib/std/math/isnormal.zig | 12 +-
lib/std/math/ln.zig | 10 +-
lib/std/math/log.zig | 10 +-
lib/std/math/log10.zig | 8 +-
lib/std/math/log1p.zig | 6 +-
lib/std/math/log2.zig | 8 +-
lib/std/math/modf.zig | 8 +-
lib/std/math/round.zig | 4 +-
lib/std/math/scalbn.zig | 4 +-
lib/std/math/signbit.zig | 6 +-
lib/std/math/sin.zig | 6 +-
lib/std/math/sinh.zig | 4 +-
lib/std/math/sqrt.zig | 6 +-
lib/std/math/tan.zig | 4 +-
lib/std/math/tanh.zig | 4 +-
lib/std/math/trunc.zig | 8 +-
lib/std/mem.zig | 20 +-
lib/std/meta.zig | 2 +-
lib/std/meta/trait.zig | 4 +-
lib/std/net.zig | 14 +-
lib/std/os.zig | 10 +-
lib/std/os/bits/dragonfly.zig | 2 +-
lib/std/os/bits/linux.zig | 10 +-
lib/std/os/linux.zig | 188 +++++++++---------
lib/std/os/linux/arm-eabi.zig | 4 +-
lib/std/os/linux/arm64.zig | 2 +-
lib/std/os/linux/mipsel.zig | 6 +-
lib/std/os/linux/riscv64.zig | 2 +-
lib/std/os/linux/vdso.zig | 4 +-
lib/std/os/linux/x86_64.zig | 2 +-
lib/std/os/test.zig | 2 +-
lib/std/os/windows.zig | 2 +-
lib/std/os/zen.zig | 4 +-
lib/std/packed_int_array.zig | 18 +-
lib/std/pdb.zig | 2 +-
lib/std/priority_queue.zig | 60 +++---
lib/std/rand.zig | 8 +-
lib/std/rand/ziggurat.zig | 2 +-
lib/std/segmented_list.zig | 10 +-
lib/std/sort.zig | 8 +-
lib/std/special/c.zig | 6 +-
lib/std/special/compiler_rt.zig | 34 ++--
lib/std/special/compiler_rt/addXf3.zig | 26 +--
lib/std/special/compiler_rt/addXf3_test.zig | 8 +-
lib/std/special/compiler_rt/comparedf2.zig | 20 +-
lib/std/special/compiler_rt/comparesf2.zig | 20 +-
lib/std/special/compiler_rt/comparetf2.zig | 20 +-
lib/std/special/compiler_rt/divdf3.zig | 66 +++---
lib/std/special/compiler_rt/divsf3.zig | 22 +-
lib/std/special/compiler_rt/divti3_test.zig | 8 +-
lib/std/special/compiler_rt/extendXfYf2.zig | 14 +-
.../special/compiler_rt/extendXfYf2_test.zig | 8 +-
lib/std/special/compiler_rt/fixdfdi_test.zig | 2 +-
lib/std/special/compiler_rt/fixdfsi_test.zig | 2 +-
lib/std/special/compiler_rt/fixdfti_test.zig | 2 +-
lib/std/special/compiler_rt/fixint.zig | 6 +-
lib/std/special/compiler_rt/fixint_test.zig | 26 +--
lib/std/special/compiler_rt/fixsfdi_test.zig | 2 +-
lib/std/special/compiler_rt/fixsfsi_test.zig | 2 +-
lib/std/special/compiler_rt/fixsfti_test.zig | 2 +-
lib/std/special/compiler_rt/fixtfdi_test.zig | 2 +-
lib/std/special/compiler_rt/fixtfsi_test.zig | 2 +-
lib/std/special/compiler_rt/fixtfti_test.zig | 2 +-
lib/std/special/compiler_rt/fixuint.zig | 8 +-
.../special/compiler_rt/fixunstfsi_test.zig | 2 +-
.../special/compiler_rt/fixunstfti_test.zig | 2 +-
lib/std/special/compiler_rt/floatsiXf.zig | 10 +-
lib/std/special/compiler_rt/floattidf.zig | 2 +-
lib/std/special/compiler_rt/floattisf.zig | 2 +-
lib/std/special/compiler_rt/floattitf.zig | 2 +-
lib/std/special/compiler_rt/floatunsidf.zig | 6 +-
lib/std/special/compiler_rt/floatuntidf.zig | 4 +-
lib/std/special/compiler_rt/floatuntisf.zig | 4 +-
lib/std/special/compiler_rt/floatuntitf.zig | 4 +-
lib/std/special/compiler_rt/mulXf3.zig | 50 ++---
lib/std/special/compiler_rt/mulXf3_test.zig | 18 +-
lib/std/special/compiler_rt/muldi3.zig | 2 +-
lib/std/special/compiler_rt/mulodi4.zig | 2 +-
lib/std/special/compiler_rt/mulodi4_test.zig | 48 ++---
lib/std/special/compiler_rt/muloti4.zig | 2 +-
lib/std/special/compiler_rt/muloti4_test.zig | 62 +++---
lib/std/special/compiler_rt/multi3.zig | 2 +-
lib/std/special/compiler_rt/negXf2.zig | 2 +-
.../special/compiler_rt/popcountdi2_test.zig | 6 +-
lib/std/special/compiler_rt/truncXfYf2.zig | 2 +-
.../special/compiler_rt/truncXfYf2_test.zig | 20 +-
lib/std/special/compiler_rt/udivmod.zig | 6 +-
lib/std/target.zig | 2 +-
lib/std/thread.zig | 2 +-
lib/std/time.zig | 8 +-
lib/std/unicode.zig | 10 +-
lib/std/valgrind.zig | 2 +-
lib/std/zig/parse_string_literal.zig | 2 +-
lib/std/zig/parser_test.zig | 2 +-
lib/std/zig/render.zig | 6 +-
lib/std/zig/tokenizer.zig | 2 +-
test/compare_output.zig | 50 ++---
test/compile_errors.zig | 52 ++---
test/stage1/behavior.zig | 10 +-
test/stage1/behavior/align.zig | 4 +-
test/stage1/behavior/array.zig | 4 +-
test/stage1/behavior/asm.zig | 16 +-
test/stage1/behavior/async_fn.zig | 10 +-
test/stage1/behavior/atomics.zig | 6 +-
test/stage1/behavior/bitreverse.zig | 28 +--
test/stage1/behavior/bool.zig | 8 +-
test/stage1/behavior/bugs/1322.zig | 4 +-
test/stage1/behavior/bugs/1421.zig | 2 +-
test/stage1/behavior/bugs/2114.zig | 8 +-
test/stage1/behavior/bugs/3046.zig | 2 +-
test/stage1/behavior/byteswap.zig | 24 +--
test/stage1/behavior/cast.zig | 12 +-
test/stage1/behavior/defer.zig | 2 +-
test/stage1/behavior/enum.zig | 4 +-
test/stage1/behavior/error.zig | 4 +-
test/stage1/behavior/eval.zig | 36 ++--
test/stage1/behavior/floatop.zig | 4 +-
test/stage1/behavior/fn.zig | 4 +-
test/stage1/behavior/if.zig | 4 +-
test/stage1/behavior/import.zig | 4 +-
test/stage1/behavior/math.zig | 24 +--
test/stage1/behavior/misc.zig | 6 +-
test/stage1/behavior/popcount.zig | 2 +-
test/stage1/behavior/pub_enum.zig | 2 +-
test/stage1/behavior/shuffle.zig | 26 +--
test/stage1/behavior/slicetobytes.zig | 2 +-
test/stage1/behavior/struct.zig | 16 +-
test/stage1/behavior/switch.zig | 8 +-
test/stage1/behavior/try.zig | 6 +-
test/stage1/behavior/type_info.zig | 46 ++---
test/stage1/behavior/union.zig | 24 +--
test/stage1/behavior/var_args.zig | 10 +-
test/stage1/behavior/vector.zig | 50 ++---
test/stage1/behavior/void.zig | 2 +-
test/stage1/behavior/while.zig | 16 +-
test/tests.zig | 4 +-
test/translate_c.zig | 62 +++---
206 files changed, 1287 insertions(+), 1282 deletions(-)
diff --git a/build.zig b/build.zig
index ca78bdf197..7cd6d1b7bb 100644
--- a/build.zig
+++ b/build.zig
@@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
) catch unreachable;
for (dep.system_libs.toSliceConst()) |lib| {
const static_bare_name = if (mem.eql(u8, lib, "curses"))
- ([]const u8)("libncurses.a")
+ @as([]const u8,"libncurses.a")
else
b.fmt("lib{}.a", lib);
const static_lib_name = fs.path.join(
diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig
index a57839ec3b..59fd2a10e5 100644
--- a/lib/std/array_list.zig
+++ b/lib/std/array_list.zig
@@ -344,18 +344,18 @@ test "std.ArrayList.orderedRemove" {
try list.append(7);
//remove from middle
- testing.expectEqual(i32(4), list.orderedRemove(3));
- testing.expectEqual(i32(5), list.at(3));
- testing.expectEqual(usize(6), list.len);
+ testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
+ testing.expectEqual(@as(i32, 5), list.at(3));
+ testing.expectEqual(@as(usize, 6), list.len);
//remove from end
- testing.expectEqual(i32(7), list.orderedRemove(5));
- testing.expectEqual(usize(5), list.len);
+ testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
+ testing.expectEqual(@as(usize, 5), list.len);
//remove from front
- testing.expectEqual(i32(1), list.orderedRemove(0));
- testing.expectEqual(i32(2), list.at(0));
- testing.expectEqual(usize(4), list.len);
+ testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
+ testing.expectEqual(@as(i32, 2), list.at(0));
+ testing.expectEqual(@as(usize, 4), list.len);
}
test "std.ArrayList.swapRemove" {
diff --git a/lib/std/ascii.zig b/lib/std/ascii.zig
index 2bc11ba3f2..71f52bfd17 100644
--- a/lib/std/ascii.zig
+++ b/lib/std/ascii.zig
@@ -129,26 +129,26 @@ const combinedTable = init: {
comptime var i = 0;
inline while (i < 128) : (i += 1) {
table[i] =
- u8(alpha[i]) << @enumToInt(tIndex.Alpha) |
- u8(hex[i]) << @enumToInt(tIndex.Hex) |
- u8(space[i]) << @enumToInt(tIndex.Space) |
- u8(digit[i]) << @enumToInt(tIndex.Digit) |
- u8(lower[i]) << @enumToInt(tIndex.Lower) |
- u8(upper[i]) << @enumToInt(tIndex.Upper) |
- u8(punct[i]) << @enumToInt(tIndex.Punct) |
- u8(graph[i]) << @enumToInt(tIndex.Graph);
+ @as(u8, alpha[i]) << @enumToInt(tIndex.Alpha) |
+ @as(u8, hex[i]) << @enumToInt(tIndex.Hex) |
+ @as(u8, space[i]) << @enumToInt(tIndex.Space) |
+ @as(u8, digit[i]) << @enumToInt(tIndex.Digit) |
+ @as(u8, lower[i]) << @enumToInt(tIndex.Lower) |
+ @as(u8, upper[i]) << @enumToInt(tIndex.Upper) |
+ @as(u8, punct[i]) << @enumToInt(tIndex.Punct) |
+ @as(u8, graph[i]) << @enumToInt(tIndex.Graph);
}
mem.set(u8, table[128..256], 0);
break :init table;
};
fn inTable(c: u8, t: tIndex) bool {
- return (combinedTable[c] & (u8(1) << @enumToInt(t))) != 0;
+ return (combinedTable[c] & (@as(u8, 1) << @enumToInt(t))) != 0;
}
pub fn isAlNum(c: u8) bool {
- return (combinedTable[c] & ((u8(1) << @enumToInt(tIndex.Alpha)) |
- u8(1) << @enumToInt(tIndex.Digit))) != 0;
+ return (combinedTable[c] & ((@as(u8, 1) << @enumToInt(tIndex.Alpha)) |
+ @as(u8, 1) << @enumToInt(tIndex.Digit))) != 0;
}
pub fn isAlpha(c: u8) bool {
diff --git a/lib/std/atomic/queue.zig b/lib/std/atomic/queue.zig
index dbc011bed3..173355eb3b 100644
--- a/lib/std/atomic/queue.zig
+++ b/lib/std/atomic/queue.zig
@@ -214,8 +214,8 @@ test "std.atomic.Queue" {
std.debug.panic(
"failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",
context.get_count,
- u32(puts_per_thread),
- u32(put_thread_count),
+ @as(u32, puts_per_thread),
+ @as(u32, put_thread_count),
);
}
}
diff --git a/lib/std/atomic/stack.zig b/lib/std/atomic/stack.zig
index dd288adbf1..664191eb77 100644
--- a/lib/std/atomic/stack.zig
+++ b/lib/std/atomic/stack.zig
@@ -11,7 +11,7 @@ pub fn Stack(comptime T: type) type {
root: ?*Node,
lock: @typeOf(lock_init),
- const lock_init = if (builtin.single_threaded) {} else u8(0);
+ const lock_init = if (builtin.single_threaded) {} else @as(u8, 0);
pub const Self = @This();
@@ -141,8 +141,8 @@ test "std.atomic.stack" {
std.debug.panic(
"failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",
context.get_count,
- u32(puts_per_thread),
- u32(put_thread_count),
+ @as(u32, puts_per_thread),
+ @as(u32, put_thread_count),
);
}
}
diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig
index c36c5e9dfa..2734e7d54f 100644
--- a/lib/std/bloom_filter.zig
+++ b/lib/std/bloom_filter.zig
@@ -171,7 +171,7 @@ test "std.BloomFilter" {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
testing.expectEqual(BF.Index(0), bf.popCount());
- testing.expectEqual(f64(0), bf.estimateItems());
+ testing.expectEqual(@as(f64, 0), bf.estimateItems());
// fill in a few items
bf.incrementCell(42);
bf.incrementCell(255);
@@ -197,7 +197,7 @@ test "std.BloomFilter" {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
testing.expectEqual(BF.Index(0), bf.popCount());
- testing.expectEqual(f64(0), bf.estimateItems());
+ testing.expectEqual(@as(f64, 0), bf.estimateItems());
// Lets add a string
bf.add("foo");
@@ -219,7 +219,7 @@ test "std.BloomFilter" {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
testing.expectEqual(BF.Index(0), bf.popCount());
- testing.expectEqual(f64(0), bf.estimateItems());
+ testing.expectEqual(@as(f64, 0), bf.estimateItems());
comptime var teststrings = [_][]const u8{
"foo",
diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig
index eaccb1dcfd..4d40e8aee5 100644
--- a/lib/std/c/darwin.zig
+++ b/lib/std/c/darwin.zig
@@ -53,7 +53,7 @@ pub extern "c" fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clo
pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;
pub fn sigaddset(set: *sigset_t, signo: u5) void {
- set.* |= u32(1) << (signo - 1);
+ set.* |= @as(u32, 1) << (signo - 1);
}
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig
index 5fae9447a9..e6d81aeb4f 100644
--- a/lib/std/child_process.zig
+++ b/lib/std/child_process.zig
@@ -717,7 +717,7 @@ fn destroyPipe(pipe: [2]os.fd_t) void {
// Child of fork calls this to report an error to the fork parent.
// Then the child exits.
fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
- writeIntFd(fd, ErrInt(@errorToInt(err))) catch {};
+ writeIntFd(fd, @as(ErrInt,@errorToInt(err))) catch {};
os.exit(1);
}
diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig
index 4e7a4f2e13..ddccd0b1b3 100644
--- a/lib/std/crypto/aes.zig
+++ b/lib/std/crypto/aes.zig
@@ -6,7 +6,7 @@ const testing = std.testing;
// Apply sbox0 to each byte in w.
fn subw(w: u32) u32 {
- return u32(sbox0[w >> 24]) << 24 | u32(sbox0[w >> 16 & 0xff]) << 16 | u32(sbox0[w >> 8 & 0xff]) << 8 | u32(sbox0[w & 0xff]);
+ return @as(u32, sbox0[w >> 24]) << 24 | @as(u32, sbox0[w >> 16 & 0xff]) << 16 | @as(u32, sbox0[w >> 8 & 0xff]) << 8 | @as(u32, sbox0[w & 0xff]);
}
fn rotw(w: u32) u32 {
@@ -48,10 +48,10 @@ fn encryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {
}
// Last round uses s-box directly and XORs to produce output.
- s0 = u32(sbox0[t0 >> 24]) << 24 | u32(sbox0[t1 >> 16 & 0xff]) << 16 | u32(sbox0[t2 >> 8 & 0xff]) << 8 | u32(sbox0[t3 & 0xff]);
- s1 = u32(sbox0[t1 >> 24]) << 24 | u32(sbox0[t2 >> 16 & 0xff]) << 16 | u32(sbox0[t3 >> 8 & 0xff]) << 8 | u32(sbox0[t0 & 0xff]);
- s2 = u32(sbox0[t2 >> 24]) << 24 | u32(sbox0[t3 >> 16 & 0xff]) << 16 | u32(sbox0[t0 >> 8 & 0xff]) << 8 | u32(sbox0[t1 & 0xff]);
- s3 = u32(sbox0[t3 >> 24]) << 24 | u32(sbox0[t0 >> 16 & 0xff]) << 16 | u32(sbox0[t1 >> 8 & 0xff]) << 8 | u32(sbox0[t2 & 0xff]);
+ s0 = @as(u32, sbox0[t0 >> 24]) << 24 | @as(u32, sbox0[t1 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t2 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t3 & 0xff]);
+ s1 = @as(u32, sbox0[t1 >> 24]) << 24 | @as(u32, sbox0[t2 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t3 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t0 & 0xff]);
+ s2 = @as(u32, sbox0[t2 >> 24]) << 24 | @as(u32, sbox0[t3 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t0 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t1 & 0xff]);
+ s3 = @as(u32, sbox0[t3 >> 24]) << 24 | @as(u32, sbox0[t0 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t1 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t2 & 0xff]);
s0 ^= xk[k + 0];
s1 ^= xk[k + 1];
@@ -99,10 +99,10 @@ pub fn decryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {
}
// Last round uses s-box directly and XORs to produce output.
- s0 = u32(sbox1[t0 >> 24]) << 24 | u32(sbox1[t3 >> 16 & 0xff]) << 16 | u32(sbox1[t2 >> 8 & 0xff]) << 8 | u32(sbox1[t1 & 0xff]);
- s1 = u32(sbox1[t1 >> 24]) << 24 | u32(sbox1[t0 >> 16 & 0xff]) << 16 | u32(sbox1[t3 >> 8 & 0xff]) << 8 | u32(sbox1[t2 & 0xff]);
- s2 = u32(sbox1[t2 >> 24]) << 24 | u32(sbox1[t1 >> 16 & 0xff]) << 16 | u32(sbox1[t0 >> 8 & 0xff]) << 8 | u32(sbox1[t3 & 0xff]);
- s3 = u32(sbox1[t3 >> 24]) << 24 | u32(sbox1[t2 >> 16 & 0xff]) << 16 | u32(sbox1[t1 >> 8 & 0xff]) << 8 | u32(sbox1[t0 & 0xff]);
+ s0 = @as(u32, sbox1[t0 >> 24]) << 24 | @as(u32, sbox1[t3 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t2 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t1 & 0xff]);
+ s1 = @as(u32, sbox1[t1 >> 24]) << 24 | @as(u32, sbox1[t0 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t3 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t2 & 0xff]);
+ s2 = @as(u32, sbox1[t2 >> 24]) << 24 | @as(u32, sbox1[t1 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t0 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t3 & 0xff]);
+ s3 = @as(u32, sbox1[t3 >> 24]) << 24 | @as(u32, sbox1[t2 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t1 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t0 & 0xff]);
s0 ^= xk[k + 0];
s1 ^= xk[k + 1];
@@ -256,7 +256,7 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {
while (i < enc.len) : (i += 1) {
var t = enc[i - 1];
if (i % nk == 0) {
- t = subw(rotw(t)) ^ (u32(powx[i / nk - 1]) << 24);
+ t = subw(rotw(t)) ^ (@as(u32, powx[i / nk - 1]) << 24);
} else if (nk > 6 and i % nk == 4) {
t = subw(t);
}
diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig
index 6bb2764b92..d6b1e49724 100644
--- a/lib/std/crypto/blake2.zig
+++ b/lib/std/crypto/blake2.zig
@@ -164,13 +164,13 @@ fn Blake2s(comptime out_len: usize) type {
inline while (j < 10) : (j += 1) {
inline for (rounds) |r| {
v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
- v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));
+ v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], @as(usize, 16));
v[r.c] = v[r.c] +% v[r.d];
- v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));
+ v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], @as(usize, 12));
v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
- v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));
+ v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], @as(usize, 8));
v[r.c] = v[r.c] +% v[r.d];
- v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));
+ v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], @as(usize, 7));
}
}
@@ -398,13 +398,13 @@ fn Blake2b(comptime out_len: usize) type {
inline while (j < 12) : (j += 1) {
inline for (rounds) |r| {
v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
- v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));
+ v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], @as(usize, 32));
v[r.c] = v[r.c] +% v[r.d];
- v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));
+ v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], @as(usize, 24));
v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
- v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));
+ v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], @as(usize, 16));
v[r.c] = v[r.c] +% v[r.d];
- v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));
+ v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], @as(usize, 63));
}
}
diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig
index 0d997e0d14..d5d03f2bfa 100644
--- a/lib/std/crypto/chacha20.zig
+++ b/lib/std/crypto/chacha20.zig
@@ -49,13 +49,13 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void {
// two-round cycles
inline for (rounds) |r| {
x[r.a] +%= x[r.b];
- x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], u32(16));
+ x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], @as(u32, 16));
x[r.c] +%= x[r.d];
- x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], u32(12));
+ x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], @as(u32, 12));
x[r.a] +%= x[r.b];
- x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], u32(8));
+ x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], @as(u32, 8));
x[r.c] +%= x[r.d];
- x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], u32(7));
+ x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], @as(u32, 7));
}
}
diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig
index 0a0a5056c6..0d18afd705 100644
--- a/lib/std/crypto/gimli.zig
+++ b/lib/std/crypto/gimli.zig
@@ -34,9 +34,9 @@ pub const State = struct {
pub fn permute(self: *Self) void {
const state = &self.data;
- var round = u32(24);
+ var round = @as(u32, 24);
while (round > 0) : (round -= 1) {
- var column = usize(0);
+ var column = @as(usize, 0);
while (column < 4) : (column += 1) {
const x = math.rotl(u32, state[column], 24);
const y = math.rotl(u32, state[4 + column], 9);
@@ -61,7 +61,7 @@ pub const State = struct {
}
pub fn squeeze(self: *Self, out: []u8) void {
- var i = usize(0);
+ var i = @as(usize, 0);
while (i + RATE <= out.len) : (i += RATE) {
self.permute();
mem.copy(u8, out[i..], self.toSliceConst()[0..RATE]);
@@ -79,7 +79,7 @@ test "permute" {
var state = State{
.data = blk: {
var input: [12]u32 = undefined;
- var i = u32(0);
+ var i = @as(u32, 0);
while (i < 12) : (i += 1) {
input[i] = i * i * i + i *% 0x9e3779b9;
}
diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig
index ddbb39a9df..db6150699d 100644
--- a/lib/std/crypto/md5.zig
+++ b/lib/std/crypto/md5.zig
@@ -126,10 +126,10 @@ pub const Md5 = struct {
while (i < 16) : (i += 1) {
// NOTE: Performing or's separately improves perf by ~10%
s[i] = 0;
- s[i] |= u32(b[i * 4 + 0]);
- s[i] |= u32(b[i * 4 + 1]) << 8;
- s[i] |= u32(b[i * 4 + 2]) << 16;
- s[i] |= u32(b[i * 4 + 3]) << 24;
+ s[i] |= @as(u32, b[i * 4 + 0]);
+ s[i] |= @as(u32, b[i * 4 + 1]) << 8;
+ s[i] |= @as(u32, b[i * 4 + 2]) << 16;
+ s[i] |= @as(u32, b[i * 4 + 3]) << 24;
}
var v: [4]u32 = [_]u32{
diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig
index bd0b33e586..78881ba049 100644
--- a/lib/std/crypto/poly1305.zig
+++ b/lib/std/crypto/poly1305.zig
@@ -87,11 +87,11 @@ pub const Poly1305 = struct {
// ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff
fn polyBlock(ctx: *Self) void {
// s = h + c, without carry propagation
- const s0 = u64(ctx.h[0]) + ctx.c[0]; // s0 <= 1_fffffffe
- const s1 = u64(ctx.h[1]) + ctx.c[1]; // s1 <= 1_fffffffe
- const s2 = u64(ctx.h[2]) + ctx.c[2]; // s2 <= 1_fffffffe
- const s3 = u64(ctx.h[3]) + ctx.c[3]; // s3 <= 1_fffffffe
- const s4 = u64(ctx.h[4]) + ctx.c[4]; // s4 <= 5
+ const s0 = @as(u64, ctx.h[0]) + ctx.c[0]; // s0 <= 1_fffffffe
+ const s1 = @as(u64, ctx.h[1]) + ctx.c[1]; // s1 <= 1_fffffffe
+ const s2 = @as(u64, ctx.h[2]) + ctx.c[2]; // s2 <= 1_fffffffe
+ const s3 = @as(u64, ctx.h[3]) + ctx.c[3]; // s3 <= 1_fffffffe
+ const s4 = @as(u64, ctx.h[4]) + ctx.c[4]; // s4 <= 5
// Local all the things!
const r0 = ctx.r[0]; // r0 <= 0fffffff
@@ -197,7 +197,7 @@ pub const Poly1305 = struct {
// check if we should subtract 2^130-5 by performing the
// corresponding carry propagation.
- const _u0 = u64(5) + ctx.h[0]; // <= 1_00000004
+ const _u0 = @as(u64, 5) + ctx.h[0]; // <= 1_00000004
const _u1 = (_u0 >> 32) + ctx.h[1]; // <= 1_00000000
const _u2 = (_u1 >> 32) + ctx.h[2]; // <= 1_00000000
const _u3 = (_u2 >> 32) + ctx.h[3]; // <= 1_00000000
diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig
index c5160a1f37..c17ef2daf7 100644
--- a/lib/std/crypto/sha1.zig
+++ b/lib/std/crypto/sha1.zig
@@ -146,10 +146,10 @@ pub const Sha1 = struct {
Rp(0, 1, 2, 3, 4, 15),
};
inline for (round0a) |r| {
- s[r.i] = (u32(b[r.i * 4 + 0]) << 24) | (u32(b[r.i * 4 + 1]) << 16) | (u32(b[r.i * 4 + 2]) << 8) | (u32(b[r.i * 4 + 3]) << 0);
+ s[r.i] = (@as(u32, b[r.i * 4 + 0]) << 24) | (@as(u32, b[r.i * 4 + 1]) << 16) | (@as(u32, b[r.i * 4 + 2]) << 8) | (@as(u32, b[r.i * 4 + 3]) << 0);
- v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
- v[r.b] = math.rotl(u32, v[r.b], u32(30));
+ v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
+ v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
}
const round0b = comptime [_]RoundParam{
@@ -160,10 +160,10 @@ pub const Sha1 = struct {
};
inline for (round0b) |r| {
const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
- s[r.i & 0xf] = math.rotl(u32, t, u32(1));
+ s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
- v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
- v[r.b] = math.rotl(u32, v[r.b], u32(30));
+ v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
+ v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
}
const round1 = comptime [_]RoundParam{
@@ -190,10 +190,10 @@ pub const Sha1 = struct {
};
inline for (round1) |r| {
const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
- s[r.i & 0xf] = math.rotl(u32, t, u32(1));
+ s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
- v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
- v[r.b] = math.rotl(u32, v[r.b], u32(30));
+ v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
+ v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
}
const round2 = comptime [_]RoundParam{
@@ -220,10 +220,10 @@ pub const Sha1 = struct {
};
inline for (round2) |r| {
const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
- s[r.i & 0xf] = math.rotl(u32, t, u32(1));
+ s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
- v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));
- v[r.b] = math.rotl(u32, v[r.b], u32(30));
+ v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));
+ v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
}
const round3 = comptime [_]RoundParam{
@@ -250,10 +250,10 @@ pub const Sha1 = struct {
};
inline for (round3) |r| {
const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
- s[r.i & 0xf] = math.rotl(u32, t, u32(1));
+ s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
- v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
- v[r.b] = math.rotl(u32, v[r.b], u32(30));
+ v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
+ v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
}
d.s[0] +%= v[0];
diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig
index b40a39d579..77698176bd 100644
--- a/lib/std/crypto/sha2.zig
+++ b/lib/std/crypto/sha2.zig
@@ -180,13 +180,13 @@ fn Sha2_32(comptime params: Sha2Params32) type {
var i: usize = 0;
while (i < 16) : (i += 1) {
s[i] = 0;
- s[i] |= u32(b[i * 4 + 0]) << 24;
- s[i] |= u32(b[i * 4 + 1]) << 16;
- s[i] |= u32(b[i * 4 + 2]) << 8;
- s[i] |= u32(b[i * 4 + 3]) << 0;
+ s[i] |= @as(u32, b[i * 4 + 0]) << 24;
+ s[i] |= @as(u32, b[i * 4 + 1]) << 16;
+ s[i] |= @as(u32, b[i * 4 + 2]) << 8;
+ s[i] |= @as(u32, b[i * 4 + 3]) << 0;
}
while (i < 64) : (i += 1) {
- s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u32, s[i - 15], u32(7)) ^ math.rotr(u32, s[i - 15], u32(18)) ^ (s[i - 15] >> 3)) +% (math.rotr(u32, s[i - 2], u32(17)) ^ math.rotr(u32, s[i - 2], u32(19)) ^ (s[i - 2] >> 10));
+ s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u32, s[i - 15], @as(u32, 7)) ^ math.rotr(u32, s[i - 15], @as(u32, 18)) ^ (s[i - 15] >> 3)) +% (math.rotr(u32, s[i - 2], @as(u32, 17)) ^ math.rotr(u32, s[i - 2], @as(u32, 19)) ^ (s[i - 2] >> 10));
}
var v: [8]u32 = [_]u32{
@@ -267,11 +267,11 @@ fn Sha2_32(comptime params: Sha2Params32) type {
Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),
};
inline for (round0) |r| {
- v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], u32(6)) ^ math.rotr(u32, v[r.e], u32(11)) ^ math.rotr(u32, v[r.e], u32(25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
+ v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], @as(u32, 6)) ^ math.rotr(u32, v[r.e], @as(u32, 11)) ^ math.rotr(u32, v[r.e], @as(u32, 25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
v[r.d] = v[r.d] +% v[r.h];
- v[r.h] = v[r.h] +% (math.rotr(u32, v[r.a], u32(2)) ^ math.rotr(u32, v[r.a], u32(13)) ^ math.rotr(u32, v[r.a], u32(22))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
+ v[r.h] = v[r.h] +% (math.rotr(u32, v[r.a], @as(u32, 2)) ^ math.rotr(u32, v[r.a], @as(u32, 13)) ^ math.rotr(u32, v[r.a], @as(u32, 22))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
}
d.s[0] +%= v[0];
@@ -522,17 +522,19 @@ fn Sha2_64(comptime params: Sha2Params64) type {
var i: usize = 0;
while (i < 16) : (i += 1) {
s[i] = 0;
- s[i] |= u64(b[i * 8 + 0]) << 56;
- s[i] |= u64(b[i * 8 + 1]) << 48;
- s[i] |= u64(b[i * 8 + 2]) << 40;
- s[i] |= u64(b[i * 8 + 3]) << 32;
- s[i] |= u64(b[i * 8 + 4]) << 24;
- s[i] |= u64(b[i * 8 + 5]) << 16;
- s[i] |= u64(b[i * 8 + 6]) << 8;
- s[i] |= u64(b[i * 8 + 7]) << 0;
+ s[i] |= @as(u64, b[i * 8 + 0]) << 56;
+ s[i] |= @as(u64, b[i * 8 + 1]) << 48;
+ s[i] |= @as(u64, b[i * 8 + 2]) << 40;
+ s[i] |= @as(u64, b[i * 8 + 3]) << 32;
+ s[i] |= @as(u64, b[i * 8 + 4]) << 24;
+ s[i] |= @as(u64, b[i * 8 + 5]) << 16;
+ s[i] |= @as(u64, b[i * 8 + 6]) << 8;
+ s[i] |= @as(u64, b[i * 8 + 7]) << 0;
}
while (i < 80) : (i += 1) {
- s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u64, s[i - 15], u64(1)) ^ math.rotr(u64, s[i - 15], u64(8)) ^ (s[i - 15] >> 7)) +% (math.rotr(u64, s[i - 2], u64(19)) ^ math.rotr(u64, s[i - 2], u64(61)) ^ (s[i - 2] >> 6));
+ s[i] = s[i - 16] +% s[i - 7] +%
+ (math.rotr(u64, s[i - 15], @as(u64, 1)) ^ math.rotr(u64, s[i - 15], @as(u64, 8)) ^ (s[i - 15] >> 7)) +%
+ (math.rotr(u64, s[i - 2], @as(u64, 19)) ^ math.rotr(u64, s[i - 2], @as(u64, 61)) ^ (s[i - 2] >> 6));
}
var v: [8]u64 = [_]u64{
@@ -629,11 +631,11 @@ fn Sha2_64(comptime params: Sha2Params64) type {
Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
};
inline for (round0) |r| {
- v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], u64(14)) ^ math.rotr(u64, v[r.e], u64(18)) ^ math.rotr(u64, v[r.e], u64(41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
+ v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], @as(u64, 14)) ^ math.rotr(u64, v[r.e], @as(u64, 18)) ^ math.rotr(u64, v[r.e], @as(u64, 41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
v[r.d] = v[r.d] +% v[r.h];
- v[r.h] = v[r.h] +% (math.rotr(u64, v[r.a], u64(28)) ^ math.rotr(u64, v[r.a], u64(34)) ^ math.rotr(u64, v[r.a], u64(39))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
+ v[r.h] = v[r.h] +% (math.rotr(u64, v[r.a], @as(u64, 28)) ^ math.rotr(u64, v[r.a], @as(u64, 34)) ^ math.rotr(u64, v[r.a], @as(u64, 39))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
}
d.s[0] +%= v[0];
diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig
index 659e7a254f..d417ef07e2 100644
--- a/lib/std/crypto/sha3.zig
+++ b/lib/std/crypto/sha3.zig
@@ -133,7 +133,7 @@ fn keccak_f(comptime F: usize, d: []u8) void {
}
x = 0;
inline while (x < 5) : (x += 1) {
- t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], usize(1));
+ t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], @as(usize, 1));
y = 0;
inline while (y < 5) : (y += 1) {
s[x + y * 5] ^= t[0];
diff --git a/lib/std/crypto/x25519.zig b/lib/std/crypto/x25519.zig
index 7f9220c3f4..223d65f8f4 100644
--- a/lib/std/crypto/x25519.zig
+++ b/lib/std/crypto/x25519.zig
@@ -256,15 +256,15 @@ const Fe = struct {
var t: [10]i64 = undefined;
t[0] = readIntSliceLittle(u32, s[0..4]);
- t[1] = u32(readIntSliceLittle(u24, s[4..7])) << 6;
- t[2] = u32(readIntSliceLittle(u24, s[7..10])) << 5;
- t[3] = u32(readIntSliceLittle(u24, s[10..13])) << 3;
- t[4] = u32(readIntSliceLittle(u24, s[13..16])) << 2;
+ t[1] = @as(u32, readIntSliceLittle(u24, s[4..7])) << 6;
+ t[2] = @as(u32, readIntSliceLittle(u24, s[7..10])) << 5;
+ t[3] = @as(u32, readIntSliceLittle(u24, s[10..13])) << 3;
+ t[4] = @as(u32, readIntSliceLittle(u24, s[13..16])) << 2;
t[5] = readIntSliceLittle(u32, s[16..20]);
- t[6] = u32(readIntSliceLittle(u24, s[20..23])) << 7;
- t[7] = u32(readIntSliceLittle(u24, s[23..26])) << 5;
- t[8] = u32(readIntSliceLittle(u24, s[26..29])) << 4;
- t[9] = (u32(readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2;
+ t[6] = @as(u32, readIntSliceLittle(u24, s[20..23])) << 7;
+ t[7] = @as(u32, readIntSliceLittle(u24, s[23..26])) << 5;
+ t[8] = @as(u32, readIntSliceLittle(u24, s[26..29])) << 4;
+ t[9] = (@as(u32, readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2;
carry1(h, t[0..]);
}
@@ -500,7 +500,7 @@ const Fe = struct {
if (i + 1 < 10) {
t[i + 1] += c[i];
}
- t[i] -= c[i] * (i32(1) << shift);
+ t[i] -= c[i] * (@as(i32, 1) << shift);
}
fn toBytes(s: []u8, h: *const Fe) void {
@@ -511,7 +511,7 @@ const Fe = struct {
t[i] = h.b[i];
}
- var q = (19 * t[9] + ((i32(1) << 24))) >> 25;
+ var q = (19 * t[9] + ((@as(i32, 1) << 24))) >> 25;
{
var i: usize = 0;
while (i < 5) : (i += 1) {
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index cd0c3863ff..02305086cc 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -1008,7 +1008,7 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
const word = try stream.readIntLittle(u32);
var bit_i: u5 = 0;
while (true) : (bit_i += 1) {
- if (word & (u32(1) << bit_i) != 0) {
+ if (word & (@as(u32, 1) << bit_i) != 0) {
try list.append(word_i * 32 + bit_i);
}
if (bit_i == maxInt(u5)) break;
@@ -1556,13 +1556,14 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
// TODO the noasyncs here are workarounds
fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
- return if (is_64) try noasync in_stream.readIntLittle(u64) else u64(try noasync in_stream.readIntLittle(u32));
+ return if (is_64) try noasync in_stream.readIntLittle(u64) else @as(u64, try noasync in_stream.readIntLittle(u32));
}
// TODO the noasyncs here are workarounds
fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
if (@sizeOf(usize) == 4) {
- return u64(try noasync in_stream.readIntLittle(u32));
+ // TODO this cast should not be needed
+ return @as(u64, try noasync in_stream.readIntLittle(u32));
} else if (@sizeOf(usize) == 8) {
return noasync in_stream.readIntLittle(u64);
} else {
@@ -1846,7 +1847,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
// special opcodes
const adjusted_opcode = opcode - opcode_base;
const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
- const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);
+ const inc_line = @as(i32, line_base) + @as(i32, adjusted_opcode % line_range);
prog.line += inc_line;
prog.address += inc_addr;
if (try prog.checkLineMatch()) |info| return info;
@@ -1913,7 +1914,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr
if (unit_length == 0) {
return error.MissingDebugInfo;
}
- const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
+ const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
const version = try di.dwarf_in_stream.readInt(u16, di.endian);
// TODO support 3 and 5
@@ -2012,7 +2013,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr
// special opcodes
const adjusted_opcode = opcode - opcode_base;
const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
- const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);
+ const inc_line = @as(i32, line_base) + @as(i32, adjusted_opcode % line_range);
prog.line += inc_line;
prog.address += inc_addr;
if (try prog.checkLineMatch()) |info| return info;
@@ -2093,7 +2094,7 @@ fn scanAllFunctions(di: *DwarfInfo) !void {
var is_64: bool = undefined;
const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
if (unit_length == 0) return;
- const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
+ const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
const version = try di.dwarf_in_stream.readInt(u16, di.endian);
if (version < 2 or version > 5) return error.InvalidDebugInfo;
@@ -2195,7 +2196,7 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
var is_64: bool = undefined;
const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
if (unit_length == 0) return;
- const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
+ const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
const version = try di.dwarf_in_stream.readInt(u16, di.endian);
if (version < 2 or version > 5) return error.InvalidDebugInfo;
@@ -2312,7 +2313,8 @@ fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {
} else {
if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
ptr.* += 4;
- return u64(first_32_bits);
+ // TODO this cast should not be needed
+ return @as(u64, first_32_bits);
}
}
@@ -2329,7 +2331,8 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)
return in_stream.readIntLittle(u64);
} else {
if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
- return u64(first_32_bits);
+ // TODO this cast should not be needed
+ return @as(u64, first_32_bits);
}
}
diff --git a/lib/std/debug/leb128.zig b/lib/std/debug/leb128.zig
index cb59c5b0d2..ee1d1ac9ee 100644
--- a/lib/std/debug/leb128.zig
+++ b/lib/std/debug/leb128.zig
@@ -62,13 +62,13 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {
var shift: usize = 0;
while (true) {
- const byte = u8(try in_stream.readByte());
+ const byte: u8 = try in_stream.readByte();
if (shift > T.bit_count)
return error.Overflow;
var operand: UT = undefined;
- if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
+ if (@shlWithOverflow(UT, @as(UT, byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
if (byte != 0x7f)
return error.Overflow;
}
diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig
index 3413788019..0e8792ca90 100644
--- a/lib/std/dynamic_library.zig
+++ b/lib/std/dynamic_library.zig
@@ -215,8 +215,8 @@ pub const ElfLib = struct {
var i: usize = 0;
while (i < self.hashtab[1]) : (i += 1) {
- if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
- if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
+ if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
+ if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
if (0 == self.syms[i].st_shndx) continue;
if (!mem.eql(u8, name, mem.toSliceConst(u8, self.strings + self.syms[i].st_name))) continue;
if (maybe_versym) |versym| {
diff --git a/lib/std/elf.zig b/lib/std/elf.zig
index b3aea3e5c6..3bb4054bfe 100644
--- a/lib/std/elf.zig
+++ b/lib/std/elf.zig
@@ -441,9 +441,9 @@ pub const Elf = struct {
elf.program_header_offset = try in.readInt(u64, elf.endian);
elf.section_header_offset = try in.readInt(u64, elf.endian);
} else {
- elf.entry_addr = u64(try in.readInt(u32, elf.endian));
- elf.program_header_offset = u64(try in.readInt(u32, elf.endian));
- elf.section_header_offset = u64(try in.readInt(u32, elf.endian));
+ elf.entry_addr = @as(u64, try in.readInt(u32, elf.endian));
+ elf.program_header_offset = @as(u64, try in.readInt(u32, elf.endian));
+ elf.section_header_offset = @as(u64, try in.readInt(u32, elf.endian));
}
// skip over flags
@@ -458,13 +458,13 @@ pub const Elf = struct {
const ph_entry_count = try in.readInt(u16, elf.endian);
const sh_entry_size = try in.readInt(u16, elf.endian);
const sh_entry_count = try in.readInt(u16, elf.endian);
- elf.string_section_index = usize(try in.readInt(u16, elf.endian));
+ elf.string_section_index = @as(usize, try in.readInt(u16, elf.endian));
if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;
- const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count);
+ const sh_byte_count = @as(u64, sh_entry_size) * @as(u64, sh_entry_count);
const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count);
- const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count);
+ const ph_byte_count = @as(u64, ph_entry_size) * @as(u64, ph_entry_count);
const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count);
const stream_end = try seekable_stream.getEndPos();
@@ -499,14 +499,14 @@ pub const Elf = struct {
// TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ?
elf_section.name = try in.readInt(u32, elf.endian);
elf_section.sh_type = try in.readInt(u32, elf.endian);
- elf_section.flags = u64(try in.readInt(u32, elf.endian));
- elf_section.addr = u64(try in.readInt(u32, elf.endian));
- elf_section.offset = u64(try in.readInt(u32, elf.endian));
- elf_section.size = u64(try in.readInt(u32, elf.endian));
+ elf_section.flags = @as(u64, try in.readInt(u32, elf.endian));
+ elf_section.addr = @as(u64, try in.readInt(u32, elf.endian));
+ elf_section.offset = @as(u64, try in.readInt(u32, elf.endian));
+ elf_section.size = @as(u64, try in.readInt(u32, elf.endian));
elf_section.link = try in.readInt(u32, elf.endian);
elf_section.info = try in.readInt(u32, elf.endian);
- elf_section.addr_align = u64(try in.readInt(u32, elf.endian));
- elf_section.ent_size = u64(try in.readInt(u32, elf.endian));
+ elf_section.addr_align = @as(u64, try in.readInt(u32, elf.endian));
+ elf_section.ent_size = @as(u64, try in.readInt(u32, elf.endian));
}
}
diff --git a/lib/std/event/fs.zig b/lib/std/event/fs.zig
index d86bcbaed5..1035a51b81 100644
--- a/lib/std/event/fs.zig
+++ b/lib/std/event/fs.zig
@@ -328,11 +328,11 @@ pub fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize {
windows.ERROR.IO_PENDING => unreachable,
windows.ERROR.OPERATION_ABORTED => return error.OperationAborted,
windows.ERROR.BROKEN_PIPE => return error.BrokenPipe,
- windows.ERROR.HANDLE_EOF => return usize(bytes_transferred),
+ windows.ERROR.HANDLE_EOF => return @as(usize, bytes_transferred),
else => |err| return windows.unexpectedError(err),
}
}
- return usize(bytes_transferred);
+ return @as(usize, bytes_transferred);
}
/// iovecs must live until preadv frame completes
diff --git a/lib/std/fifo.zig b/lib/std/fifo.zig
index b47dda34de..73f9b2dee7 100644
--- a/lib/std/fifo.zig
+++ b/lib/std/fifo.zig
@@ -257,7 +257,7 @@ test "ByteFifo" {
defer fifo.deinit();
try fifo.write("HELLO");
- testing.expectEqual(usize(5), fifo.readableLength());
+ testing.expectEqual(@as(usize, 5), fifo.readableLength());
testing.expectEqualSlices(u8, "HELLO", fifo.readableSlice(0));
{
@@ -265,34 +265,34 @@ test "ByteFifo" {
while (i < 5) : (i += 1) {
try fifo.write([_]u8{try fifo.peekItem(i)});
}
- testing.expectEqual(usize(10), fifo.readableLength());
+ testing.expectEqual(@as(usize, 10), fifo.readableLength());
testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0));
}
{
- testing.expectEqual(u8('H'), try fifo.readItem());
- testing.expectEqual(u8('E'), try fifo.readItem());
- testing.expectEqual(u8('L'), try fifo.readItem());
- testing.expectEqual(u8('L'), try fifo.readItem());
- testing.expectEqual(u8('O'), try fifo.readItem());
+ testing.expectEqual(@as(u8, 'H'), try fifo.readItem());
+ testing.expectEqual(@as(u8, 'E'), try fifo.readItem());
+ testing.expectEqual(@as(u8, 'L'), try fifo.readItem());
+ testing.expectEqual(@as(u8, 'L'), try fifo.readItem());
+ testing.expectEqual(@as(u8, 'O'), try fifo.readItem());
}
- testing.expectEqual(usize(5), fifo.readableLength());
+ testing.expectEqual(@as(usize, 5), fifo.readableLength());
{ // Writes that wrap around
- testing.expectEqual(usize(11), fifo.writableLength());
- testing.expectEqual(usize(6), fifo.writableSlice(0).len);
+ testing.expectEqual(@as(usize, 11), fifo.writableLength());
+ testing.expectEqual(@as(usize, 6), fifo.writableSlice(0).len);
fifo.writeAssumeCapacity("6 buf.len) (width - buf.len) else return;
const pad_byte: u8 = options.fill;
while (leftover_padding > 0) : (leftover_padding -= 1) {
- try output(context, (*const [1]u8)(&pad_byte)[0..1]);
+ try output(context, @as(*const [1]u8, &pad_byte)[0..1]);
}
}
@@ -668,7 +668,7 @@ pub fn formatFloatScientific(
try output(context, float_decimal.digits[0..1]);
try output(context, ".");
if (float_decimal.digits.len > 1) {
- const num_digits = if (@typeOf(value) == f32) math.min(usize(9), float_decimal.digits.len) else float_decimal.digits.len;
+ const num_digits = if (@typeOf(value) == f32) math.min(@as(usize, 9), float_decimal.digits.len) else float_decimal.digits.len;
try output(context, float_decimal.digits[1..num_digits]);
} else {
@@ -703,7 +703,7 @@ pub fn formatFloatDecimal(
comptime Errors: type,
output: fn (@typeOf(context), []const u8) Errors!void,
) Errors!void {
- var x = f64(value);
+ var x = @as(f64, value);
// Errol doesn't handle these special cases.
if (math.signbit(x)) {
@@ -921,14 +921,14 @@ fn formatIntSigned(
const uint = @IntType(false, @typeOf(value).bit_count);
if (value < 0) {
const minus_sign: u8 = '-';
- try output(context, (*const [1]u8)(&minus_sign)[0..]);
+ try output(context, @as(*const [1]u8, &minus_sign)[0..]);
const new_value = @intCast(uint, -(value + 1)) + 1;
return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);
} else if (options.width == null or options.width.? == 0) {
return formatIntUnsigned(@intCast(uint, value), base, uppercase, options, context, Errors, output);
} else {
const plus_sign: u8 = '+';
- try output(context, (*const [1]u8)(&plus_sign)[0..]);
+ try output(context, @as(*const [1]u8, &plus_sign)[0..]);
const new_value = @intCast(uint, value);
return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);
}
@@ -966,7 +966,7 @@ fn formatIntUnsigned(
const zero_byte: u8 = options.fill;
var leftover_padding = padding - index;
while (true) {
- try output(context, (*const [1]u8)(&zero_byte)[0..]);
+ try output(context, @as(*const [1]u8, &zero_byte)[0..]);
leftover_padding -= 1;
if (leftover_padding == 0) break;
}
@@ -1088,7 +1088,7 @@ pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
fn digitToChar(digit: u8, uppercase: bool) u8 {
return switch (digit) {
0...9 => digit + '0',
- 10...35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
+ 10...35 => digit + ((if (uppercase) @as(u8, 'A') else @as(u8, 'a')) - 10),
else => unreachable,
};
}
@@ -1134,19 +1134,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
test "bufPrintInt" {
var buffer: [100]u8 = undefined;
const buf = buffer[0..];
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, FormatOptions{}), "-12345678"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, FormatOptions{}), "-bc614e"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, FormatOptions{}), "-BC614E"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, FormatOptions{}), "12345678"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, FormatOptions{ .width = 6 }), " 666"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), " 666"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, FormatOptions{ .width = 3 }), "+42"));
- testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, FormatOptions{ .width = 3 }), "-42"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42"));
}
fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: FormatOptions) []u8 {
@@ -1208,8 +1208,8 @@ test "int.specifier" {
}
test "int.padded" {
- try testFmt("u8: ' 1'", "u8: '{:4}'", u8(1));
- try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", u8(1));
+ try testFmt("u8: ' 1'", "u8: '{:4}'", @as(u8, 1));
+ try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", @as(u8, 1));
}
test "buffer" {
@@ -1287,8 +1287,8 @@ test "filesize" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));
- try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", usize(63 * 1024 * 1024));
+ try testFmt("file size: 63MiB\n", "file size: {Bi}\n", @as(usize, 63 * 1024 * 1024));
+ try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", @as(usize, 63 * 1024 * 1024));
}
test "struct" {
@@ -1327,8 +1327,8 @@ test "float.scientific" {
}
try testFmt("f32: 1.34000003e+00", "f32: {e}", f32(1.34));
try testFmt("f32: 1.23400001e+01", "f32: {e}", f32(12.34));
- try testFmt("f64: -1.234e+11", "f64: {e}", f64(-12.34e10));
- try testFmt("f64: 9.99996e-40", "f64: {e}", f64(9.999960e-40));
+ try testFmt("f64: -1.234e+11", "f64: {e}", @as(f64, -12.34e10));
+ try testFmt("f64: 9.99996e-40", "f64: {e}", @as(f64, 9.999960e-40));
}
test "float.scientific.precision" {
@@ -1336,12 +1336,12 @@ test "float.scientific.precision" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- try testFmt("f64: 1.40971e-42", "f64: {e:.5}", f64(1.409706e-42));
- try testFmt("f64: 1.00000e-09", "f64: {e:.5}", f64(@bitCast(f32, u32(814313563))));
- try testFmt("f64: 7.81250e-03", "f64: {e:.5}", f64(@bitCast(f32, u32(1006632960))));
+ try testFmt("f64: 1.40971e-42", "f64: {e:.5}", @as(f64, 1.409706e-42));
+ try testFmt("f64: 1.00000e-09", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 814313563))));
+ try testFmt("f64: 7.81250e-03", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 1006632960))));
// libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
// In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
- try testFmt("f64: 1.00001e+05", "f64: {e:.5}", f64(@bitCast(f32, u32(1203982400))));
+ try testFmt("f64: 1.00001e+05", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 1203982400))));
}
test "float.special" {
@@ -1364,21 +1364,21 @@ test "float.decimal" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- try testFmt("f64: 152314000000000000000000000000", "f64: {d}", f64(1.52314e+29));
+ try testFmt("f64: 152314000000000000000000000000", "f64: {d}", @as(f64, 1.52314e+29));
try testFmt("f32: 1.1", "f32: {d:.1}", f32(1.1234));
try testFmt("f32: 1234.57", "f32: {d:.2}", f32(1234.567));
// -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
// -11.12339... is rounded back up to -11.1234
try testFmt("f32: -11.1234", "f32: {d:.4}", f32(-11.1234));
try testFmt("f32: 91.12345", "f32: {d:.5}", f32(91.12345));
- try testFmt("f64: 91.1234567890", "f64: {d:.10}", f64(91.12345678901235));
- try testFmt("f64: 0.00000", "f64: {d:.5}", f64(0.0));
- try testFmt("f64: 6", "f64: {d:.0}", f64(5.700));
- try testFmt("f64: 10.0", "f64: {d:.1}", f64(9.999));
- try testFmt("f64: 1.000", "f64: {d:.3}", f64(1.0));
- try testFmt("f64: 0.00030000", "f64: {d:.8}", f64(0.0003));
- try testFmt("f64: 0.00000", "f64: {d:.5}", f64(1.40130e-45));
- try testFmt("f64: 0.00000", "f64: {d:.5}", f64(9.999960e-40));
+ try testFmt("f64: 91.1234567890", "f64: {d:.10}", @as(f64, 91.12345678901235));
+ try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 0.0));
+ try testFmt("f64: 6", "f64: {d:.0}", @as(f64, 5.700));
+ try testFmt("f64: 10.0", "f64: {d:.1}", @as(f64, 9.999));
+ try testFmt("f64: 1.000", "f64: {d:.3}", @as(f64, 1.0));
+ try testFmt("f64: 0.00030000", "f64: {d:.8}", @as(f64, 0.0003));
+ try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 1.40130e-45));
+ try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 9.999960e-40));
}
test "float.libc.sanity" {
@@ -1386,22 +1386,22 @@ test "float.libc.sanity" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(916964781))));
- try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(925353389))));
- try testFmt("f64: 0.10000", "f64: {d:.5}", f64(@bitCast(f32, u32(1036831278))));
- try testFmt("f64: 1.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1065353133))));
- try testFmt("f64: 10.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1092616192))));
+ try testFmt("f64: 0.00001", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 916964781))));
+ try testFmt("f64: 0.00001", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 925353389))));
+ try testFmt("f64: 0.10000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1036831278))));
+ try testFmt("f64: 1.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1065353133))));
+ try testFmt("f64: 10.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1092616192))));
// libc differences
//
// This is 0.015625 exactly according to gdb. We thus round down,
// however glibc rounds up for some reason. This occurs for all
// floats of the form x.yyyy25 on a precision point.
- try testFmt("f64: 0.01563", "f64: {d:.5}", f64(@bitCast(f32, u32(1015021568))));
+ try testFmt("f64: 0.01563", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1015021568))));
// errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
// also rounds to 630 so I'm inclined to believe libc is not
// optimal here.
- try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1518338049))));
+ try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1518338049))));
}
test "custom" {
@@ -1677,17 +1677,17 @@ test "formatType max_depth" {
}
test "positional" {
- try testFmt("2 1 0", "{2} {1} {0}", usize(0), usize(1), usize(2));
- try testFmt("2 1 0", "{2} {1} {}", usize(0), usize(1), usize(2));
- try testFmt("0 0", "{0} {0}", usize(0));
- try testFmt("0 1", "{} {1}", usize(0), usize(1));
- try testFmt("1 0 0 1", "{1} {} {0} {}", usize(0), usize(1));
+ try testFmt("2 1 0", "{2} {1} {0}", @as(usize, 0), @as(usize, 1), @as(usize, 2));
+ try testFmt("2 1 0", "{2} {1} {}", @as(usize, 0), @as(usize, 1), @as(usize, 2));
+ try testFmt("0 0", "{0} {0}", @as(usize, 0));
+ try testFmt("0 1", "{} {1}", @as(usize, 0), @as(usize, 1));
+ try testFmt("1 0 0 1", "{1} {} {0} {}", @as(usize, 0), @as(usize, 1));
}
test "positional with specifier" {
- try testFmt("10.0", "{0d:.1}", f64(9.999));
+ try testFmt("10.0", "{0d:.1}", @as(f64, 9.999));
}
test "positional/alignment/width/precision" {
- try testFmt("10.0", "{0d: >3.1}", f64(9.999));
+ try testFmt("10.0", "{0d: >3.1}", @as(f64, 9.999));
}
diff --git a/lib/std/fmt/errol.zig b/lib/std/fmt/errol.zig
index a835195fc7..e697b7d42f 100644
--- a/lib/std/fmt/errol.zig
+++ b/lib/std/fmt/errol.zig
@@ -296,7 +296,7 @@ fn hpMul10(hp: *HP) void {
/// @buf: The output buffer.
/// &return: The exponent.
fn errolInt(val: f64, buffer: []u8) FloatDecimal {
- const pow19 = u128(1e19);
+ const pow19 = @as(u128, 1e19);
assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
@@ -670,7 +670,7 @@ fn fpeint(from: f64) u128 {
const bits = @bitCast(u64, from);
assert((bits & ((1 << 52) - 1)) == 0);
- return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
+ return @as(u128, 1) << @truncate(u7, (bits >> 52) -% 1023);
}
/// Given two different integers with the same length in terms of the number
diff --git a/lib/std/fmt/parse_float.zig b/lib/std/fmt/parse_float.zig
index 9a35e27c21..aa3ac6d458 100644
--- a/lib/std/fmt/parse_float.zig
+++ b/lib/std/fmt/parse_float.zig
@@ -59,29 +59,29 @@ const Z96 = struct {
// d += s
inline fn add(d: *Z96, s: Z96) void {
- var w = u64(d.d0) + u64(s.d0);
+ var w = @as(u64, d.d0) + @as(u64, s.d0);
d.d0 = @truncate(u32, w);
w >>= 32;
- w += u64(d.d1) + u64(s.d1);
+ w += @as(u64, d.d1) + @as(u64, s.d1);
d.d1 = @truncate(u32, w);
w >>= 32;
- w += u64(d.d2) + u64(s.d2);
+ w += @as(u64, d.d2) + @as(u64, s.d2);
d.d2 = @truncate(u32, w);
}
// d -= s
inline fn sub(d: *Z96, s: Z96) void {
- var w = u64(d.d0) -% u64(s.d0);
+ var w = @as(u64, d.d0) -% @as(u64, s.d0);
d.d0 = @truncate(u32, w);
w >>= 32;
- w += u64(d.d1) -% u64(s.d1);
+ w += @as(u64, d.d1) -% @as(u64, s.d1);
d.d1 = @truncate(u32, w);
w >>= 32;
- w += u64(d.d2) -% u64(s.d2);
+ w += @as(u64, d.d2) -% @as(u64, s.d2);
d.d2 = @truncate(u32, w);
}
};
@@ -160,7 +160,7 @@ fn convertRepr(comptime T: type, n: FloatRepr) T {
break :blk if (n.negative) f64_minus_zero else f64_plus_zero;
} else if (s.d2 != 0) {
const binexs2 = @intCast(u64, binary_exponent) << 52;
- const rr = (u64(s.d2 & ~mask28) << 24) | ((u64(s.d1) + 128) >> 8) | binexs2;
+ const rr = (@as(u64, s.d2 & ~mask28) << 24) | ((@as(u64, s.d1) + 128) >> 8) | binexs2;
break :blk if (n.negative) rr | (1 << 63) else rr;
} else {
break :blk 0;
diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig
index 431b89bebf..117e49369a 100644
--- a/lib/std/fs/file.zig
+++ b/lib/std/fs/file.zig
@@ -272,9 +272,9 @@ pub const File = struct {
return Stat{
.size = @bitCast(u64, st.size),
.mode = st.mode,
- .atime = i64(atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
- .mtime = i64(mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
- .ctime = i64(ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
+ .atime = @as(i64, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
+ .mtime = @as(i64, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
+ .ctime = @as(i64, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
};
}
diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig
index 3a4abcbcd9..1df434116c 100644
--- a/lib/std/hash/auto_hash.zig
+++ b/lib/std/hash/auto_hash.zig
@@ -306,7 +306,7 @@ test "hash struct deep" {
test "testHash optional" {
const a: ?u32 = 123;
const b: ?u32 = null;
- testing.expectEqual(testHash(a), testHash(u32(123)));
+ testing.expectEqual(testHash(a), testHash(@as(u32, 123)));
testing.expect(testHash(a) != testHash(b));
testing.expectEqual(testHash(b), 0);
}
@@ -315,9 +315,9 @@ test "testHash array" {
const a = [_]u32{ 1, 2, 3 };
const h = testHash(a);
var hasher = Wyhash.init(0);
- autoHash(&hasher, u32(1));
- autoHash(&hasher, u32(2));
- autoHash(&hasher, u32(3));
+ autoHash(&hasher, @as(u32, 1));
+ autoHash(&hasher, @as(u32, 2));
+ autoHash(&hasher, @as(u32, 3));
testing.expectEqual(h, hasher.final());
}
@@ -330,9 +330,9 @@ test "testHash struct" {
const f = Foo{};
const h = testHash(f);
var hasher = Wyhash.init(0);
- autoHash(&hasher, u32(1));
- autoHash(&hasher, u32(2));
- autoHash(&hasher, u32(3));
+ autoHash(&hasher, @as(u32, 1));
+ autoHash(&hasher, @as(u32, 2));
+ autoHash(&hasher, @as(u32, 3));
testing.expectEqual(h, hasher.final());
}
diff --git a/lib/std/hash/cityhash.zig b/lib/std/hash/cityhash.zig
index 43e5b7a385..d31ee17105 100644
--- a/lib/std/hash/cityhash.zig
+++ b/lib/std/hash/cityhash.zig
@@ -214,7 +214,7 @@ pub const CityHash64 = struct {
}
fn hashLen0To16(str: []const u8) u64 {
- const len: u64 = u64(str.len);
+ const len: u64 = @as(u64, str.len);
if (len >= 8) {
const mul: u64 = k2 +% len *% 2;
const a: u64 = fetch64(str.ptr) +% k2;
@@ -240,7 +240,7 @@ pub const CityHash64 = struct {
}
fn hashLen17To32(str: []const u8) u64 {
- const len: u64 = u64(str.len);
+ const len: u64 = @as(u64, str.len);
const mul: u64 = k2 +% len *% 2;
const a: u64 = fetch64(str.ptr) *% k1;
const b: u64 = fetch64(str.ptr + 8);
@@ -251,7 +251,7 @@ pub const CityHash64 = struct {
}
fn hashLen33To64(str: []const u8) u64 {
- const len: u64 = u64(str.len);
+ const len: u64 = @as(u64, str.len);
const mul: u64 = k2 +% len *% 2;
const a: u64 = fetch64(str.ptr) *% k2;
const b: u64 = fetch64(str.ptr + 8);
@@ -305,7 +305,7 @@ pub const CityHash64 = struct {
return hashLen33To64(str);
}
- var len: u64 = u64(str.len);
+ var len: u64 = @as(u64, str.len);
var x: u64 = fetch64(str.ptr + str.len - 40);
var y: u64 = fetch64(str.ptr + str.len - 16) +% fetch64(str.ptr + str.len - 56);
diff --git a/lib/std/hash/crc.zig b/lib/std/hash/crc.zig
index cdcaf55610..6176ded81d 100644
--- a/lib/std/hash/crc.zig
+++ b/lib/std/hash/crc.zig
@@ -65,10 +65,10 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
const p = input[i .. i + 8];
// Unrolling this way gives ~50Mb/s increase
- self.crc ^= (u32(p[0]) << 0);
- self.crc ^= (u32(p[1]) << 8);
- self.crc ^= (u32(p[2]) << 16);
- self.crc ^= (u32(p[3]) << 24);
+ self.crc ^= (@as(u32, p[0]) << 0);
+ self.crc ^= (@as(u32, p[1]) << 8);
+ self.crc ^= (@as(u32, p[2]) << 16);
+ self.crc ^= (@as(u32, p[3]) << 24);
self.crc =
lookup_tables[0][p[7]] ^
diff --git a/lib/std/hash/murmur.zig b/lib/std/hash/murmur.zig
index a0c8f91338..f70190d311 100644
--- a/lib/std/hash/murmur.zig
+++ b/lib/std/hash/murmur.zig
@@ -98,7 +98,7 @@ pub const Murmur2_64 = struct {
pub fn hashWithSeed(str: []const u8, seed: u64) u64 {
const m: u64 = 0xc6a4a7935bd1e995;
- const len = u64(str.len);
+ const len = @as(u64, str.len);
var h1: u64 = seed ^ (len *% m);
for (@ptrCast([*]allowzero align(1) const u64, str.ptr)[0..@intCast(usize, len >> 3)]) |v| {
var k1: u64 = v;
diff --git a/lib/std/hash/siphash.zig b/lib/std/hash/siphash.zig
index 3d67ba685b..c3a9184fa4 100644
--- a/lib/std/hash/siphash.zig
+++ b/lib/std/hash/siphash.zig
@@ -102,7 +102,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
}
const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3;
- return (u128(b2) << 64) | b1;
+ return (@as(u128, b2) << 64) | b1;
}
fn round(self: *Self, b: []const u8) void {
@@ -121,19 +121,19 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
fn sipRound(d: *Self) void {
d.v0 +%= d.v1;
- d.v1 = math.rotl(u64, d.v1, u64(13));
+ d.v1 = math.rotl(u64, d.v1, @as(u64, 13));
d.v1 ^= d.v0;
- d.v0 = math.rotl(u64, d.v0, u64(32));
+ d.v0 = math.rotl(u64, d.v0, @as(u64, 32));
d.v2 +%= d.v3;
- d.v3 = math.rotl(u64, d.v3, u64(16));
+ d.v3 = math.rotl(u64, d.v3, @as(u64, 16));
d.v3 ^= d.v2;
d.v0 +%= d.v3;
- d.v3 = math.rotl(u64, d.v3, u64(21));
+ d.v3 = math.rotl(u64, d.v3, @as(u64, 21));
d.v3 ^= d.v0;
d.v2 +%= d.v1;
- d.v1 = math.rotl(u64, d.v1, u64(17));
+ d.v1 = math.rotl(u64, d.v1, @as(u64, 17));
d.v1 ^= d.v2;
- d.v2 = math.rotl(u64, d.v2, u64(32));
+ d.v2 = math.rotl(u64, d.v2, @as(u64, 32));
}
pub fn hash(key: []const u8, input: []const u8) T {
diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig
index 7c872de5ca..aae3b60831 100644
--- a/lib/std/hash_map.zig
+++ b/lib/std/hash_map.zig
@@ -402,7 +402,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
}
fn keyToIndex(hm: Self, key: K) usize {
- return hm.constrainIndex(usize(hash(key)));
+ return hm.constrainIndex(@as(usize, hash(key)));
}
fn constrainIndex(hm: Self, i: usize) usize {
diff --git a/lib/std/heap.zig b/lib/std/heap.zig
index ccdab8d332..c9e9e3533d 100644
--- a/lib/std/heap.zig
+++ b/lib/std/heap.zig
@@ -896,7 +896,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
const large_align = u29(mem.page_size << 2);
var align_mask: usize = undefined;
- _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask);
+ _ = @shlWithOverflow(usize, ~@as(usize, 0), USizeShift(@ctz(u29, large_align)), &align_mask);
var slice = try allocator.alignedAlloc(u8, large_align, 500);
testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
diff --git a/lib/std/http/headers.zig b/lib/std/http/headers.zig
index 7ee035ce80..a860186e47 100644
--- a/lib/std/http/headers.zig
+++ b/lib/std/http/headers.zig
@@ -399,7 +399,7 @@ test "Headers.iterator" {
}
count += 1;
}
- testing.expectEqual(i32(2), count);
+ testing.expectEqual(@as(i32, 2), count);
}
test "Headers.contains" {
@@ -420,10 +420,10 @@ test "Headers.delete" {
try h.append("cookie", "somevalue", null);
testing.expectEqual(false, h.delete("not-present"));
- testing.expectEqual(usize(3), h.count());
+ testing.expectEqual(@as(usize, 3), h.count());
testing.expectEqual(true, h.delete("foo"));
- testing.expectEqual(usize(2), h.count());
+ testing.expectEqual(@as(usize, 2), h.count());
{
const e = h.at(0);
testing.expectEqualSlices(u8, "baz", e.name);
@@ -448,7 +448,7 @@ test "Headers.orderedRemove" {
try h.append("cookie", "somevalue", null);
h.orderedRemove(0);
- testing.expectEqual(usize(2), h.count());
+ testing.expectEqual(@as(usize, 2), h.count());
{
const e = h.at(0);
testing.expectEqualSlices(u8, "baz", e.name);
@@ -471,7 +471,7 @@ test "Headers.swapRemove" {
try h.append("cookie", "somevalue", null);
h.swapRemove(0);
- testing.expectEqual(usize(2), h.count());
+ testing.expectEqual(@as(usize, 2), h.count());
{
const e = h.at(0);
testing.expectEqualSlices(u8, "cookie", e.name);
diff --git a/lib/std/io.zig b/lib/std/io.zig
index 95280b888f..4fcee6ec14 100644
--- a/lib/std/io.zig
+++ b/lib/std/io.zig
@@ -353,7 +353,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
const Buf = @IntType(false, buf_bit_count);
const BufShift = math.Log2Int(Buf);
- out_bits.* = usize(0);
+ out_bits.* = @as(usize, 0);
if (U == u0 or bits == 0) return 0;
var out_buffer = Buf(0);
@@ -434,7 +434,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
var self = @fieldParentPtr(Self, "stream", self_stream);
var out_bits: usize = undefined;
- var out_bits_total = usize(0);
+ var out_bits_total = @as(usize, 0);
//@NOTE: I'm not sure this is a good idea, maybe alignToByte should be forced
if (self.bit_count > 0) {
for (buffer) |*b, i| {
diff --git a/lib/std/io/out_stream.zig b/lib/std/io/out_stream.zig
index 42c40337a8..c0cd6e48a1 100644
--- a/lib/std/io/out_stream.zig
+++ b/lib/std/io/out_stream.zig
@@ -40,12 +40,12 @@ pub fn OutStream(comptime WriteError: type) type {
}
pub fn writeByte(self: *Self, byte: u8) Error!void {
- const slice = (*const [1]u8)(&byte)[0..];
+ const slice = @as(*const [1]u8, &byte)[0..];
return self.writeFn(self, slice);
}
pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void {
- const slice = (*const [1]u8)(&byte)[0..];
+ const slice = @as(*const [1]u8, &byte)[0..];
var i: usize = 0;
while (i < n) : (i += 1) {
try self.writeFn(self, slice);
diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig
index e93b74169b..1fa7fc594c 100644
--- a/lib/std/io/test.zig
+++ b/lib/std/io/test.zig
@@ -228,8 +228,8 @@ test "BitOutStream" {
try bit_stream_be.writeBits(u2(1), 1);
try bit_stream_be.writeBits(u5(2), 2);
- try bit_stream_be.writeBits(u128(3), 3);
- try bit_stream_be.writeBits(u8(4), 4);
+ try bit_stream_be.writeBits(@as(u128, 3), 3);
+ try bit_stream_be.writeBits(@as(u8, 4), 4);
try bit_stream_be.writeBits(u9(5), 5);
try bit_stream_be.writeBits(u1(1), 1);
@@ -242,33 +242,33 @@ test "BitOutStream" {
expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
mem_out_be.pos = 0;
- try bit_stream_be.writeBits(u32(0b110011010000101), 16);
+ try bit_stream_be.writeBits(@as(u32, 0b110011010000101), 16);
expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
- try bit_stream_be.writeBits(u0(0), 0);
+ try bit_stream_be.writeBits(@as(u0, 0), 0);
var mem_out_le = io.SliceOutStream.init(mem_le[0..]);
var bit_stream_le = io.BitOutStream(builtin.Endian.Little, OutError).init(&mem_out_le.stream);
- try bit_stream_le.writeBits(u2(1), 1);
- try bit_stream_le.writeBits(u5(2), 2);
- try bit_stream_le.writeBits(u128(3), 3);
- try bit_stream_le.writeBits(u8(4), 4);
- try bit_stream_le.writeBits(u9(5), 5);
- try bit_stream_le.writeBits(u1(1), 1);
+ try bit_stream_le.writeBits(@as(u2, 1), 1);
+ try bit_stream_le.writeBits(@as(u5, 2), 2);
+ try bit_stream_le.writeBits(@as(u128, 3), 3);
+ try bit_stream_le.writeBits(@as(u8, 4), 4);
+ try bit_stream_le.writeBits(@as(u9, 5), 5);
+ try bit_stream_le.writeBits(@as(u1, 1), 1);
expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
mem_out_le.pos = 0;
- try bit_stream_le.writeBits(u15(0b110011010000101), 15);
+ try bit_stream_le.writeBits(@as(u15, 0b110011010000101), 15);
try bit_stream_le.flushBits();
expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
mem_out_le.pos = 0;
- try bit_stream_le.writeBits(u32(0b1100110100001011), 16);
+ try bit_stream_le.writeBits(@as(u32, 0b1100110100001011), 16);
expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
- try bit_stream_le.writeBits(u0(0), 0);
+ try bit_stream_le.writeBits(@as(u0, 0), 0);
}
test "BitStreams with File Stream" {
@@ -282,12 +282,12 @@ test "BitStreams with File Stream" {
const OutError = File.WriteError;
var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream);
- try bit_stream.writeBits(u2(1), 1);
- try bit_stream.writeBits(u5(2), 2);
- try bit_stream.writeBits(u128(3), 3);
- try bit_stream.writeBits(u8(4), 4);
- try bit_stream.writeBits(u9(5), 5);
- try bit_stream.writeBits(u1(1), 1);
+ try bit_stream.writeBits(@as(u2, 1), 1);
+ try bit_stream.writeBits(@as(u5, 2), 2);
+ try bit_stream.writeBits(@as(u128, 3), 3);
+ try bit_stream.writeBits(@as(u8, 4), 4);
+ try bit_stream.writeBits(@as(u9, 5), 5);
+ try bit_stream.writeBits(@as(u1, 1), 1);
try bit_stream.flushBits();
}
{
@@ -603,7 +603,7 @@ test "c out stream" {
}
const out_stream = &io.COutStream.init(out_file).stream;
- try out_stream.print("hi: {}\n", i32(123));
+ try out_stream.print("hi: {}\n", @as(i32, 123));
}
test "File seek ops" {
diff --git a/lib/std/json.zig b/lib/std/json.zig
index 6cd032806e..ecf0bf822b 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -1343,7 +1343,7 @@ test "write json then parse it" {
try jw.emitBool(true);
try jw.objectField("int");
- try jw.emitNumber(i32(1234));
+ try jw.emitNumber(@as(i32, 1234));
try jw.objectField("array");
try jw.beginArray();
@@ -1352,7 +1352,7 @@ test "write json then parse it" {
try jw.emitNull();
try jw.arrayElem();
- try jw.emitNumber(f64(12.34));
+ try jw.emitNumber(@as(f64, 12.34));
try jw.endArray();
diff --git a/lib/std/math.zig b/lib/std/math.zig
index 9b56d0b8ce..7c672c7ae8 100644
--- a/lib/std/math.zig
+++ b/lib/std/math.zig
@@ -44,10 +44,10 @@ pub const sqrt2 = 1.414213562373095048801688724209698079;
pub const sqrt1_2 = 0.707106781186547524400844362104849039;
// From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128)
-pub const f128_true_min = @bitCast(f128, u128(0x00000000000000000000000000000001));
-pub const f128_min = @bitCast(f128, u128(0x00010000000000000000000000000000));
-pub const f128_max = @bitCast(f128, u128(0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
-pub const f128_epsilon = @bitCast(f128, u128(0x3F8F0000000000000000000000000000));
+pub const f128_true_min = @bitCast(f128, @as(u128, 0x00000000000000000000000000000001));
+pub const f128_min = @bitCast(f128, @as(u128, 0x00010000000000000000000000000000));
+pub const f128_max = @bitCast(f128, @as(u128, 0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
+pub const f128_epsilon = @bitCast(f128, @as(u128, 0x3F8F0000000000000000000000000000));
pub const f128_toint = 1.0 / f128_epsilon;
// float.h details
@@ -69,28 +69,28 @@ pub const f16_max = 65504;
pub const f16_epsilon = 0.0009765625; // 2**-10
pub const f16_toint = 1.0 / f16_epsilon;
-pub const nan_u16 = u16(0x7C01);
+pub const nan_u16 = @as(u16, 0x7C01);
pub const nan_f16 = @bitCast(f16, nan_u16);
-pub const inf_u16 = u16(0x7C00);
+pub const inf_u16 = @as(u16, 0x7C00);
pub const inf_f16 = @bitCast(f16, inf_u16);
-pub const nan_u32 = u32(0x7F800001);
+pub const nan_u32 = @as(u32, 0x7F800001);
pub const nan_f32 = @bitCast(f32, nan_u32);
-pub const inf_u32 = u32(0x7F800000);
+pub const inf_u32 = @as(u32, 0x7F800000);
pub const inf_f32 = @bitCast(f32, inf_u32);
-pub const nan_u64 = u64(0x7FF << 52) | 1;
+pub const nan_u64 = @as(u64, 0x7FF << 52) | 1;
pub const nan_f64 = @bitCast(f64, nan_u64);
-pub const inf_u64 = u64(0x7FF << 52);
+pub const inf_u64 = @as(u64, 0x7FF << 52);
pub const inf_f64 = @bitCast(f64, inf_u64);
-pub const nan_u128 = u128(0x7fff0000000000000000000000000001);
+pub const nan_u128 = @as(u128, 0x7fff0000000000000000000000000001);
pub const nan_f128 = @bitCast(f128, nan_u128);
-pub const inf_u128 = u128(0x7fff0000000000000000000000000000);
+pub const inf_u128 = @as(u128, 0x7fff0000000000000000000000000000);
pub const inf_f128 = @bitCast(f128, inf_u128);
pub const nan = @import("math/nan.zig").nan;
@@ -248,7 +248,7 @@ pub fn Min(comptime A: type, comptime B: type) type {
},
else => {},
}
- return @typeOf(A(0) + B(0));
+ return @typeOf(@as(A, 0) + @as(B, 0));
}
/// Returns the smaller number. When one of the parameter's type's full range fits in the other,
@@ -273,7 +273,7 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) {
}
test "math.min" {
- testing.expect(min(i32(-1), i32(2)) == -1);
+ testing.expect(min(@as(i32, -1), @as(i32, 2)) == -1);
{
var a: u16 = 999;
var b: u32 = 10;
@@ -309,7 +309,7 @@ pub fn max(x: var, y: var) @typeOf(x + y) {
}
test "math.max" {
- testing.expect(max(i32(-1), i32(2)) == 2);
+ testing.expect(max(@as(i32, -1), @as(i32, 2)) == 2);
}
pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {
@@ -352,10 +352,10 @@ pub fn shl(comptime T: type, a: T, shift_amt: var) T {
}
test "math.shl" {
- testing.expect(shl(u8, 0b11111111, usize(3)) == 0b11111000);
- testing.expect(shl(u8, 0b11111111, usize(8)) == 0);
- testing.expect(shl(u8, 0b11111111, usize(9)) == 0);
- testing.expect(shl(u8, 0b11111111, isize(-2)) == 0b00111111);
+ testing.expect(shl(u8, 0b11111111, @as(usize, 3)) == 0b11111000);
+ testing.expect(shl(u8, 0b11111111, @as(usize, 8)) == 0);
+ testing.expect(shl(u8, 0b11111111, @as(usize, 9)) == 0);
+ testing.expect(shl(u8, 0b11111111, @as(isize, -2)) == 0b00111111);
testing.expect(shl(u8, 0b11111111, 3) == 0b11111000);
testing.expect(shl(u8, 0b11111111, 8) == 0);
testing.expect(shl(u8, 0b11111111, 9) == 0);
@@ -380,10 +380,10 @@ pub fn shr(comptime T: type, a: T, shift_amt: var) T {
}
test "math.shr" {
- testing.expect(shr(u8, 0b11111111, usize(3)) == 0b00011111);
- testing.expect(shr(u8, 0b11111111, usize(8)) == 0);
- testing.expect(shr(u8, 0b11111111, usize(9)) == 0);
- testing.expect(shr(u8, 0b11111111, isize(-2)) == 0b11111100);
+ testing.expect(shr(u8, 0b11111111, @as(usize, 3)) == 0b00011111);
+ testing.expect(shr(u8, 0b11111111, @as(usize, 8)) == 0);
+ testing.expect(shr(u8, 0b11111111, @as(usize, 9)) == 0);
+ testing.expect(shr(u8, 0b11111111, @as(isize, -2)) == 0b11111100);
testing.expect(shr(u8, 0b11111111, 3) == 0b00011111);
testing.expect(shr(u8, 0b11111111, 8) == 0);
testing.expect(shr(u8, 0b11111111, 9) == 0);
@@ -402,11 +402,11 @@ pub fn rotr(comptime T: type, x: T, r: var) T {
}
test "math.rotr" {
- testing.expect(rotr(u8, 0b00000001, usize(0)) == 0b00000001);
- testing.expect(rotr(u8, 0b00000001, usize(9)) == 0b10000000);
- testing.expect(rotr(u8, 0b00000001, usize(8)) == 0b00000001);
- testing.expect(rotr(u8, 0b00000001, usize(4)) == 0b00010000);
- testing.expect(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);
+ testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
+ testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000);
+ testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001);
+ testing.expect(rotr(u8, 0b00000001, @as(usize, 4)) == 0b00010000);
+ testing.expect(rotr(u8, 0b00000001, @as(isize, -1)) == 0b00000010);
}
/// Rotates left. Only unsigned values can be rotated.
@@ -421,11 +421,11 @@ pub fn rotl(comptime T: type, x: T, r: var) T {
}
test "math.rotl" {
- testing.expect(rotl(u8, 0b00000001, usize(0)) == 0b00000001);
- testing.expect(rotl(u8, 0b00000001, usize(9)) == 0b00000010);
- testing.expect(rotl(u8, 0b00000001, usize(8)) == 0b00000001);
- testing.expect(rotl(u8, 0b00000001, usize(4)) == 0b00010000);
- testing.expect(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);
+ testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
+ testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010);
+ testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001);
+ testing.expect(rotl(u8, 0b00000001, @as(usize, 4)) == 0b00010000);
+ testing.expect(rotl(u8, 0b00000001, @as(isize, -1)) == 0b10000000);
}
pub fn Log2Int(comptime T: type) type {
@@ -532,8 +532,8 @@ test "math.absInt" {
comptime testAbsInt();
}
fn testAbsInt() void {
- testing.expect((absInt(i32(-10)) catch unreachable) == 10);
- testing.expect((absInt(i32(10)) catch unreachable) == 10);
+ testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);
+ testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);
}
pub const absFloat = fabs;
@@ -679,14 +679,14 @@ pub fn absCast(x: var) t: {
}
test "math.absCast" {
- testing.expect(absCast(i32(-999)) == 999);
- testing.expect(@typeOf(absCast(i32(-999))) == u32);
+ testing.expect(absCast(@as(i32, -999)) == 999);
+ testing.expect(@typeOf(absCast(@as(i32, -999))) == u32);
- testing.expect(absCast(i32(999)) == 999);
- testing.expect(@typeOf(absCast(i32(999))) == u32);
+ testing.expect(absCast(@as(i32, 999)) == 999);
+ testing.expect(@typeOf(absCast(@as(i32, 999))) == u32);
- testing.expect(absCast(i32(minInt(i32))) == -minInt(i32));
- testing.expect(@typeOf(absCast(i32(minInt(i32)))) == u32);
+ testing.expect(absCast(@as(i32, minInt(i32))) == -minInt(i32));
+ testing.expect(@typeOf(absCast(@as(i32, minInt(i32)))) == u32);
testing.expect(absCast(-999) == 999);
}
@@ -705,13 +705,13 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
}
test "math.negateCast" {
- testing.expect((negateCast(u32(999)) catch unreachable) == -999);
- testing.expect(@typeOf(negateCast(u32(999)) catch unreachable) == i32);
+ testing.expect((negateCast(@as(u32, 999)) catch unreachable) == -999);
+ testing.expect(@typeOf(negateCast(@as(u32, 999)) catch unreachable) == i32);
- testing.expect((negateCast(u32(-minInt(i32))) catch unreachable) == minInt(i32));
- testing.expect(@typeOf(negateCast(u32(-minInt(i32))) catch unreachable) == i32);
+ testing.expect((negateCast(@as(u32, -minInt(i32))) catch unreachable) == minInt(i32));
+ testing.expect(@typeOf(negateCast(@as(u32, -minInt(i32))) catch unreachable) == i32);
- testing.expectError(error.Overflow, negateCast(u32(maxInt(i32) + 10)));
+ testing.expectError(error.Overflow, negateCast(@as(u32, maxInt(i32) + 10)));
}
/// Cast an integer to a different integer type. If the value doesn't fit,
@@ -729,13 +729,13 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
}
test "math.cast" {
- testing.expectError(error.Overflow, cast(u8, u32(300)));
- testing.expectError(error.Overflow, cast(i8, i32(-200)));
+ testing.expectError(error.Overflow, cast(u8, @as(u32, 300)));
+ testing.expectError(error.Overflow, cast(i8, @as(i32, -200)));
testing.expectError(error.Overflow, cast(u8, i8(-1)));
testing.expectError(error.Overflow, cast(u64, i8(-1)));
- testing.expect((try cast(u8, u32(255))) == u8(255));
- testing.expect(@typeOf(try cast(u8, u32(255))) == u8);
+ testing.expect((try cast(u8, @as(u32, 255))) == @as(u8, 255));
+ testing.expect(@typeOf(try cast(u8, @as(u32, 255))) == u8);
}
pub const AlignCastError = error{UnalignedMemory};
@@ -812,15 +812,15 @@ test "math.ceilPowerOfTwoPromote" {
}
fn testCeilPowerOfTwoPromote() void {
- testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1));
- testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2));
- testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63));
- testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 64));
- testing.expectEqual(u33(128), ceilPowerOfTwoPromote(u32, 65));
- testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 7));
- testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 8));
- testing.expectEqual(u6(16), ceilPowerOfTwoPromote(u5, 9));
- testing.expectEqual(u5(16), ceilPowerOfTwoPromote(u4, 9));
+ testing.expectEqual(@as(u33, 1), ceilPowerOfTwoPromote(u32, 1));
+ testing.expectEqual(@as(u33, 2), ceilPowerOfTwoPromote(u32, 2));
+ testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 63));
+ testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 64));
+ testing.expectEqual(@as(u33, 128), ceilPowerOfTwoPromote(u32, 65));
+ testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 7));
+ testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 8));
+ testing.expectEqual(@as(u6, 16), ceilPowerOfTwoPromote(u5, 9));
+ testing.expectEqual(@as(u5, 16), ceilPowerOfTwoPromote(u4, 9));
}
test "math.ceilPowerOfTwo" {
@@ -829,14 +829,14 @@ test "math.ceilPowerOfTwo" {
}
fn testCeilPowerOfTwo() !void {
- testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1));
- testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2));
- testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63));
- testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 64));
- testing.expectEqual(u32(128), try ceilPowerOfTwo(u32, 65));
- testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 7));
- testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 8));
- testing.expectEqual(u5(16), try ceilPowerOfTwo(u5, 9));
+ testing.expectEqual(@as(u32, 1), try ceilPowerOfTwo(u32, 1));
+ testing.expectEqual(@as(u32, 2), try ceilPowerOfTwo(u32, 2));
+ testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 63));
+ testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 64));
+ testing.expectEqual(@as(u32, 128), try ceilPowerOfTwo(u32, 65));
+ testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 7));
+ testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 8));
+ testing.expectEqual(@as(u5, 16), try ceilPowerOfTwo(u5, 9));
testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9));
}
@@ -944,7 +944,7 @@ test "max value type" {
pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) {
const ResultInt = @IntType(T.is_signed, T.bit_count * 2);
- return ResultInt(a) * ResultInt(b);
+ return @as(ResultInt, a) * @as(ResultInt, b);
}
test "math.mulWide" {
diff --git a/lib/std/math/acos.zig b/lib/std/math/acos.zig
index de07da8fe0..94b6fc3f8f 100644
--- a/lib/std/math/acos.zig
+++ b/lib/std/math/acos.zig
@@ -149,8 +149,8 @@ fn acos64(x: f64) f64 {
}
test "math.acos" {
- expect(acos(f32(0.0)) == acos32(0.0));
- expect(acos(f64(0.0)) == acos64(0.0));
+ expect(acos(@as(f32, 0.0)) == acos32(0.0));
+ expect(acos(@as(f64, 0.0)) == acos64(0.0));
}
test "math.acos32" {
diff --git a/lib/std/math/acosh.zig b/lib/std/math/acosh.zig
index 503c0433fc..065e4d39de 100644
--- a/lib/std/math/acosh.zig
+++ b/lib/std/math/acosh.zig
@@ -61,8 +61,8 @@ fn acosh64(x: f64) f64 {
}
test "math.acosh" {
- expect(acosh(f32(1.5)) == acosh32(1.5));
- expect(acosh(f64(1.5)) == acosh64(1.5));
+ expect(acosh(@as(f32, 1.5)) == acosh32(1.5));
+ expect(acosh(@as(f64, 1.5)) == acosh64(1.5));
}
test "math.acosh32" {
diff --git a/lib/std/math/asin.zig b/lib/std/math/asin.zig
index 2db9f86ff1..d354f8ceed 100644
--- a/lib/std/math/asin.zig
+++ b/lib/std/math/asin.zig
@@ -142,8 +142,8 @@ fn asin64(x: f64) f64 {
}
test "math.asin" {
- expect(asin(f32(0.0)) == asin32(0.0));
- expect(asin(f64(0.0)) == asin64(0.0));
+ expect(asin(@as(f32, 0.0)) == asin32(0.0));
+ expect(asin(@as(f64, 0.0)) == asin64(0.0));
}
test "math.asin32" {
diff --git a/lib/std/math/asinh.zig b/lib/std/math/asinh.zig
index 0fb51d1b43..b915df3171 100644
--- a/lib/std/math/asinh.zig
+++ b/lib/std/math/asinh.zig
@@ -89,8 +89,8 @@ fn asinh64(x: f64) f64 {
}
test "math.asinh" {
- expect(asinh(f32(0.0)) == asinh32(0.0));
- expect(asinh(f64(0.0)) == asinh64(0.0));
+ expect(asinh(@as(f32, 0.0)) == asinh32(0.0));
+ expect(asinh(@as(f64, 0.0)) == asinh64(0.0));
}
test "math.asinh32" {
diff --git a/lib/std/math/atan.zig b/lib/std/math/atan.zig
index 5790eba8cf..ea639872be 100644
--- a/lib/std/math/atan.zig
+++ b/lib/std/math/atan.zig
@@ -212,8 +212,8 @@ fn atan64(x_: f64) f64 {
}
test "math.atan" {
- expect(@bitCast(u32, atan(f32(0.2))) == @bitCast(u32, atan32(0.2)));
- expect(atan(f64(0.2)) == atan64(0.2));
+ expect(@bitCast(u32, atan(@as(f32, 0.2))) == @bitCast(u32, atan32(0.2)));
+ expect(atan(@as(f64, 0.2)) == atan64(0.2));
}
test "math.atan32" {
diff --git a/lib/std/math/atanh.zig b/lib/std/math/atanh.zig
index 8ba29be761..ae588f4fb8 100644
--- a/lib/std/math/atanh.zig
+++ b/lib/std/math/atanh.zig
@@ -84,8 +84,8 @@ fn atanh_64(x: f64) f64 {
}
test "math.atanh" {
- expect(atanh(f32(0.0)) == atanh_32(0.0));
- expect(atanh(f64(0.0)) == atanh_64(0.0));
+ expect(atanh(@as(f32, 0.0)) == atanh_32(0.0));
+ expect(atanh(@as(f64, 0.0)) == atanh_64(0.0));
}
test "math.atanh_32" {
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index bfdc768375..fa2424de07 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -261,7 +261,7 @@ pub const Int = struct {
/// the minus sign. This is used for determining the number of characters needed to print the
/// value. It is inexact and may exceed the given value by ~1-2 bytes.
pub fn sizeInBase(self: Int, base: usize) usize {
- const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs();
+ const bit_count = @as(usize, @boolToInt(!self.isPositive())) + self.bitCountAbs();
return (bit_count / math.log2(base)) + 1;
}
diff --git a/lib/std/math/cbrt.zig b/lib/std/math/cbrt.zig
index 5241e31323..c9e205a495 100644
--- a/lib/std/math/cbrt.zig
+++ b/lib/std/math/cbrt.zig
@@ -54,11 +54,11 @@ fn cbrt32(x: f32) f32 {
// first step newton to 16 bits
var t: f64 = @bitCast(f32, u);
var r: f64 = t * t * t;
- t = t * (f64(x) + x + r) / (x + r + r);
+ t = t * (@as(f64, x) + x + r) / (x + r + r);
// second step newton to 47 bits
r = t * t * t;
- t = t * (f64(x) + x + r) / (x + r + r);
+ t = t * (@as(f64, x) + x + r) / (x + r + r);
return @floatCast(f32, t);
}
@@ -97,7 +97,7 @@ fn cbrt64(x: f64) f64 {
}
u &= 1 << 63;
- u |= u64(hx) << 32;
+ u |= @as(u64, hx) << 32;
var t = @bitCast(f64, u);
// cbrt to 23 bits
@@ -120,8 +120,8 @@ fn cbrt64(x: f64) f64 {
}
test "math.cbrt" {
- expect(cbrt(f32(0.0)) == cbrt32(0.0));
- expect(cbrt(f64(0.0)) == cbrt64(0.0));
+ expect(cbrt(@as(f32, 0.0)) == cbrt32(0.0));
+ expect(cbrt(@as(f64, 0.0)) == cbrt64(0.0));
}
test "math.cbrt32" {
diff --git a/lib/std/math/ceil.zig b/lib/std/math/ceil.zig
index 5f86093a6d..b5a2238621 100644
--- a/lib/std/math/ceil.zig
+++ b/lib/std/math/ceil.zig
@@ -37,7 +37,7 @@ fn ceil32(x: f32) f32 {
if (e >= 23) {
return x;
} else if (e >= 0) {
- m = u32(0x007FFFFF) >> @intCast(u5, e);
+ m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
if (u & m == 0) {
return x;
}
@@ -87,8 +87,8 @@ fn ceil64(x: f64) f64 {
}
test "math.ceil" {
- expect(ceil(f32(0.0)) == ceil32(0.0));
- expect(ceil(f64(0.0)) == ceil64(0.0));
+ expect(ceil(@as(f32, 0.0)) == ceil32(0.0));
+ expect(ceil(@as(f64, 0.0)) == ceil64(0.0));
}
test "math.ceil32" {
diff --git a/lib/std/math/complex/ldexp.zig b/lib/std/math/complex/ldexp.zig
index d6f810793f..d74ac86148 100644
--- a/lib/std/math/complex/ldexp.zig
+++ b/lib/std/math/complex/ldexp.zig
@@ -59,7 +59,7 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {
expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k;
const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);
- return @bitCast(f64, (u64(high_word) << 32) | lx);
+ return @bitCast(f64, (@as(u64, high_word) << 32) | lx);
}
fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {
diff --git a/lib/std/math/complex/sqrt.zig b/lib/std/math/complex/sqrt.zig
index 36f4c28e29..7e17f422bb 100644
--- a/lib/std/math/complex/sqrt.zig
+++ b/lib/std/math/complex/sqrt.zig
@@ -52,8 +52,8 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {
// y = nan special case is handled fine below
// double-precision avoids overflow with correct rounding.
- const dx = f64(x);
- const dy = f64(y);
+ const dx = @as(f64, x);
+ const dy = @as(f64, y);
if (dx >= 0) {
const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5);
diff --git a/lib/std/math/complex/tanh.zig b/lib/std/math/complex/tanh.zig
index 6895e8a769..fc7f4e9ea8 100644
--- a/lib/std/math/complex/tanh.zig
+++ b/lib/std/math/complex/tanh.zig
@@ -76,7 +76,7 @@ fn tanh64(z: Complex(f64)) Complex(f64) {
return Complex(f64).new(x, r);
}
- const xx = @bitCast(f64, (u64(hx - 0x40000000) << 32) | lx);
+ const xx = @bitCast(f64, (@as(u64, hx - 0x40000000) << 32) | lx);
const r = if (math.isInf(y)) y else math.sin(y) * math.cos(y);
return Complex(f64).new(xx, math.copysign(f64, 0, r));
}
diff --git a/lib/std/math/copysign.zig b/lib/std/math/copysign.zig
index e4d90c395e..e874da0bb9 100644
--- a/lib/std/math/copysign.zig
+++ b/lib/std/math/copysign.zig
@@ -24,7 +24,7 @@ fn copysign16(x: f16, y: f16) f16 {
const uy = @bitCast(u16, y);
const h1 = ux & (maxInt(u16) / 2);
- const h2 = uy & (u16(1) << 15);
+ const h2 = uy & (@as(u16, 1) << 15);
return @bitCast(f16, h1 | h2);
}
@@ -33,7 +33,7 @@ fn copysign32(x: f32, y: f32) f32 {
const uy = @bitCast(u32, y);
const h1 = ux & (maxInt(u32) / 2);
- const h2 = uy & (u32(1) << 31);
+ const h2 = uy & (@as(u32, 1) << 31);
return @bitCast(f32, h1 | h2);
}
@@ -42,7 +42,7 @@ fn copysign64(x: f64, y: f64) f64 {
const uy = @bitCast(u64, y);
const h1 = ux & (maxInt(u64) / 2);
- const h2 = uy & (u64(1) << 63);
+ const h2 = uy & (@as(u64, 1) << 63);
return @bitCast(f64, h1 | h2);
}
diff --git a/lib/std/math/cos.zig b/lib/std/math/cos.zig
index 5261a25f80..68e13e41bf 100644
--- a/lib/std/math/cos.zig
+++ b/lib/std/math/cos.zig
@@ -83,8 +83,8 @@ fn cos_(comptime T: type, x_: T) T {
}
test "math.cos" {
- expect(cos(f32(0.0)) == cos_(f32, 0.0));
- expect(cos(f64(0.0)) == cos_(f64, 0.0));
+ expect(cos(@as(f32, 0.0)) == cos_(f32, 0.0));
+ expect(cos(@as(f64, 0.0)) == cos_(f64, 0.0));
}
test "math.cos32" {
diff --git a/lib/std/math/cosh.zig b/lib/std/math/cosh.zig
index 75c5c15ec1..62bedeaa49 100644
--- a/lib/std/math/cosh.zig
+++ b/lib/std/math/cosh.zig
@@ -88,8 +88,8 @@ fn cosh64(x: f64) f64 {
}
test "math.cosh" {
- expect(cosh(f32(1.5)) == cosh32(1.5));
- expect(cosh(f64(1.5)) == cosh64(1.5));
+ expect(cosh(@as(f32, 1.5)) == cosh32(1.5));
+ expect(cosh(@as(f64, 1.5)) == cosh64(1.5));
}
test "math.cosh32" {
diff --git a/lib/std/math/exp.zig b/lib/std/math/exp.zig
index 718bbcd476..e1297b11bc 100644
--- a/lib/std/math/exp.zig
+++ b/lib/std/math/exp.zig
@@ -183,8 +183,8 @@ fn exp64(x_: f64) f64 {
}
test "math.exp" {
- assert(exp(f32(0.0)) == exp32(0.0));
- assert(exp(f64(0.0)) == exp64(0.0));
+ assert(exp(@as(f32, 0.0)) == exp32(0.0));
+ assert(exp(@as(f64, 0.0)) == exp64(0.0));
}
test "math.exp32" {
diff --git a/lib/std/math/exp2.zig b/lib/std/math/exp2.zig
index 57f6620d77..f3e51e542e 100644
--- a/lib/std/math/exp2.zig
+++ b/lib/std/math/exp2.zig
@@ -85,7 +85,7 @@ fn exp2_32(x: f32) f32 {
const k = i_0 / tblsiz;
// NOTE: musl relies on undefined overflow shift behaviour. Appears that this produces the
// intended result but should confirm how GCC/Clang handle this to ensure.
- const uk = @bitCast(f64, u64(0x3FF + k) << 52);
+ const uk = @bitCast(f64, @as(u64, 0x3FF + k) << 52);
i_0 &= tblsiz - 1;
uf -= redux;
@@ -421,8 +421,8 @@ fn exp2_64(x: f64) f64 {
}
test "math.exp2" {
- expect(exp2(f32(0.8923)) == exp2_32(0.8923));
- expect(exp2(f64(0.8923)) == exp2_64(0.8923));
+ expect(exp2(@as(f32, 0.8923)) == exp2_32(0.8923));
+ expect(exp2(@as(f64, 0.8923)) == exp2_64(0.8923));
}
test "math.exp2_32" {
diff --git a/lib/std/math/expm1.zig b/lib/std/math/expm1.zig
index 5e347f86f6..871fa38449 100644
--- a/lib/std/math/expm1.zig
+++ b/lib/std/math/expm1.zig
@@ -287,8 +287,8 @@ fn expm1_64(x_: f64) f64 {
}
test "math.exp1m" {
- expect(expm1(f32(0.0)) == expm1_32(0.0));
- expect(expm1(f64(0.0)) == expm1_64(0.0));
+ expect(expm1(@as(f32, 0.0)) == expm1_32(0.0));
+ expect(expm1(@as(f64, 0.0)) == expm1_64(0.0));
}
test "math.expm1_32" {
diff --git a/lib/std/math/expo2.zig b/lib/std/math/expo2.zig
index c00098a5a7..590f36bb18 100644
--- a/lib/std/math/expo2.zig
+++ b/lib/std/math/expo2.zig
@@ -30,6 +30,6 @@ fn expo2d(x: f64) f64 {
const kln2 = 0x1.62066151ADD8BP+10;
const u = (0x3FF + k / 2) << 20;
- const scale = @bitCast(f64, u64(u) << 32);
+ const scale = @bitCast(f64, @as(u64, u) << 32);
return math.exp(x - kln2) * scale * scale;
}
diff --git a/lib/std/math/fabs.zig b/lib/std/math/fabs.zig
index 6469f38835..e0eadd0d00 100644
--- a/lib/std/math/fabs.zig
+++ b/lib/std/math/fabs.zig
@@ -50,10 +50,10 @@ fn fabs128(x: f128) f128 {
}
test "math.fabs" {
- expect(fabs(f16(1.0)) == fabs16(1.0));
- expect(fabs(f32(1.0)) == fabs32(1.0));
- expect(fabs(f64(1.0)) == fabs64(1.0));
- expect(fabs(f128(1.0)) == fabs128(1.0));
+ expect(fabs(@as(f16, 1.0)) == fabs16(1.0));
+ expect(fabs(@as(f32, 1.0)) == fabs32(1.0));
+ expect(fabs(@as(f64, 1.0)) == fabs64(1.0));
+ expect(fabs(@as(f128, 1.0)) == fabs128(1.0));
}
test "math.fabs16" {
diff --git a/lib/std/math/floor.zig b/lib/std/math/floor.zig
index e5ff2b1fc1..f2cabe8f02 100644
--- a/lib/std/math/floor.zig
+++ b/lib/std/math/floor.zig
@@ -40,7 +40,7 @@ fn floor16(x: f16) f16 {
}
if (e >= 0) {
- m = u16(1023) >> @intCast(u4, e);
+ m = @as(u16, 1023) >> @intCast(u4, e);
if (u & m == 0) {
return x;
}
@@ -74,7 +74,7 @@ fn floor32(x: f32) f32 {
}
if (e >= 0) {
- m = u32(0x007FFFFF) >> @intCast(u5, e);
+ m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
if (u & m == 0) {
return x;
}
@@ -123,9 +123,9 @@ fn floor64(x: f64) f64 {
}
test "math.floor" {
- expect(floor(f16(1.3)) == floor16(1.3));
- expect(floor(f32(1.3)) == floor32(1.3));
- expect(floor(f64(1.3)) == floor64(1.3));
+ expect(floor(@as(f16, 1.3)) == floor16(1.3));
+ expect(floor(@as(f32, 1.3)) == floor32(1.3));
+ expect(floor(@as(f64, 1.3)) == floor64(1.3));
}
test "math.floor16" {
diff --git a/lib/std/math/fma.zig b/lib/std/math/fma.zig
index 19c306fa2a..014593cda5 100644
--- a/lib/std/math/fma.zig
+++ b/lib/std/math/fma.zig
@@ -18,7 +18,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) T {
}
fn fma32(x: f32, y: f32, z: f32) f32 {
- const xy = f64(x) * y;
+ const xy = @as(f64, x) * y;
const xy_z = xy + z;
const u = @bitCast(u64, xy_z);
const e = (u >> 52) & 0x7FF;
diff --git a/lib/std/math/frexp.zig b/lib/std/math/frexp.zig
index 2759cd6492..93705ae6a4 100644
--- a/lib/std/math/frexp.zig
+++ b/lib/std/math/frexp.zig
@@ -108,11 +108,11 @@ fn frexp64(x: f64) frexp64_result {
}
test "math.frexp" {
- const a = frexp(f32(1.3));
+ const a = frexp(@as(f32, 1.3));
const b = frexp32(1.3);
expect(a.significand == b.significand and a.exponent == b.exponent);
- const c = frexp(f64(1.3));
+ const c = frexp(@as(f64, 1.3));
const d = frexp64(1.3);
expect(c.significand == d.significand and c.exponent == d.exponent);
}
diff --git a/lib/std/math/hypot.zig b/lib/std/math/hypot.zig
index c15da1495e..59116014b3 100644
--- a/lib/std/math/hypot.zig
+++ b/lib/std/math/hypot.zig
@@ -56,7 +56,7 @@ fn hypot32(x: f32, y: f32) f32 {
yy *= 0x1.0p-90;
}
- return z * math.sqrt(@floatCast(f32, f64(x) * x + f64(y) * y));
+ return z * math.sqrt(@floatCast(f32, @as(f64, x) * x + @as(f64, y) * y));
}
fn sq(hi: *f64, lo: *f64, x: f64) void {
diff --git a/lib/std/math/ilogb.zig b/lib/std/math/ilogb.zig
index fe4158a6dd..8d23bb09a0 100644
--- a/lib/std/math/ilogb.zig
+++ b/lib/std/math/ilogb.zig
@@ -26,7 +26,7 @@ pub fn ilogb(x: var) i32 {
}
// NOTE: Should these be exposed publicly?
-const fp_ilogbnan = -1 - i32(maxInt(u32) >> 1);
+const fp_ilogbnan = -1 - @as(i32, maxInt(u32) >> 1);
const fp_ilogb0 = fp_ilogbnan;
fn ilogb32(x: f32) i32 {
@@ -101,8 +101,8 @@ fn ilogb64(x: f64) i32 {
}
test "math.ilogb" {
- expect(ilogb(f32(0.2)) == ilogb32(0.2));
- expect(ilogb(f64(0.2)) == ilogb64(0.2));
+ expect(ilogb(@as(f32, 0.2)) == ilogb32(0.2));
+ expect(ilogb(@as(f64, 0.2)) == ilogb64(0.2));
}
test "math.ilogb32" {
diff --git a/lib/std/math/isfinite.zig b/lib/std/math/isfinite.zig
index 99eba668f9..3d23a0f3bf 100644
--- a/lib/std/math/isfinite.zig
+++ b/lib/std/math/isfinite.zig
@@ -26,12 +26,12 @@ pub fn isFinite(x: var) bool {
}
test "math.isFinite" {
- expect(isFinite(f16(0.0)));
- expect(isFinite(f16(-0.0)));
- expect(isFinite(f32(0.0)));
- expect(isFinite(f32(-0.0)));
- expect(isFinite(f64(0.0)));
- expect(isFinite(f64(-0.0)));
+ expect(isFinite(@as(f16, 0.0)));
+ expect(isFinite(@as(f16, -0.0)));
+ expect(isFinite(@as(f32, 0.0)));
+ expect(isFinite(@as(f32, -0.0)));
+ expect(isFinite(@as(f64, 0.0)));
+ expect(isFinite(@as(f64, -0.0)));
expect(!isFinite(math.inf(f16)));
expect(!isFinite(-math.inf(f16)));
expect(!isFinite(math.inf(f32)));
diff --git a/lib/std/math/isinf.zig b/lib/std/math/isinf.zig
index 37934f4cf4..d691068be5 100644
--- a/lib/std/math/isinf.zig
+++ b/lib/std/math/isinf.zig
@@ -74,14 +74,14 @@ pub fn isNegativeInf(x: var) bool {
}
test "math.isInf" {
- expect(!isInf(f16(0.0)));
- expect(!isInf(f16(-0.0)));
- expect(!isInf(f32(0.0)));
- expect(!isInf(f32(-0.0)));
- expect(!isInf(f64(0.0)));
- expect(!isInf(f64(-0.0)));
- expect(!isInf(f128(0.0)));
- expect(!isInf(f128(-0.0)));
+ expect(!isInf(@as(f16, 0.0)));
+ expect(!isInf(@as(f16, -0.0)));
+ expect(!isInf(@as(f32, 0.0)));
+ expect(!isInf(@as(f32, -0.0)));
+ expect(!isInf(@as(f64, 0.0)));
+ expect(!isInf(@as(f64, -0.0)));
+ expect(!isInf(@as(f128, 0.0)));
+ expect(!isInf(@as(f128, -0.0)));
expect(isInf(math.inf(f16)));
expect(isInf(-math.inf(f16)));
expect(isInf(math.inf(f32)));
@@ -93,14 +93,14 @@ test "math.isInf" {
}
test "math.isPositiveInf" {
- expect(!isPositiveInf(f16(0.0)));
- expect(!isPositiveInf(f16(-0.0)));
- expect(!isPositiveInf(f32(0.0)));
- expect(!isPositiveInf(f32(-0.0)));
- expect(!isPositiveInf(f64(0.0)));
- expect(!isPositiveInf(f64(-0.0)));
- expect(!isPositiveInf(f128(0.0)));
- expect(!isPositiveInf(f128(-0.0)));
+ expect(!isPositiveInf(@as(f16, 0.0)));
+ expect(!isPositiveInf(@as(f16, -0.0)));
+ expect(!isPositiveInf(@as(f32, 0.0)));
+ expect(!isPositiveInf(@as(f32, -0.0)));
+ expect(!isPositiveInf(@as(f64, 0.0)));
+ expect(!isPositiveInf(@as(f64, -0.0)));
+ expect(!isPositiveInf(@as(f128, 0.0)));
+ expect(!isPositiveInf(@as(f128, -0.0)));
expect(isPositiveInf(math.inf(f16)));
expect(!isPositiveInf(-math.inf(f16)));
expect(isPositiveInf(math.inf(f32)));
@@ -112,14 +112,14 @@ test "math.isPositiveInf" {
}
test "math.isNegativeInf" {
- expect(!isNegativeInf(f16(0.0)));
- expect(!isNegativeInf(f16(-0.0)));
- expect(!isNegativeInf(f32(0.0)));
- expect(!isNegativeInf(f32(-0.0)));
- expect(!isNegativeInf(f64(0.0)));
- expect(!isNegativeInf(f64(-0.0)));
- expect(!isNegativeInf(f128(0.0)));
- expect(!isNegativeInf(f128(-0.0)));
+ expect(!isNegativeInf(@as(f16, 0.0)));
+ expect(!isNegativeInf(@as(f16, -0.0)));
+ expect(!isNegativeInf(@as(f32, 0.0)));
+ expect(!isNegativeInf(@as(f32, -0.0)));
+ expect(!isNegativeInf(@as(f64, 0.0)));
+ expect(!isNegativeInf(@as(f64, -0.0)));
+ expect(!isNegativeInf(@as(f128, 0.0)));
+ expect(!isNegativeInf(@as(f128, -0.0)));
expect(!isNegativeInf(math.inf(f16)));
expect(isNegativeInf(-math.inf(f16)));
expect(!isNegativeInf(math.inf(f32)));
diff --git a/lib/std/math/isnan.zig b/lib/std/math/isnan.zig
index cf8cd2e1c2..ac865f0d0c 100644
--- a/lib/std/math/isnan.zig
+++ b/lib/std/math/isnan.zig
@@ -20,8 +20,8 @@ test "math.isNan" {
expect(isNan(math.nan(f32)));
expect(isNan(math.nan(f64)));
expect(isNan(math.nan(f128)));
- expect(!isNan(f16(1.0)));
- expect(!isNan(f32(1.0)));
- expect(!isNan(f64(1.0)));
- expect(!isNan(f128(1.0)));
+ expect(!isNan(@as(f16, 1.0)));
+ expect(!isNan(@as(f32, 1.0)));
+ expect(!isNan(@as(f64, 1.0)));
+ expect(!isNan(@as(f128, 1.0)));
}
diff --git a/lib/std/math/isnormal.zig b/lib/std/math/isnormal.zig
index f8611ef805..01d919d417 100644
--- a/lib/std/math/isnormal.zig
+++ b/lib/std/math/isnormal.zig
@@ -29,10 +29,10 @@ test "math.isNormal" {
expect(!isNormal(math.nan(f16)));
expect(!isNormal(math.nan(f32)));
expect(!isNormal(math.nan(f64)));
- expect(!isNormal(f16(0)));
- expect(!isNormal(f32(0)));
- expect(!isNormal(f64(0)));
- expect(isNormal(f16(1.0)));
- expect(isNormal(f32(1.0)));
- expect(isNormal(f64(1.0)));
+ expect(!isNormal(@as(f16, 0)));
+ expect(!isNormal(@as(f32, 0)));
+ expect(!isNormal(@as(f64, 0)));
+ expect(isNormal(@as(f16, 1.0)));
+ expect(isNormal(@as(f32, 1.0)));
+ expect(isNormal(@as(f64, 1.0)));
}
diff --git a/lib/std/math/ln.zig b/lib/std/math/ln.zig
index c5d4c9ff25..362e44a869 100644
--- a/lib/std/math/ln.zig
+++ b/lib/std/math/ln.zig
@@ -31,10 +31,10 @@ pub fn ln(x: var) @typeOf(x) {
};
},
TypeId.ComptimeInt => {
- return @typeOf(1)(math.floor(ln_64(f64(x))));
+ return @typeOf(1)(math.floor(ln_64(@as(f64, x))));
},
TypeId.Int => {
- return T(math.floor(ln_64(f64(x))));
+ return T(math.floor(ln_64(@as(f64, x))));
},
else => @compileError("ln not implemented for " ++ @typeName(T)),
}
@@ -132,7 +132,7 @@ pub fn ln_64(x_: f64) f64 {
hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
- ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
+ ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix);
const f = x - 1.0;
@@ -149,8 +149,8 @@ pub fn ln_64(x_: f64) f64 {
}
test "math.ln" {
- expect(ln(f32(0.2)) == ln_32(0.2));
- expect(ln(f64(0.2)) == ln_64(0.2));
+ expect(ln(@as(f32, 0.2)) == ln_32(0.2));
+ expect(ln(@as(f64, 0.2)) == ln_64(0.2));
}
test "math.ln32" {
diff --git a/lib/std/math/log.zig b/lib/std/math/log.zig
index 77f3639fd2..84dbcf939d 100644
--- a/lib/std/math/log.zig
+++ b/lib/std/math/log.zig
@@ -23,10 +23,10 @@ pub fn log(comptime T: type, base: T, x: T) T {
const float_base = math.lossyCast(f64, base);
switch (@typeId(T)) {
TypeId.ComptimeFloat => {
- return @typeOf(1.0)(math.ln(f64(x)) / math.ln(float_base));
+ return @typeOf(1.0)(math.ln(@as(f64, x)) / math.ln(float_base));
},
TypeId.ComptimeInt => {
- return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(float_base)));
+ return @typeOf(1)(math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));
},
builtin.TypeId.Int => {
// TODO implement integer log without using float math
@@ -35,7 +35,7 @@ pub fn log(comptime T: type, base: T, x: T) T {
builtin.TypeId.Float => {
switch (T) {
- f32 => return @floatCast(f32, math.ln(f64(x)) / math.ln(float_base)),
+ f32 => return @floatCast(f32, math.ln(@as(f64, x)) / math.ln(float_base)),
f64 => return math.ln(x) / math.ln(float_base),
else => @compileError("log not implemented for " ++ @typeName(T)),
}
@@ -67,6 +67,6 @@ test "math.log float_special" {
expect(log(f32, 2, 0.2301974) == math.log2(f32(0.2301974)));
expect(log(f32, 10, 0.2301974) == math.log10(f32(0.2301974)));
- expect(log(f64, 2, 213.23019799993) == math.log2(f64(213.23019799993)));
- expect(log(f64, 10, 213.23019799993) == math.log10(f64(213.23019799993)));
+ expect(log(f64, 2, 213.23019799993) == math.log2(@as(f64, 213.23019799993)));
+ expect(log(f64, 10, 213.23019799993) == math.log10(@as(f64, 213.23019799993)));
}
diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig
index 9b0bc3ac52..a4b3fef26b 100644
--- a/lib/std/math/log10.zig
+++ b/lib/std/math/log10.zig
@@ -32,7 +32,7 @@ pub fn log10(x: var) @typeOf(x) {
};
},
TypeId.ComptimeInt => {
- return @typeOf(1)(math.floor(log10_64(f64(x))));
+ return @typeOf(1)(math.floor(log10_64(@as(f64, x))));
},
TypeId.Int => {
return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));
@@ -143,7 +143,7 @@ pub fn log10_64(x_: f64) f64 {
hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
- ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
+ ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix);
const f = x - 1.0;
@@ -158,7 +158,7 @@ pub fn log10_64(x_: f64) f64 {
// hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
var hi = f - hfsq;
var hii = @bitCast(u64, hi);
- hii &= u64(maxInt(u64)) << 32;
+ hii &= @as(u64, maxInt(u64)) << 32;
hi = @bitCast(f64, hii);
const lo = f - hi - hfsq + s * (hfsq + R);
@@ -178,7 +178,7 @@ pub fn log10_64(x_: f64) f64 {
test "math.log10" {
testing.expect(log10(f32(0.2)) == log10_32(0.2));
- testing.expect(log10(f64(0.2)) == log10_64(0.2));
+ testing.expect(log10(@as(f64, 0.2)) == log10_64(0.2));
}
test "math.log10_32" {
diff --git a/lib/std/math/log1p.zig b/lib/std/math/log1p.zig
index bae6deb536..047e089a91 100644
--- a/lib/std/math/log1p.zig
+++ b/lib/std/math/log1p.zig
@@ -166,7 +166,7 @@ fn log1p_64(x: f64) f64 {
// u into [sqrt(2)/2, sqrt(2)]
iu = (iu & 0x000FFFFF) + 0x3FE6A09E;
- const iq = (u64(iu) << 32) | (hu & 0xFFFFFFFF);
+ const iq = (@as(u64, iu) << 32) | (hu & 0xFFFFFFFF);
f = @bitCast(f64, iq) - 1;
}
@@ -183,8 +183,8 @@ fn log1p_64(x: f64) f64 {
}
test "math.log1p" {
- expect(log1p(f32(0.0)) == log1p_32(0.0));
- expect(log1p(f64(0.0)) == log1p_64(0.0));
+ expect(log1p(@as(f32, 0.0)) == log1p_32(0.0));
+ expect(log1p(@as(f64, 0.0)) == log1p_64(0.0));
}
test "math.log1p_32" {
diff --git a/lib/std/math/log2.zig b/lib/std/math/log2.zig
index 88450a7ffd..47b214d6cf 100644
--- a/lib/std/math/log2.zig
+++ b/lib/std/math/log2.zig
@@ -143,7 +143,7 @@ pub fn log2_64(x_: f64) f64 {
hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
- ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
+ ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix);
const f = x - 1.0;
@@ -158,7 +158,7 @@ pub fn log2_64(x_: f64) f64 {
// hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
var hi = f - hfsq;
var hii = @bitCast(u64, hi);
- hii &= u64(maxInt(u64)) << 32;
+ hii &= @as(u64, maxInt(u64)) << 32;
hi = @bitCast(f64, hii);
const lo = f - hi - hfsq + s * (hfsq + R);
@@ -175,8 +175,8 @@ pub fn log2_64(x_: f64) f64 {
}
test "math.log2" {
- expect(log2(f32(0.2)) == log2_32(0.2));
- expect(log2(f64(0.2)) == log2_64(0.2));
+ expect(log2(@as(f32, 0.2)) == log2_32(0.2));
+ expect(log2(@as(f64, 0.2)) == log2_64(0.2));
}
test "math.log2_32" {
diff --git a/lib/std/math/modf.zig b/lib/std/math/modf.zig
index 92194d4c75..6567cbc9ed 100644
--- a/lib/std/math/modf.zig
+++ b/lib/std/math/modf.zig
@@ -65,7 +65,7 @@ fn modf32(x: f32) modf32_result {
return result;
}
- const mask = u32(0x007FFFFF) >> @intCast(u5, e);
+ const mask = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
if (u & mask == 0) {
result.ipart = x;
result.fpart = @bitCast(f32, us);
@@ -109,7 +109,7 @@ fn modf64(x: f64) modf64_result {
return result;
}
- const mask = u64(maxInt(u64) >> 12) >> @intCast(u6, e);
+ const mask = @as(u64, maxInt(u64) >> 12) >> @intCast(u6, e);
if (u & mask == 0) {
result.ipart = x;
result.fpart = @bitCast(f64, us);
@@ -123,12 +123,12 @@ fn modf64(x: f64) modf64_result {
}
test "math.modf" {
- const a = modf(f32(1.0));
+ const a = modf(@as(f32, 1.0));
const b = modf32(1.0);
// NOTE: No struct comparison on generic return type function? non-named, makes sense, but still.
expect(a.ipart == b.ipart and a.fpart == b.fpart);
- const c = modf(f64(1.0));
+ const c = modf(@as(f64, 1.0));
const d = modf64(1.0);
expect(a.ipart == b.ipart and a.fpart == b.fpart);
}
diff --git a/lib/std/math/round.zig b/lib/std/math/round.zig
index 0b80a46ce5..adedbf2e94 100644
--- a/lib/std/math/round.zig
+++ b/lib/std/math/round.zig
@@ -91,8 +91,8 @@ fn round64(x_: f64) f64 {
}
test "math.round" {
- expect(round(f32(1.3)) == round32(1.3));
- expect(round(f64(1.3)) == round64(1.3));
+ expect(round(@as(f32, 1.3)) == round32(1.3));
+ expect(round(@as(f64, 1.3)) == round64(1.3));
}
test "math.round32" {
diff --git a/lib/std/math/scalbn.zig b/lib/std/math/scalbn.zig
index d5716d621c..e3c457ade5 100644
--- a/lib/std/math/scalbn.zig
+++ b/lib/std/math/scalbn.zig
@@ -79,8 +79,8 @@ fn scalbn64(x: f64, n_: i32) f64 {
}
test "math.scalbn" {
- expect(scalbn(f32(1.5), 4) == scalbn32(1.5, 4));
- expect(scalbn(f64(1.5), 4) == scalbn64(1.5, 4));
+ expect(scalbn(@as(f32, 1.5), 4) == scalbn32(1.5, 4));
+ expect(scalbn(@as(f64, 1.5), 4) == scalbn64(1.5, 4));
}
test "math.scalbn32" {
diff --git a/lib/std/math/signbit.zig b/lib/std/math/signbit.zig
index e5c5909292..f20753f2ff 100644
--- a/lib/std/math/signbit.zig
+++ b/lib/std/math/signbit.zig
@@ -29,9 +29,9 @@ fn signbit64(x: f64) bool {
}
test "math.signbit" {
- expect(signbit(f16(4.0)) == signbit16(4.0));
- expect(signbit(f32(4.0)) == signbit32(4.0));
- expect(signbit(f64(4.0)) == signbit64(4.0));
+ expect(signbit(@as(f16, 4.0)) == signbit16(4.0));
+ expect(signbit(@as(f32, 4.0)) == signbit32(4.0));
+ expect(signbit(@as(f64, 4.0)) == signbit64(4.0));
}
test "math.signbit16" {
diff --git a/lib/std/math/sin.zig b/lib/std/math/sin.zig
index ee07b4f85e..3baa730123 100644
--- a/lib/std/math/sin.zig
+++ b/lib/std/math/sin.zig
@@ -88,9 +88,9 @@ test "math.sin" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- expect(sin(f32(0.0)) == sin_(f32, 0.0));
- expect(sin(f64(0.0)) == sin_(f64, 0.0));
- expect(comptime (math.sin(f64(2))) == math.sin(f64(2)));
+ expect(sin(@as(f32, 0.0)) == sin_(f32, 0.0));
+ expect(sin(@as(f64, 0.0)) == sin_(f64, 0.0));
+ expect(comptime (math.sin(@as(f64, 2))) == math.sin(@as(f64, 2)));
}
test "math.sin32" {
diff --git a/lib/std/math/sinh.zig b/lib/std/math/sinh.zig
index 73ee65ea6f..c9718e3ce2 100644
--- a/lib/std/math/sinh.zig
+++ b/lib/std/math/sinh.zig
@@ -93,8 +93,8 @@ fn sinh64(x: f64) f64 {
}
test "math.sinh" {
- expect(sinh(f32(1.5)) == sinh32(1.5));
- expect(sinh(f64(1.5)) == sinh64(1.5));
+ expect(sinh(@as(f32, 1.5)) == sinh32(1.5));
+ expect(sinh(@as(f64, 1.5)) == sinh64(1.5));
}
test "math.sinh32" {
diff --git a/lib/std/math/sqrt.zig b/lib/std/math/sqrt.zig
index 30af5915d4..1b74c34eda 100644
--- a/lib/std/math/sqrt.zig
+++ b/lib/std/math/sqrt.zig
@@ -32,9 +32,9 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ
}
test "math.sqrt" {
- expect(sqrt(f16(0.0)) == @sqrt(f16, 0.0));
- expect(sqrt(f32(0.0)) == @sqrt(f32, 0.0));
- expect(sqrt(f64(0.0)) == @sqrt(f64, 0.0));
+ expect(sqrt(@as(f16, 0.0)) == @sqrt(f16, 0.0));
+ expect(sqrt(@as(f32, 0.0)) == @sqrt(f32, 0.0));
+ expect(sqrt(@as(f64, 0.0)) == @sqrt(f64, 0.0));
}
test "math.sqrt16" {
diff --git a/lib/std/math/tan.zig b/lib/std/math/tan.zig
index 049c85df12..1a027cf403 100644
--- a/lib/std/math/tan.zig
+++ b/lib/std/math/tan.zig
@@ -75,8 +75,8 @@ fn tan_(comptime T: type, x_: T) T {
}
test "math.tan" {
- expect(tan(f32(0.0)) == tan_(f32, 0.0));
- expect(tan(f64(0.0)) == tan_(f64, 0.0));
+ expect(tan(@as(f32, 0.0)) == tan_(f32, 0.0));
+ expect(tan(@as(f64, 0.0)) == tan_(f64, 0.0));
}
test "math.tan32" {
diff --git a/lib/std/math/tanh.zig b/lib/std/math/tanh.zig
index 48d26d091e..ced5f58bcc 100644
--- a/lib/std/math/tanh.zig
+++ b/lib/std/math/tanh.zig
@@ -119,8 +119,8 @@ fn tanh64(x: f64) f64 {
}
test "math.tanh" {
- expect(tanh(f32(1.5)) == tanh32(1.5));
- expect(tanh(f64(1.5)) == tanh64(1.5));
+ expect(tanh(@as(f32, 1.5)) == tanh32(1.5));
+ expect(tanh(@as(f64, 1.5)) == tanh64(1.5));
}
test "math.tanh32" {
diff --git a/lib/std/math/trunc.zig b/lib/std/math/trunc.zig
index 219bcd4914..56a842345c 100644
--- a/lib/std/math/trunc.zig
+++ b/lib/std/math/trunc.zig
@@ -36,7 +36,7 @@ fn trunc32(x: f32) f32 {
e = 1;
}
- m = u32(maxInt(u32)) >> @intCast(u5, e);
+ m = @as(u32, maxInt(u32)) >> @intCast(u5, e);
if (u & m == 0) {
return x;
} else {
@@ -57,7 +57,7 @@ fn trunc64(x: f64) f64 {
e = 1;
}
- m = u64(maxInt(u64)) >> @intCast(u6, e);
+ m = @as(u64, maxInt(u64)) >> @intCast(u6, e);
if (u & m == 0) {
return x;
} else {
@@ -67,8 +67,8 @@ fn trunc64(x: f64) f64 {
}
test "math.trunc" {
- expect(trunc(f32(1.3)) == trunc32(1.3));
- expect(trunc(f64(1.3)) == trunc64(1.3));
+ expect(trunc(@as(f32, 1.3)) == trunc32(1.3));
+ expect(trunc(@as(f64, 1.3)) == trunc64(1.3));
}
test "math.trunc32" {
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index 8924828378..19e9634d5a 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -118,7 +118,7 @@ pub const Allocator = struct {
} else @alignOf(T);
if (n == 0) {
- return ([*]align(a) T)(undefined)[0..0];
+ return @as([*]align(a) T, undefined)[0..0];
}
const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
@@ -170,7 +170,7 @@ pub const Allocator = struct {
}
if (new_n == 0) {
self.free(old_mem);
- return ([*]align(new_alignment) T)(undefined)[0..0];
+ return @as([*]align(new_alignment) T, undefined)[0..0];
}
const old_byte_slice = @sliceToBytes(old_mem);
@@ -523,7 +523,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin.
builtin.Endian.Little => {
const ShiftType = math.Log2Int(ReturnType);
for (bytes) |b, index| {
- result = result | (ReturnType(b) << @intCast(ShiftType, index * 8));
+ result = result | (@as(ReturnType, b) << @intCast(ShiftType, index * 8));
}
},
}
@@ -1332,7 +1332,7 @@ fn AsBytesReturnType(comptime P: type) type {
if (comptime !trait.isSingleItemPtr(P))
@compileError("expected single item " ++ "pointer, passed " ++ @typeName(P));
- const size = usize(@sizeOf(meta.Child(P)));
+ const size = @as(usize, @sizeOf(meta.Child(P)));
const alignment = comptime meta.alignment(P);
if (alignment == 0) {
@@ -1353,7 +1353,7 @@ pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) {
}
test "asBytes" {
- const deadbeef = u32(0xDEADBEEF);
+ const deadbeef = @as(u32, 0xDEADBEEF);
const deadbeef_bytes = switch (builtin.endian) {
builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
@@ -1361,7 +1361,7 @@ test "asBytes" {
testing.expect(eql(u8, asBytes(&deadbeef), deadbeef_bytes));
- var codeface = u32(0xC0DEFACE);
+ var codeface = @as(u32, 0xC0DEFACE);
for (asBytes(&codeface).*) |*b|
b.* = 0;
testing.expect(codeface == 0);
@@ -1392,7 +1392,7 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {
}
test "toBytes" {
- var my_bytes = toBytes(u32(0x12345678));
+ var my_bytes = toBytes(@as(u32, 0x12345678));
switch (builtin.endian) {
builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")),
builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")),
@@ -1406,7 +1406,7 @@ test "toBytes" {
}
fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
- const size = usize(@sizeOf(T));
+ const size = @as(usize, @sizeOf(T));
if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) {
@compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));
@@ -1424,7 +1424,7 @@ pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typ
}
test "bytesAsValue" {
- const deadbeef = u32(0xDEADBEEF);
+ const deadbeef = @as(u32, 0xDEADBEEF);
const deadbeef_bytes = switch (builtin.endian) {
builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
@@ -1472,7 +1472,7 @@ test "bytesToValue" {
};
const deadbeef = bytesToValue(u32, deadbeef_bytes);
- testing.expect(deadbeef == u32(0xDEADBEEF));
+ testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
}
fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index b29eb60201..ded5aa4b1a 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -505,7 +505,7 @@ test "std.meta.eql" {
const EU = struct {
fn tst(err: bool) !u8 {
if (err) return error.Error;
- return u8(5);
+ return @as(u8, 5);
}
};
diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig
index 43be7f3dfb..8857b4aa9e 100644
--- a/lib/std/meta/trait.zig
+++ b/lib/std/meta/trait.zig
@@ -327,8 +327,8 @@ pub fn isConstPtr(comptime T: type) bool {
}
test "std.meta.trait.isConstPtr" {
- var t = u8(0);
- const c = u8(0);
+ var t = @as(u8, 0);
+ const c = @as(u8, 0);
testing.expect(isConstPtr(*const @typeOf(t)));
testing.expect(isConstPtr(@typeOf(&c)));
testing.expect(!isConstPtr(*@typeOf(t)));
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 95036707b6..fcb64d029a 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -611,7 +611,7 @@ fn linuxLookupName(
// TODO sa6.addr[12..16] should return *[4]u8, making this cast unnecessary.
mem.writeIntNative(u32, @ptrCast(*[4]u8, &sa6.addr[12]), sa4.addr);
}
- if (dscope == i32(scopeOf(sa6.addr))) key |= DAS_MATCHINGSCOPE;
+ if (dscope == @as(i32, scopeOf(sa6.addr))) key |= DAS_MATCHINGSCOPE;
if (dlabel == labelOf(sa6.addr)) key |= DAS_MATCHINGLABEL;
prefixlen = prefixMatch(sa6.addr, da6.addr);
} else |_| {}
@@ -710,7 +710,7 @@ fn prefixMatch(s: [16]u8, d: [16]u8) u8 {
// address. However the definition of the source prefix length is
// not clear and thus this limiting is not yet implemented.
var i: u8 = 0;
- while (i < 128 and ((s[i / 8] ^ d[i / 8]) & (u8(128) >> @intCast(u3, i % 8))) == 0) : (i += 1) {}
+ while (i < 128 and ((s[i / 8] ^ d[i / 8]) & (@as(u8, 128) >> @intCast(u3, i % 8))) == 0) : (i += 1) {}
return i;
}
@@ -1194,23 +1194,23 @@ fn dnsParse(
if (r.len < 12) return error.InvalidDnsPacket;
if ((r[3] & 15) != 0) return;
var p = r.ptr + 12;
- var qdcount = r[4] * usize(256) + r[5];
- var ancount = r[6] * usize(256) + r[7];
+ var qdcount = r[4] * @as(usize, 256) + r[5];
+ var ancount = r[6] * @as(usize, 256) + r[7];
if (qdcount + ancount > 64) return error.InvalidDnsPacket;
while (qdcount != 0) {
qdcount -= 1;
while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;
if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)
return error.InvalidDnsPacket;
- p += usize(5) + @boolToInt(p[0] != 0);
+ p += @as(usize, 5) + @boolToInt(p[0] != 0);
}
while (ancount != 0) {
ancount -= 1;
while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;
if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)
return error.InvalidDnsPacket;
- p += usize(1) + @boolToInt(p[0] != 0);
- const len = p[8] * usize(256) + p[9];
+ p += @as(usize, 1) + @boolToInt(p[0] != 0);
+ const len = p[8] * @as(usize, 256) + p[9];
if (@ptrToInt(p) + len > @ptrToInt(r.ptr) + r.len) return error.InvalidDnsPacket;
try callback(ctx, p[1], p[10 .. 10 + len], r);
p += 10 + len;
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 6803006bf1..c0f02c9a0b 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -472,7 +472,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
var index: usize = 0;
while (index < bytes.len) {
- const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len));
+ const amt_to_write = math.min(bytes.len - index, @as(usize, max_bytes_len));
const rc = system.write(fd, bytes.ptr + index, amt_to_write);
switch (errno(rc)) {
0 => {
@@ -1526,7 +1526,7 @@ pub fn isatty(handle: fd_t) bool {
}
if (builtin.os == .linux) {
var wsz: linux.winsize = undefined;
- return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, isize(handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
+ return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, @as(isize, handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
}
unreachable;
}
@@ -1547,7 +1547,7 @@ pub fn isCygwinPty(handle: fd_t) bool {
}
const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
- const name_bytes = name_info_bytes[size .. size + usize(name_info.FileNameLength)];
+ const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];
const name_wide = @bytesToSlice(u16, name_bytes);
return mem.indexOf(u16, name_wide, [_]u16{ 'm', 's', 'y', 's', '-' }) != null or
mem.indexOf(u16, name_wide, [_]u16{ '-', 'p', 't', 'y' }) != null;
@@ -2897,7 +2897,7 @@ pub fn res_mkquery(
// Construct query template - ID will be filled later
var q: [280]u8 = undefined;
@memset(&q, 0, n);
- q[2] = u8(op) * 8 + 1;
+ q[2] = @as(u8, op) * 8 + 1;
q[5] = 1;
mem.copy(u8, q[13..], name);
var i: usize = 13;
@@ -3143,7 +3143,7 @@ pub fn dn_expand(
// loop invariants: p= msg.len) return error.InvalidDnsPacket;
p = msg.ptr + j;
diff --git a/lib/std/os/bits/dragonfly.zig b/lib/std/os/bits/dragonfly.zig
index 87d89df7d8..042857b750 100644
--- a/lib/std/os/bits/dragonfly.zig
+++ b/lib/std/os/bits/dragonfly.zig
@@ -315,7 +315,7 @@ pub const dirent = extern struct {
d_name: [256]u8,
pub fn reclen(self: dirent) u16 {
- return (@byteOffsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~u16(7);
+ return (@byteOffsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~@as(u16, 7);
}
};
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig
index 0fd528b0c0..e101337c3a 100644
--- a/lib/std/os/bits/linux.zig
+++ b/lib/std/os/bits/linux.zig
@@ -559,10 +559,10 @@ pub const EPOLLMSG = 0x400;
pub const EPOLLERR = 0x008;
pub const EPOLLHUP = 0x010;
pub const EPOLLRDHUP = 0x2000;
-pub const EPOLLEXCLUSIVE = (u32(1) << 28);
-pub const EPOLLWAKEUP = (u32(1) << 29);
-pub const EPOLLONESHOT = (u32(1) << 30);
-pub const EPOLLET = (u32(1) << 31);
+pub const EPOLLEXCLUSIVE = (@as(u32, 1) << 28);
+pub const EPOLLWAKEUP = (@as(u32, 1) << 29);
+pub const EPOLLONESHOT = (@as(u32, 1) << 30);
+pub const EPOLLET = (@as(u32, 1) << 31);
pub const CLOCK_REALTIME = 0;
pub const CLOCK_MONOTONIC = 1;
@@ -950,7 +950,7 @@ pub fn cap_valid(u8: x) bool {
}
pub fn CAP_TO_MASK(cap: u8) u32 {
- return u32(1) << u5(cap & 31);
+ return @as(u32, 1) << u5(cap & 31);
}
pub fn CAP_TO_INDEX(cap: u8) u8 {
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index a7dedefb43..618a21f456 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -46,22 +46,22 @@ pub fn getErrno(r: usize) u12 {
pub fn dup2(old: i32, new: i32) usize {
if (@hasDecl(@This(), "SYS_dup2")) {
- return syscall2(SYS_dup2, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)));
+ return syscall2(SYS_dup2, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)));
} else {
if (old == new) {
if (std.debug.runtime_safety) {
- const rc = syscall2(SYS_fcntl, @bitCast(usize, isize(old)), F_GETFD);
+ const rc = syscall2(SYS_fcntl, @bitCast(usize, @as(isize, old)), F_GETFD);
if (@bitCast(isize, rc) < 0) return rc;
}
return @intCast(usize, old);
} else {
- return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), 0);
+ return syscall3(SYS_dup3, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)), 0);
}
}
}
pub fn dup3(old: i32, new: i32, flags: u32) usize {
- return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), flags);
+ return syscall3(SYS_dup3, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)), flags);
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -102,7 +102,7 @@ pub fn futimens(fd: i32, times: *const [2]timespec) usize {
// TODO https://github.com/ziglang/zig/issues/265
pub fn utimensat(dirfd: i32, path: ?[*]const u8, times: *const [2]timespec, flags: u32) usize {
- return syscall4(SYS_utimensat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(times), flags);
+ return syscall4(SYS_utimensat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(times), flags);
}
pub fn futex_wait(uaddr: *const i32, futex_op: u32, val: i32, timeout: ?*timespec) usize {
@@ -120,7 +120,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {
pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {
return syscall3(
SYS_getdents,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(dirp),
std.math.min(len, maxInt(c_int)),
);
@@ -129,7 +129,7 @@ pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {
pub fn getdents64(fd: i32, dirp: [*]u8, len: usize) usize {
return syscall3(
SYS_getdents64,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(dirp),
std.math.min(len, maxInt(c_int)),
);
@@ -140,11 +140,11 @@ pub fn inotify_init1(flags: u32) usize {
}
pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize {
- return syscall3(SYS_inotify_add_watch, @bitCast(usize, isize(fd)), @ptrToInt(pathname), mask);
+ return syscall3(SYS_inotify_add_watch, @bitCast(usize, @as(isize, fd)), @ptrToInt(pathname), mask);
}
pub fn inotify_rm_watch(fd: i32, wd: i32) usize {
- return syscall2(SYS_inotify_rm_watch, @bitCast(usize, isize(fd)), @bitCast(usize, isize(wd)));
+ return syscall2(SYS_inotify_rm_watch, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, wd)));
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -152,13 +152,13 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz
if (@hasDecl(@This(), "SYS_readlink")) {
return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
} else {
- return syscall4(SYS_readlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
+ return syscall4(SYS_readlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
}
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
- return syscall4(SYS_readlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
+ return syscall4(SYS_readlinkat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -166,13 +166,13 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {
if (@hasDecl(@This(), "SYS_mkdir")) {
return syscall2(SYS_mkdir, @ptrToInt(path), mode);
} else {
- return syscall3(SYS_mkdirat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode);
+ return syscall3(SYS_mkdirat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode);
}
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize {
- return syscall3(SYS_mkdirat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);
+ return syscall3(SYS_mkdirat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), mode);
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -194,7 +194,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
if (@hasDecl(@This(), "SYS_mmap2")) {
// Make sure the offset is also specified in multiples of page size
if ((offset & (MMAP2_UNIT - 1)) != 0)
- return @bitCast(usize, isize(-EINVAL));
+ return @bitCast(usize, @as(isize, -EINVAL));
return syscall6(
SYS_mmap2,
@@ -202,7 +202,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
length,
prot,
flags,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@truncate(usize, offset / MMAP2_UNIT),
);
} else {
@@ -212,7 +212,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
length,
prot,
flags,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
offset,
);
}
@@ -249,13 +249,13 @@ pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
}
pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
- return syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
+ return syscall3(SYS_read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
}
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
return syscall5(
SYS_preadv,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(iov),
count,
@truncate(usize, offset),
@@ -266,7 +266,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
return syscall6(
SYS_preadv2,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(iov),
count,
@truncate(usize, offset),
@@ -276,17 +276,17 @@ pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: k
}
pub fn readv(fd: i32, iov: [*]const iovec, count: usize) usize {
- return syscall3(SYS_readv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);
+ return syscall3(SYS_readv, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
}
pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
- return syscall3(SYS_writev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);
+ return syscall3(SYS_writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
}
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
return syscall5(
SYS_pwritev,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(iov),
count,
@truncate(usize, offset),
@@ -297,7 +297,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
return syscall6(
SYS_pwritev2,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@ptrToInt(iov),
count,
@truncate(usize, offset),
@@ -311,7 +311,7 @@ pub fn rmdir(path: [*]const u8) usize {
if (@hasDecl(@This(), "SYS_rmdir")) {
return syscall1(SYS_rmdir, @ptrToInt(path));
} else {
- return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);
+ return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);
}
}
@@ -320,18 +320,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
if (@hasDecl(@This(), "SYS_symlink")) {
return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
} else {
- return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));
+ return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));
}
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize {
- return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(newfd)), @ptrToInt(newpath));
+ return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
- return syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
+ return syscall4(SYS_pread, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset);
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -339,13 +339,13 @@ pub fn access(path: [*]const u8, mode: u32) usize {
if (@hasDecl(@This(), "SYS_access")) {
return syscall2(SYS_access, @ptrToInt(path), mode);
} else {
- return syscall4(SYS_faccessat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode, 0);
+ return syscall4(SYS_faccessat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode, 0);
}
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize {
- return syscall4(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode, flags);
+ return syscall4(SYS_faccessat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), mode, flags);
}
pub fn pipe(fd: *[2]i32) usize {
@@ -363,11 +363,11 @@ pub fn pipe2(fd: *[2]i32, flags: u32) usize {
}
pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
- return syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);
+ return syscall3(SYS_write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
}
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
- return syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);
+ return syscall4(SYS_pwrite, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset);
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -375,9 +375,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {
if (@hasDecl(@This(), "SYS_rename")) {
return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
} else if (@hasDecl(@This(), "SYS_renameat")) {
- return syscall4(SYS_renameat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));
+ return syscall4(SYS_renameat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));
} else {
- return syscall5(SYS_renameat2, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new), 0);
+ return syscall5(SYS_renameat2, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new), 0);
}
}
@@ -385,17 +385,17 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
if (@hasDecl(@This(), "SYS_renameat")) {
return syscall4(
SYS_renameat,
- @bitCast(usize, isize(oldfd)),
+ @bitCast(usize, @as(isize, oldfd)),
@ptrToInt(old),
- @bitCast(usize, isize(newfd)),
+ @bitCast(usize, @as(isize, newfd)),
@ptrToInt(new),
);
} else {
return syscall5(
SYS_renameat2,
- @bitCast(usize, isize(oldfd)),
+ @bitCast(usize, @as(isize, oldfd)),
@ptrToInt(old),
- @bitCast(usize, isize(newfd)),
+ @bitCast(usize, @as(isize, newfd)),
@ptrToInt(new),
0,
);
@@ -406,9 +406,9 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize {
return syscall5(
SYS_renameat2,
- @bitCast(usize, isize(oldfd)),
+ @bitCast(usize, @as(isize, oldfd)),
@ptrToInt(oldpath),
- @bitCast(usize, isize(newfd)),
+ @bitCast(usize, @as(isize, newfd)),
@ptrToInt(newpath),
flags,
);
@@ -421,7 +421,7 @@ pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
} else {
return syscall4(
SYS_openat,
- @bitCast(usize, isize(AT_FDCWD)),
+ @bitCast(usize, @as(isize, AT_FDCWD)),
@ptrToInt(path),
flags,
perm,
@@ -437,7 +437,7 @@ pub fn create(path: [*]const u8, perm: usize) usize {
// TODO https://github.com/ziglang/zig/issues/265
pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize {
// dirfd could be negative, for example AT_FDCWD is -100
- return syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode);
+ return syscall4(SYS_openat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags, mode);
}
/// See also `clone` (from the arch-specific include)
@@ -451,14 +451,14 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
}
pub fn close(fd: i32) usize {
- return syscall1(SYS_close, @bitCast(usize, isize(fd)));
+ return syscall1(SYS_close, @bitCast(usize, @as(isize, fd)));
}
/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
return syscall5(
SYS__llseek,
- @bitCast(usize, isize(fd)),
+ @bitCast(usize, @as(isize, fd)),
@truncate(usize, offset >> 32),
@truncate(usize, offset),
@ptrToInt(result),
@@ -468,16 +468,16 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
/// Can only be called on 64 bit systems. For 32 bit see `llseek`.
pub fn lseek(fd: i32, offset: i64, whence: usize) usize {
- return syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), whence);
+ return syscall3(SYS_lseek, @bitCast(usize, @as(isize, fd)), @bitCast(usize, offset), whence);
}
pub fn exit(status: i32) noreturn {
- _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));
+ _ = syscall1(SYS_exit, @bitCast(usize, @as(isize, status)));
unreachable;
}
pub fn exit_group(status: i32) noreturn {
- _ = syscall1(SYS_exit_group, @bitCast(usize, isize(status)));
+ _ = syscall1(SYS_exit_group, @bitCast(usize, @as(isize, status)));
unreachable;
}
@@ -486,7 +486,7 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
}
pub fn kill(pid: i32, sig: i32) usize {
- return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig)));
+ return syscall2(SYS_kill, @bitCast(usize, @as(isize, pid)), @bitCast(usize, @as(isize, sig)));
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -494,17 +494,17 @@ pub fn unlink(path: [*]const u8) usize {
if (@hasDecl(@This(), "SYS_unlink")) {
return syscall1(SYS_unlink, @ptrToInt(path));
} else {
- return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), 0);
+ return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), 0);
}
}
// TODO https://github.com/ziglang/zig/issues/265
pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
- return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);
+ return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags);
}
pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {
- return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0);
+ return syscall4(SYS_wait4, @bitCast(usize, @as(isize, pid)), @ptrToInt(status), flags, 0);
}
var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
@@ -519,12 +519,12 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
const rc = f(clk_id, tp);
switch (rc) {
- 0, @bitCast(usize, isize(-EINVAL)) => return rc,
+ 0, @bitCast(usize, @as(isize, -EINVAL)) => return rc,
else => {},
}
}
}
- return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
+ return syscall2(SYS_clock_gettime, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
}
extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
@@ -537,15 +537,15 @@ extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
return f(clk, ts);
}
- return @bitCast(usize, isize(-ENOSYS));
+ return @bitCast(usize, @as(isize, -ENOSYS));
}
pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
- return syscall2(SYS_clock_getres, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
+ return syscall2(SYS_clock_getres, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
}
pub fn clock_settime(clk_id: i32, tp: *const timespec) usize {
- return syscall2(SYS_clock_settime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
+ return syscall2(SYS_clock_settime, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
}
pub fn gettimeofday(tv: *timeval, tz: *timezone) usize {
@@ -594,33 +594,33 @@ pub fn setregid(rgid: u32, egid: u32) usize {
pub fn getuid() u32 {
if (@hasDecl(@This(), "SYS_getuid32")) {
- return u32(syscall0(SYS_getuid32));
+ return @as(u32, syscall0(SYS_getuid32));
} else {
- return u32(syscall0(SYS_getuid));
+ return @as(u32, syscall0(SYS_getuid));
}
}
pub fn getgid() u32 {
if (@hasDecl(@This(), "SYS_getgid32")) {
- return u32(syscall0(SYS_getgid32));
+ return @as(u32, syscall0(SYS_getgid32));
} else {
- return u32(syscall0(SYS_getgid));
+ return @as(u32, syscall0(SYS_getgid));
}
}
pub fn geteuid() u32 {
if (@hasDecl(@This(), "SYS_geteuid32")) {
- return u32(syscall0(SYS_geteuid32));
+ return @as(u32, syscall0(SYS_geteuid32));
} else {
- return u32(syscall0(SYS_geteuid));
+ return @as(u32, syscall0(SYS_geteuid));
}
}
pub fn getegid() u32 {
if (@hasDecl(@This(), "SYS_getegid32")) {
- return u32(syscall0(SYS_getegid32));
+ return @as(u32, syscall0(SYS_getegid32));
} else {
- return u32(syscall0(SYS_getegid));
+ return @as(u32, syscall0(SYS_getegid));
}
}
@@ -743,11 +743,11 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {
}
pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
- return syscall3(SYS_getsockname, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));
+ return syscall3(SYS_getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
}
pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
- return syscall3(SYS_getpeername, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));
+ return syscall3(SYS_getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
}
pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
@@ -755,15 +755,15 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
}
pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
- return syscall5(SYS_setsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
+ return syscall5(SYS_setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
}
pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
- return syscall5(SYS_getsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
+ return syscall5(SYS_getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
}
pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {
- return syscall3(SYS_sendmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);
+ return syscall3(SYS_sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
}
pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize {
@@ -781,7 +781,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
// batch-send all messages up to the current message
if (next_unsent < i) {
const batch_size = i - next_unsent;
- const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
+ const r = syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
if (getErrno(r) != 0) return next_unsent;
if (r < batch_size) return next_unsent + r;
}
@@ -797,41 +797,41 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
}
if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG_EOR)
const batch_size = kvlen - next_unsent;
- const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
+ const r = syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
if (getErrno(r) != 0) return r;
return next_unsent + r;
}
return kvlen;
}
- return syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(msgvec), vlen, flags);
+ return syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msgvec), vlen, flags);
}
pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
- return syscall3(SYS_connect, @bitCast(usize, isize(fd)), @ptrToInt(addr), len);
+ return syscall3(SYS_connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);
}
pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
- return syscall3(SYS_recvmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);
+ return syscall3(SYS_recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
}
pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
- return syscall6(SYS_recvfrom, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
+ return syscall6(SYS_recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
}
pub fn shutdown(fd: i32, how: i32) usize {
- return syscall2(SYS_shutdown, @bitCast(usize, isize(fd)), @bitCast(usize, isize(how)));
+ return syscall2(SYS_shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));
}
pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
- return syscall3(SYS_bind, @bitCast(usize, isize(fd)), @ptrToInt(addr), @intCast(usize, len));
+ return syscall3(SYS_bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));
}
pub fn listen(fd: i32, backlog: u32) usize {
- return syscall2(SYS_listen, @bitCast(usize, isize(fd)), backlog);
+ return syscall2(SYS_listen, @bitCast(usize, @as(isize, fd)), backlog);
}
pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
- return syscall6(SYS_sendto, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
+ return syscall6(SYS_sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
}
pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
@@ -843,14 +843,14 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
}
pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {
- return syscall4(SYS_accept4, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len), flags);
+ return syscall4(SYS_accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);
}
pub fn fstat(fd: i32, stat_buf: *Stat) usize {
if (@hasDecl(@This(), "SYS_fstat64")) {
- return syscall2(SYS_fstat64, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));
+ return syscall2(SYS_fstat64, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));
} else {
- return syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));
+ return syscall2(SYS_fstat, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));
}
}
@@ -875,9 +875,9 @@ pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {
// TODO https://github.com/ziglang/zig/issues/265
pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize {
if (@hasDecl(@This(), "SYS_fstatat64")) {
- return syscall4(SYS_fstatat64, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
+ return syscall4(SYS_fstatat64, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
} else {
- return syscall4(SYS_fstatat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
+ return syscall4(SYS_fstatat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
}
}
@@ -885,14 +885,14 @@ pub fn statx(dirfd: i32, path: [*]const u8, flags: u32, mask: u32, statx_buf: *S
if (@hasDecl(@This(), "SYS_statx")) {
return syscall5(
SYS_statx,
- @bitCast(usize, isize(dirfd)),
+ @bitCast(usize, @as(isize, dirfd)),
@ptrToInt(path),
flags,
mask,
@ptrToInt(statx_buf),
);
}
- return @bitCast(usize, isize(-ENOSYS));
+ return @bitCast(usize, @as(isize, -ENOSYS));
}
// TODO https://github.com/ziglang/zig/issues/265
@@ -959,7 +959,7 @@ pub fn sched_yield() usize {
}
pub fn sched_getaffinity(pid: i32, size: usize, set: *cpu_set_t) usize {
- const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, isize(pid)), size, @ptrToInt(set));
+ const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set));
if (@bitCast(isize, rc) < 0) return rc;
if (rc < size) @memset(@ptrCast([*]u8, set) + rc, 0, size - rc);
return 0;
@@ -974,7 +974,7 @@ pub fn epoll_create1(flags: usize) usize {
}
pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: ?*epoll_event) usize {
- return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));
+ return syscall4(SYS_epoll_ctl, @bitCast(usize, @as(isize, epoll_fd)), @intCast(usize, op), @bitCast(usize, @as(isize, fd)), @ptrToInt(ev));
}
pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
@@ -984,10 +984,10 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout
pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {
return syscall6(
SYS_epoll_pwait,
- @bitCast(usize, isize(epoll_fd)),
+ @bitCast(usize, @as(isize, epoll_fd)),
@ptrToInt(events),
@intCast(usize, maxevents),
- @bitCast(usize, isize(timeout)),
+ @bitCast(usize, @as(isize, timeout)),
@ptrToInt(sigmask),
@sizeOf(sigset_t),
);
@@ -998,7 +998,7 @@ pub fn eventfd(count: u32, flags: u32) usize {
}
pub fn timerfd_create(clockid: i32, flags: u32) usize {
- return syscall2(SYS_timerfd_create, @bitCast(usize, isize(clockid)), flags);
+ return syscall2(SYS_timerfd_create, @bitCast(usize, @as(isize, clockid)), flags);
}
pub const itimerspec = extern struct {
@@ -1007,11 +1007,11 @@ pub const itimerspec = extern struct {
};
pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
- return syscall2(SYS_timerfd_gettime, @bitCast(usize, isize(fd)), @ptrToInt(curr_value));
+ return syscall2(SYS_timerfd_gettime, @bitCast(usize, @as(isize, fd)), @ptrToInt(curr_value));
}
pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
- return syscall4(SYS_timerfd_settime, @bitCast(usize, isize(fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value));
+ return syscall4(SYS_timerfd_settime, @bitCast(usize, @as(isize, fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value));
}
pub fn unshare(flags: usize) usize {
@@ -1096,11 +1096,11 @@ pub fn io_uring_setup(entries: u32, p: *io_uring_params) usize {
}
pub fn io_uring_enter(fd: i32, to_submit: u32, min_complete: u32, flags: u32, sig: ?*sigset_t) usize {
- return syscall6(SYS_io_uring_enter, @bitCast(usize, isize(fd)), to_submit, min_complete, flags, @ptrToInt(sig), NSIG / 8);
+ return syscall6(SYS_io_uring_enter, @bitCast(usize, @as(isize, fd)), to_submit, min_complete, flags, @ptrToInt(sig), NSIG / 8);
}
pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32) usize {
- return syscall4(SYS_io_uring_register, @bitCast(usize, isize(fd)), opcode, @ptrToInt(arg), nr_args);
+ return syscall4(SYS_io_uring_register, @bitCast(usize, @as(isize, fd)), opcode, @ptrToInt(arg), nr_args);
}
test "" {
diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig
index c7371fc28d..c457e10beb 100644
--- a/lib/std/os/linux/arm-eabi.zig
+++ b/lib/std/os/linux/arm-eabi.zig
@@ -100,7 +100,7 @@ pub extern fn getThreadPointer() usize {
pub nakedcc fn restore() void {
return asm volatile ("svc #0"
:
- : [number] "{r7}" (usize(SYS_sigreturn))
+ : [number] "{r7}" (@as(usize, SYS_sigreturn))
: "memory"
);
}
@@ -108,7 +108,7 @@ pub nakedcc fn restore() void {
pub nakedcc fn restore_rt() void {
return asm volatile ("svc #0"
:
- : [number] "{r7}" (usize(SYS_rt_sigreturn))
+ : [number] "{r7}" (@as(usize, SYS_rt_sigreturn))
: "memory"
);
}
diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig
index b8d8a1636b..ac2bb3bfdf 100644
--- a/lib/std/os/linux/arm64.zig
+++ b/lib/std/os/linux/arm64.zig
@@ -93,7 +93,7 @@ pub const restore = restore_rt;
pub nakedcc fn restore_rt() void {
return asm volatile ("svc #0"
:
- : [number] "{x8}" (usize(SYS_rt_sigreturn))
+ : [number] "{x8}" (@as(usize, SYS_rt_sigreturn))
: "memory", "cc"
);
}
diff --git a/lib/std/os/linux/mipsel.zig b/lib/std/os/linux/mipsel.zig
index 791bec6a12..60408c1e84 100644
--- a/lib/std/os/linux/mipsel.zig
+++ b/lib/std/os/linux/mipsel.zig
@@ -26,7 +26,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
\\ sw $3, 4($4)
\\ 2:
: [ret] "={$2}" (-> usize)
- : [number] "{$2}" (usize(SYS_pipe))
+ : [number] "{$2}" (@as(usize, SYS_pipe))
: "memory", "cc", "$7"
);
}
@@ -147,7 +147,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a
pub nakedcc fn restore() void {
return asm volatile ("syscall"
:
- : [number] "{$2}" (usize(SYS_sigreturn))
+ : [number] "{$2}" (@as(usize, SYS_sigreturn))
: "memory", "cc", "$7"
);
}
@@ -155,7 +155,7 @@ pub nakedcc fn restore() void {
pub nakedcc fn restore_rt() void {
return asm volatile ("syscall"
:
- : [number] "{$2}" (usize(SYS_rt_sigreturn))
+ : [number] "{$2}" (@as(usize, SYS_rt_sigreturn))
: "memory", "cc", "$7"
);
}
diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig
index 64facede89..b7c59a9039 100644
--- a/lib/std/os/linux/riscv64.zig
+++ b/lib/std/os/linux/riscv64.zig
@@ -92,7 +92,7 @@ pub const restore = restore_rt;
pub nakedcc fn restore_rt() void {
return asm volatile ("ecall"
:
- : [number] "{x17}" (usize(SYS_rt_sigreturn))
+ : [number] "{x17}" (@as(usize, SYS_rt_sigreturn))
: "memory"
);
}
diff --git a/lib/std/os/linux/vdso.zig b/lib/std/os/linux/vdso.zig
index 86d54bfbf8..d3e00b8673 100644
--- a/lib/std/os/linux/vdso.zig
+++ b/lib/std/os/linux/vdso.zig
@@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
var i: usize = 0;
while (i < hashtab[1]) : (i += 1) {
- if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue;
- if (0 == (u32(1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
+ if (0 == (@as(u32, 1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue;
+ if (0 == (@as(u32, 1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
if (0 == syms[i].st_shndx) continue;
if (!mem.eql(u8, name, mem.toSliceConst(u8, strings + syms[i].st_name))) continue;
if (maybe_versym) |versym| {
diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig
index e0e4687c9f..d037b3c6ae 100644
--- a/lib/std/os/linux/x86_64.zig
+++ b/lib/std/os/linux/x86_64.zig
@@ -93,7 +93,7 @@ pub const restore = restore_rt;
pub nakedcc fn restore_rt() void {
return asm volatile ("syscall"
:
- : [number] "{rax}" (usize(SYS_rt_sigreturn))
+ : [number] "{rax}" (@as(usize, SYS_rt_sigreturn))
: "rcx", "r11", "memory"
);
}
diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig
index 1d61548396..741f108eea 100644
--- a/lib/std/os/test.zig
+++ b/lib/std/os/test.zig
@@ -172,7 +172,7 @@ export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
var counter = data.?;
// Count how many libraries are loaded
- counter.* += usize(1);
+ counter.* += @as(usize, 1);
// The image should contain at least a PT_LOAD segment
if (info.dlpi_phnum < 1) return -1;
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index c8c99c6a59..4342512941 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -801,7 +801,7 @@ pub fn toSysTime(ns: i64) i64 {
}
pub fn fileTimeToNanoSeconds(ft: FILETIME) i64 {
- const hns = @bitCast(i64, (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime);
+ const hns = @bitCast(i64, (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime);
return fromSysTime(hns);
}
diff --git a/lib/std/os/zen.zig b/lib/std/os/zen.zig
index 9d111d98ae..190b7ffe08 100644
--- a/lib/std/os/zen.zig
+++ b/lib/std/os/zen.zig
@@ -138,7 +138,7 @@ pub const Syscall = enum(usize) {
////////////////////
pub fn exit(status: i32) noreturn {
- _ = syscall1(Syscall.exit, @bitCast(usize, isize(status)));
+ _ = syscall1(Syscall.exit, @bitCast(usize, @as(isize, status)));
unreachable;
}
@@ -167,7 +167,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
}
pub fn createThread(function: fn () void) u16 {
- return u16(syscall1(Syscall.createThread, @ptrToInt(function)));
+ return @as(u16, syscall1(Syscall.createThread, @ptrToInt(function)));
}
/////////////////////////
diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig
index 5cbab2d33b..c22d701bf2 100644
--- a/lib/std/packed_int_array.zig
+++ b/lib/std/packed_int_array.zig
@@ -331,7 +331,7 @@ test "PackedIntArray" {
var data = PackedArray(undefined);
//write values, counting up
- var i = usize(0);
+ var i = @as(usize, 0);
var count = I(0);
while (i < data.len()) : (i += 1) {
data.set(i, count);
@@ -352,7 +352,7 @@ test "PackedIntArray" {
test "PackedIntArray init" {
const PackedArray = PackedIntArray(u3, 8);
var packed_array = PackedArray.init([_]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array.len()) : (i += 1) testing.expect(packed_array.get(i) == i);
}
@@ -375,7 +375,7 @@ test "PackedIntSlice" {
var data = P.init(&buffer, int_count);
//write values, counting up
- var i = usize(0);
+ var i = @as(usize, 0);
var count = I(0);
while (i < data.len()) : (i += 1) {
data.set(i, count);
@@ -406,7 +406,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
const limit = (1 << bits);
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array.len()) : (i += 1) {
packed_array.set(i, @intCast(Int, i % limit));
}
@@ -466,7 +466,7 @@ test "PackedIntSlice accumulating bit offsets" {
var packed_array = PackedArray(undefined);
var packed_slice = packed_array.slice(0, packed_array.len());
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array.len() - 1) : (i += 1) {
packed_slice = packed_slice.slice(1, packed_slice.len());
}
@@ -476,7 +476,7 @@ test "PackedIntSlice accumulating bit offsets" {
var packed_array = PackedArray(undefined);
var packed_slice = packed_array.slice(0, packed_array.len());
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array.len() - 1) : (i += 1) {
packed_slice = packed_slice.slice(1, packed_slice.len());
}
@@ -493,7 +493,7 @@ test "PackedInt(Array/Slice) sliceCast" {
var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);
const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_slice_cast_2.len()) : (i += 1) {
const val = switch (builtin.endian) {
.Big => 0b01,
@@ -541,7 +541,7 @@ test "PackedInt(Array/Slice)Endian" {
testing.expect(packed_array_be.bytes[0] == 0b00000001);
testing.expect(packed_array_be.bytes[1] == 0b00100011);
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array_be.len()) : (i += 1) {
testing.expect(packed_array_be.get(i) == i);
}
@@ -579,7 +579,7 @@ test "PackedInt(Array/Slice)Endian" {
testing.expect(packed_array_be.bytes[3] == 0b00000001);
testing.expect(packed_array_be.bytes[4] == 0b00000000);
- var i = usize(0);
+ var i = @as(usize, 0);
while (i < packed_array_be.len()) : (i += 1) {
testing.expect(packed_array_be.get(i) == i);
}
diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig
index 7a2b2c6b6b..8e4a9b5d6a 100644
--- a/lib/std/pdb.zig
+++ b/lib/std/pdb.zig
@@ -532,7 +532,7 @@ const Msf = struct {
const stream_sizes = try allocator.alloc(u32, stream_count);
defer allocator.free(stream_sizes);
- // Microsoft's implementation uses u32(-1) for inexistant streams.
+ // Microsoft's implementation uses @as(u32, -1) for inexistant streams.
// These streams are not used, but still participate in the file
// and must be taken into account when resolving stream indices.
const Nil = 0xFFFFFFFF;
diff --git a/lib/std/priority_queue.zig b/lib/std/priority_queue.zig
index a081e03c5f..bf54f6937f 100644
--- a/lib/std/priority_queue.zig
+++ b/lib/std/priority_queue.zig
@@ -236,12 +236,12 @@ test "std.PriorityQueue: add and remove min heap" {
try queue.add(23);
try queue.add(25);
try queue.add(13);
- expectEqual(u32(7), queue.remove());
- expectEqual(u32(12), queue.remove());
- expectEqual(u32(13), queue.remove());
- expectEqual(u32(23), queue.remove());
- expectEqual(u32(25), queue.remove());
- expectEqual(u32(54), queue.remove());
+ expectEqual(@as(u32, 7), queue.remove());
+ expectEqual(@as(u32, 12), queue.remove());
+ expectEqual(@as(u32, 13), queue.remove());
+ expectEqual(@as(u32, 23), queue.remove());
+ expectEqual(@as(u32, 25), queue.remove());
+ expectEqual(@as(u32, 54), queue.remove());
}
test "std.PriorityQueue: add and remove same min heap" {
@@ -254,12 +254,12 @@ test "std.PriorityQueue: add and remove same min heap" {
try queue.add(2);
try queue.add(1);
try queue.add(1);
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(2), queue.remove());
- expectEqual(u32(2), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 2), queue.remove());
+ expectEqual(@as(u32, 2), queue.remove());
}
test "std.PriorityQueue: removeOrNull on empty" {
@@ -276,9 +276,9 @@ test "std.PriorityQueue: edge case 3 elements" {
try queue.add(9);
try queue.add(3);
try queue.add(2);
- expectEqual(u32(2), queue.remove());
- expectEqual(u32(3), queue.remove());
- expectEqual(u32(9), queue.remove());
+ expectEqual(@as(u32, 2), queue.remove());
+ expectEqual(@as(u32, 3), queue.remove());
+ expectEqual(@as(u32, 9), queue.remove());
}
test "std.PriorityQueue: peek" {
@@ -289,8 +289,8 @@ test "std.PriorityQueue: peek" {
try queue.add(9);
try queue.add(3);
try queue.add(2);
- expectEqual(u32(2), queue.peek().?);
- expectEqual(u32(2), queue.peek().?);
+ expectEqual(@as(u32, 2), queue.peek().?);
+ expectEqual(@as(u32, 2), queue.peek().?);
}
test "std.PriorityQueue: sift up with odd indices" {
@@ -341,12 +341,12 @@ test "std.PriorityQueue: add and remove max heap" {
try queue.add(23);
try queue.add(25);
try queue.add(13);
- expectEqual(u32(54), queue.remove());
- expectEqual(u32(25), queue.remove());
- expectEqual(u32(23), queue.remove());
- expectEqual(u32(13), queue.remove());
- expectEqual(u32(12), queue.remove());
- expectEqual(u32(7), queue.remove());
+ expectEqual(@as(u32, 54), queue.remove());
+ expectEqual(@as(u32, 25), queue.remove());
+ expectEqual(@as(u32, 23), queue.remove());
+ expectEqual(@as(u32, 13), queue.remove());
+ expectEqual(@as(u32, 12), queue.remove());
+ expectEqual(@as(u32, 7), queue.remove());
}
test "std.PriorityQueue: add and remove same max heap" {
@@ -359,12 +359,12 @@ test "std.PriorityQueue: add and remove same max heap" {
try queue.add(2);
try queue.add(1);
try queue.add(1);
- expectEqual(u32(2), queue.remove());
- expectEqual(u32(2), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
- expectEqual(u32(1), queue.remove());
+ expectEqual(@as(u32, 2), queue.remove());
+ expectEqual(@as(u32, 2), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
+ expectEqual(@as(u32, 1), queue.remove());
}
test "std.PriorityQueue: iterator" {
@@ -386,5 +386,5 @@ test "std.PriorityQueue: iterator" {
_ = map.remove(e);
}
- expectEqual(usize(0), map.count());
+ expectEqual(@as(usize, 0), map.count());
}
diff --git a/lib/std/rand.zig b/lib/std/rand.zig
index e14a60e2ae..2cd1583f63 100644
--- a/lib/std/rand.zig
+++ b/lib/std/rand.zig
@@ -633,8 +633,8 @@ pub const Xoroshiro128 = struct {
const r = s0 +% s1;
s1 ^= s0;
- self.s[0] = math.rotl(u64, s0, u8(55)) ^ s1 ^ (s1 << 14);
- self.s[1] = math.rotl(u64, s1, u8(36));
+ self.s[0] = math.rotl(u64, s0, @as(u8, 55)) ^ s1 ^ (s1 << 14);
+ self.s[1] = math.rotl(u64, s1, @as(u8, 36));
return r;
}
@@ -652,7 +652,7 @@ pub const Xoroshiro128 = struct {
inline for (table) |entry| {
var b: usize = 0;
while (b < 64) : (b += 1) {
- if ((entry & (u64(1) << @intCast(u6, b))) != 0) {
+ if ((entry & (@as(u64, 1) << @intCast(u6, b))) != 0) {
s0 ^= self.s[0];
s1 ^= self.s[1];
}
@@ -1090,7 +1090,7 @@ fn testRange(r: *Random, start: i8, end: i8) void {
testRangeBias(r, start, end, false);
}
fn testRangeBias(r: *Random, start: i8, end: i8, biased: bool) void {
- const count = @intCast(usize, i32(end) - i32(start));
+ const count = @intCast(usize, @as(i32, end) - @as(i32, start));
var values_buffer = [_]bool{false} ** 0x100;
const values = values_buffer[0..count];
var i: usize = 0;
diff --git a/lib/std/rand/ziggurat.zig b/lib/std/rand/ziggurat.zig
index 995248415b..c29d3eeb2b 100644
--- a/lib/std/rand/ziggurat.zig
+++ b/lib/std/rand/ziggurat.zig
@@ -17,7 +17,7 @@ pub fn next_f64(random: *Random, comptime tables: ZigTable) f64 {
// We manually construct a float from parts as we can avoid an extra random lookup here by
// using the unused exponent for the lookup table entry.
const bits = random.scalar(u64);
- const i = usize(bits & 0xff);
+ const i = @as(usize, bits & 0xff);
const u = blk: {
if (tables.is_symmetric) {
diff --git a/lib/std/segmented_list.zig b/lib/std/segmented_list.zig
index 3bbbde782e..7db1535755 100644
--- a/lib/std/segmented_list.zig
+++ b/lib/std/segmented_list.zig
@@ -162,7 +162,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
/// Grows or shrinks capacity to match usage.
pub fn setCapacity(self: *Self, new_capacity: usize) !void {
if (prealloc_item_count != 0) {
- if (new_capacity <= usize(1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
+ if (new_capacity <= @as(usize, 1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
return self.shrinkCapacity(new_capacity);
}
}
@@ -231,9 +231,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
fn shelfSize(shelf_index: ShelfIndex) usize {
if (prealloc_item_count == 0) {
- return usize(1) << shelf_index;
+ return @as(usize, 1) << shelf_index;
}
- return usize(1) << (shelf_index + (prealloc_exp + 1));
+ return @as(usize, 1) << (shelf_index + (prealloc_exp + 1));
}
fn shelfIndex(list_index: usize) ShelfIndex {
@@ -245,9 +245,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {
if (prealloc_item_count == 0) {
- return (list_index + 1) - (usize(1) << shelf_index);
+ return (list_index + 1) - (@as(usize, 1) << shelf_index);
}
- return list_index + prealloc_item_count - (usize(1) << ((prealloc_exp + 1) + shelf_index));
+ return list_index + prealloc_item_count - (@as(usize, 1) << ((prealloc_exp + 1) + shelf_index));
}
fn freeShelves(self: *Self, from_count: ShelfIndex, to_count: ShelfIndex) void {
diff --git a/lib/std/sort.zig b/lib/std/sort.zig
index 378a92992f..c5758dd6e7 100644
--- a/lib/std/sort.zig
+++ b/lib/std/sort.zig
@@ -813,7 +813,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
// where have some idea as to how many unique values there are and where the next value might be
fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
if (range.length() == 0) return range.start;
- const skip = math.max(range.length() / unique, usize(1));
+ const skip = math.max(range.length() / unique, @as(usize, 1));
var index = range.start + skip;
while (lessThan(items[index - 1], value)) : (index += skip) {
@@ -827,7 +827,7 @@ fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessTh
fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
if (range.length() == 0) return range.start;
- const skip = math.max(range.length() / unique, usize(1));
+ const skip = math.max(range.length() / unique, @as(usize, 1));
var index = range.end - skip;
while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {
@@ -841,7 +841,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessT
fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
if (range.length() == 0) return range.start;
- const skip = math.max(range.length() / unique, usize(1));
+ const skip = math.max(range.length() / unique, @as(usize, 1));
var index = range.start + skip;
while (!lessThan(value, items[index - 1])) : (index += skip) {
@@ -855,7 +855,7 @@ fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessTha
fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
if (range.length() == 0) return range.start;
- const skip = math.max(range.length() / unique, usize(1));
+ const skip = math.max(range.length() / unique, @as(usize, 1));
var index = range.end - skip;
while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {
diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig
index 473d2d4e33..145c8897d5 100644
--- a/lib/std/special/c.zig
+++ b/lib/std/special/c.zig
@@ -62,7 +62,7 @@ extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int {
r += 1;
n -= 1;
}
- return c_int(l[0]) - c_int(r[0]);
+ return @as(c_int, l[0]) - @as(c_int, r[0]);
}
extern fn strerror(errnum: c_int) [*]const u8 {
@@ -540,7 +540,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
// scale result up
if (ex > 0) {
ux -%= 1 << digits;
- ux |= uint(@bitCast(u32, ex)) << digits;
+ ux |= @as(uint, @bitCast(u32, ex)) << digits;
} else {
ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));
}
@@ -687,7 +687,7 @@ export fn sqrt(x: f64) f64 {
export fn sqrtf(x: f32) f32 {
const tiny: f32 = 1.0e-30;
- const sign: i32 = @bitCast(i32, u32(0x80000000));
+ const sign: i32 = @bitCast(i32, @as(u32, 0x80000000));
var ix: i32 = @bitCast(i32, x);
if ((ix & 0x7F800000) == 0x7F800000) {
diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig
index 0a09f616e9..1fbb618b1e 100644
--- a/lib/std/special/compiler_rt.zig
+++ b/lib/std/special/compiler_rt.zig
@@ -672,7 +672,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
// special cases
if (d == 0) return 0; // ?!
if (n == 0) return 0;
- var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n)));
+ var sr = @bitCast(c_uint, @as(c_int, @clz(u32, d)) - @as(c_int, @clz(u32, n)));
// 0 <= sr <= n_uword_bits - 1 or sr large
if (sr > n_uword_bits - 1) {
// d > r
@@ -1414,10 +1414,10 @@ test "test_divsi3" {
[_]i32{ -2, 1, -2 },
[_]i32{ -2, -1, 2 },
- [_]i32{ @bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000)) },
- [_]i32{ @bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000)) },
- [_]i32{ @bitCast(i32, u32(0x80000000)), -2, 0x40000000 },
- [_]i32{ @bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000)) },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) },
};
for (cases) |case| {
@@ -1443,8 +1443,8 @@ test "test_divmodsi4" {
[_]i32{ 19, 5, 3, 4 },
[_]i32{ 19, -5, -3, 4 },
- [_]i32{ @bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0 },
- [_]i32{ @bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1 },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 },
+ [_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 },
};
for (cases) |case| {
@@ -1467,10 +1467,10 @@ test "test_divdi3" {
[_]i64{ -2, 1, -2 },
[_]i64{ -2, -1, 2 },
- [_]i64{ @bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)) },
- [_]i64{ @bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)) },
- [_]i64{ @bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000 },
- [_]i64{ @bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000)) },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) },
};
for (cases) |case| {
@@ -1492,12 +1492,12 @@ test "test_moddi3" {
[_]i64{ -5, 3, -2 },
[_]i64{ -5, -3, -2 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2 },
- [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 },
+ [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 },
};
for (cases) |case| {
diff --git a/lib/std/special/compiler_rt/addXf3.zig b/lib/std/special/compiler_rt/addXf3.zig
index 1654c1f08b..e3dd1819c3 100644
--- a/lib/std/special/compiler_rt/addXf3.zig
+++ b/lib/std/special/compiler_rt/addXf3.zig
@@ -19,26 +19,26 @@ pub extern fn __addtf3(a: f128, b: f128) f128 {
}
pub extern fn __subsf3(a: f32, b: f32) f32 {
- const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (u32(1) << 31));
+ const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (@as(u32, 1) << 31));
return addXf3(f32, a, neg_b);
}
pub extern fn __subdf3(a: f64, b: f64) f64 {
- const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (u64(1) << 63));
+ const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (@as(u64, 1) << 63));
return addXf3(f64, a, neg_b);
}
pub extern fn __subtf3(a: f128, b: f128) f128 {
- const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127));
+ const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (@as(u128, 1) << 127));
return addXf3(f128, a, neg_b);
}
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
const significandBits = std.math.floatMantissaBits(T);
- const implicitBit = Z(1) << significandBits;
+ const implicitBit = @as(Z, 1) << significandBits;
const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(S, shift);
@@ -48,17 +48,17 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
fn addXf3(comptime T: type, a: T, b: T) T {
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
const typeWidth = T.bit_count;
const significandBits = std.math.floatMantissaBits(T);
const exponentBits = std.math.floatExponentBits(T);
- const signBit = (Z(1) << (significandBits + exponentBits));
+ const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (Z(1) << significandBits);
+ const implicitBit = (@as(Z, 1) << significandBits);
const quietBit = implicitBit >> 1;
const significandMask = implicitBit - 1;
@@ -78,8 +78,8 @@ fn addXf3(comptime T: type, a: T, b: T) T {
const infRep = @bitCast(Z, std.math.inf(T));
// Detect if a or b is zero, infinity, or NaN.
- if (aAbs -% Z(1) >= infRep - Z(1) or
- bAbs -% Z(1) >= infRep - Z(1))
+ if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
+ bAbs -% @as(Z, 1) >= infRep - @as(Z, 1))
{
// NaN + anything = qNaN
if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);
@@ -148,7 +148,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
const @"align" = @intCast(Z, aExponent - bExponent);
if (@"align" != 0) {
if (@"align" < typeWidth) {
- const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) Z(1) else 0;
+ const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0;
bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;
} else {
bSignificand = 1; // sticky; b is known to be non-zero.
@@ -157,7 +157,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
if (subtraction) {
aSignificand -= bSignificand;
// If a == -b, return +zero.
- if (aSignificand == 0) return @bitCast(T, Z(0));
+ if (aSignificand == 0) return @bitCast(T, @as(Z, 0));
// If partial cancellation occured, we need to left-shift the result
// and adjust the exponent:
@@ -185,7 +185,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
// Result is denormal before rounding; the exponent is zero and we
// need to shift the significand.
const shift = @intCast(Z, 1 - aExponent);
- const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) Z(1) else 0;
+ const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) @as(Z, 1) else 0;
aSignificand = aSignificand >> @intCast(S, shift | sticky);
aExponent = 0;
}
diff --git a/lib/std/special/compiler_rt/addXf3_test.zig b/lib/std/special/compiler_rt/addXf3_test.zig
index 099b737976..af991b37e9 100644
--- a/lib/std/special/compiler_rt/addXf3_test.zig
+++ b/lib/std/special/compiler_rt/addXf3_test.zig
@@ -3,8 +3,8 @@
// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c
// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/subtf3_test.c
-const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);
-const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);
+const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
+const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64);
const __addtf3 = @import("addXf3.zig").__addtf3;
@@ -34,7 +34,7 @@ test "addtf3" {
test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// NaN + any = NaN
- test__addtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+ test__addtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// inf + inf = inf
test__addtf3(inf128, inf128, 0x7fff000000000000, 0x0);
@@ -75,7 +75,7 @@ test "subtf3" {
test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// NaN + any = NaN
- test__subtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+ test__subtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// inf - any = inf
test__subtf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
diff --git a/lib/std/special/compiler_rt/comparedf2.zig b/lib/std/special/compiler_rt/comparedf2.zig
index f97e2474be..95dc878630 100644
--- a/lib/std/special/compiler_rt/comparedf2.zig
+++ b/lib/std/special/compiler_rt/comparedf2.zig
@@ -13,19 +13,19 @@ const srep_t = i64;
const typeWidth = rep_t.bit_count;
const significandBits = std.math.floatMantissaBits(fp_t);
const exponentBits = std.math.floatExponentBits(fp_t);
-const signBit = (rep_t(1) << (significandBits + exponentBits));
+const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const absMask = signBit - 1;
-const implicitBit = rep_t(1) << significandBits;
+const implicitBit = @as(rep_t, 1) << significandBits;
const significandMask = implicitBit - 1;
const exponentMask = absMask ^ significandMask;
const infRep = @bitCast(rep_t, std.math.inf(fp_t));
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const LE_LESS = c_int(-1);
-const LE_EQUAL = c_int(0);
-const LE_GREATER = c_int(1);
-const LE_UNORDERED = c_int(1);
+const LE_LESS = @as(c_int, -1);
+const LE_EQUAL = @as(c_int, 0);
+const LE_GREATER = @as(c_int, 1);
+const LE_UNORDERED = @as(c_int, 1);
pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {
@setRuntimeSafety(is_test);
@@ -65,10 +65,10 @@ pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const GE_LESS = c_int(-1);
-const GE_EQUAL = c_int(0);
-const GE_GREATER = c_int(1);
-const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
+const GE_LESS = @as(c_int, -1);
+const GE_EQUAL = @as(c_int, 0);
+const GE_GREATER = @as(c_int, 1);
+const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
pub extern fn __gedf2(a: fp_t, b: fp_t) c_int {
@setRuntimeSafety(is_test);
diff --git a/lib/std/special/compiler_rt/comparesf2.zig b/lib/std/special/compiler_rt/comparesf2.zig
index e99e0bb3dd..4468da4fbe 100644
--- a/lib/std/special/compiler_rt/comparesf2.zig
+++ b/lib/std/special/compiler_rt/comparesf2.zig
@@ -13,19 +13,19 @@ const srep_t = i32;
const typeWidth = rep_t.bit_count;
const significandBits = std.math.floatMantissaBits(fp_t);
const exponentBits = std.math.floatExponentBits(fp_t);
-const signBit = (rep_t(1) << (significandBits + exponentBits));
+const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const absMask = signBit - 1;
-const implicitBit = rep_t(1) << significandBits;
+const implicitBit = @as(rep_t, 1) << significandBits;
const significandMask = implicitBit - 1;
const exponentMask = absMask ^ significandMask;
const infRep = @bitCast(rep_t, std.math.inf(fp_t));
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const LE_LESS = c_int(-1);
-const LE_EQUAL = c_int(0);
-const LE_GREATER = c_int(1);
-const LE_UNORDERED = c_int(1);
+const LE_LESS = @as(c_int, -1);
+const LE_EQUAL = @as(c_int, 0);
+const LE_GREATER = @as(c_int, 1);
+const LE_UNORDERED = @as(c_int, 1);
pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {
@setRuntimeSafety(is_test);
@@ -65,10 +65,10 @@ pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const GE_LESS = c_int(-1);
-const GE_EQUAL = c_int(0);
-const GE_GREATER = c_int(1);
-const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
+const GE_LESS = @as(c_int, -1);
+const GE_EQUAL = @as(c_int, 0);
+const GE_GREATER = @as(c_int, 1);
+const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
pub extern fn __gesf2(a: fp_t, b: fp_t) c_int {
@setRuntimeSafety(is_test);
diff --git a/lib/std/special/compiler_rt/comparetf2.zig b/lib/std/special/compiler_rt/comparetf2.zig
index 05e5974558..e973018455 100644
--- a/lib/std/special/compiler_rt/comparetf2.zig
+++ b/lib/std/special/compiler_rt/comparetf2.zig
@@ -1,9 +1,9 @@
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const LE_LESS = c_int(-1);
-const LE_EQUAL = c_int(0);
-const LE_GREATER = c_int(1);
-const LE_UNORDERED = c_int(1);
+const LE_LESS = @as(c_int, -1);
+const LE_EQUAL = @as(c_int, 0);
+const LE_GREATER = @as(c_int, 1);
+const LE_UNORDERED = @as(c_int, 1);
const rep_t = u128;
const srep_t = i128;
@@ -11,9 +11,9 @@ const srep_t = i128;
const typeWidth = rep_t.bit_count;
const significandBits = 112;
const exponentBits = (typeWidth - significandBits - 1);
-const signBit = (rep_t(1) << (significandBits + exponentBits));
+const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const absMask = signBit - 1;
-const implicitBit = rep_t(1) << significandBits;
+const implicitBit = @as(rep_t, 1) << significandBits;
const significandMask = implicitBit - 1;
const exponentMask = absMask ^ significandMask;
const infRep = exponentMask;
@@ -60,10 +60,10 @@ pub extern fn __letf2(a: f128, b: f128) c_int {
// TODO https://github.com/ziglang/zig/issues/641
// and then make the return types of some of these functions the enum instead of c_int
-const GE_LESS = c_int(-1);
-const GE_EQUAL = c_int(0);
-const GE_GREATER = c_int(1);
-const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
+const GE_LESS = @as(c_int, -1);
+const GE_EQUAL = @as(c_int, 0);
+const GE_GREATER = @as(c_int, 1);
+const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
pub extern fn __getf2(a: f128, b: f128) c_int {
@setRuntimeSafety(is_test);
diff --git a/lib/std/special/compiler_rt/divdf3.zig b/lib/std/special/compiler_rt/divdf3.zig
index 072feaec67..9937b09497 100644
--- a/lib/std/special/compiler_rt/divdf3.zig
+++ b/lib/std/special/compiler_rt/divdf3.zig
@@ -14,11 +14,11 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
const significandBits = std.math.floatMantissaBits(f64);
const exponentBits = std.math.floatExponentBits(f64);
- const signBit = (Z(1) << (significandBits + exponentBits));
+ const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (Z(1) << significandBits);
+ const implicitBit = (@as(Z, 1) << significandBits);
const quietBit = implicitBit >> 1;
const significandMask = implicitBit - 1;
@@ -91,7 +91,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits.
const q31b: u32 = @truncate(u32, bSignificand >> 21);
- var recip32 = u32(0x7504f333) -% q31b;
+ var recip32 = @as(u32, 0x7504f333) -% q31b;
// Now refine the reciprocal estimate using a Newton-Raphson iteration:
//
@@ -101,12 +101,12 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
// with each iteration, so after three iterations, we have about 28 binary
// digits of accuracy.
var correction32: u32 = undefined;
- correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);
- recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);
- correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);
- recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);
- correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);
- recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);
+ correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
+ recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
+ correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
+ recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
+ correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
+ recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
// recip32 might have overflowed to exactly zero in the preceding
// computation if the high word of b is exactly 1.0. This would sabotage
@@ -119,10 +119,10 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
const q63blo: u32 = @truncate(u32, bSignificand << 11);
var correction: u64 = undefined;
var reciprocal: u64 = undefined;
- correction = ~(u64(recip32) *% q31b +% (u64(recip32) *% q63blo >> 32)) +% 1;
+ correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1;
const cHi = @truncate(u32, correction >> 32);
const cLo = @truncate(u32, correction);
- reciprocal = u64(recip32) *% cHi +% (u64(recip32) *% cLo >> 32);
+ reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32);
// We already adjusted the 32-bit estimate, now we need to adjust the final
// 64-bit reciprocal estimate downward to ensure that it is strictly smaller
@@ -195,7 +195,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
// Clear the implicit bit
var absResult = quotient & significandMask;
// Insert the exponent
- absResult |= @bitCast(Z, SignedZ(writtenExponent)) << significandBits;
+ absResult |= @bitCast(Z, @as(SignedZ, writtenExponent)) << significandBits;
// Round
absResult +%= round;
// Insert the sign and return
@@ -208,7 +208,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
switch (Z) {
u32 => {
// 32x32 --> 64 bit multiply
- const product = u64(a) * u64(b);
+ const product = @as(u64, a) * @as(u64, b);
hi.* = @truncate(u32, product >> 32);
lo.* = @truncate(u32, product);
},
@@ -237,9 +237,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
},
u128 => {
- const Word_LoMask = u64(0x00000000ffffffff);
- const Word_HiMask = u64(0xffffffff00000000);
- const Word_FullMask = u64(0xffffffffffffffff);
+ const Word_LoMask = @as(u64, 0x00000000ffffffff);
+ const Word_HiMask = @as(u64, 0xffffffff00000000);
+ const Word_FullMask = @as(u64, 0xffffffffffffffff);
const S = struct {
fn Word_1(x: u128) u64 {
return @truncate(u32, x >> 96);
@@ -275,22 +275,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
const product43: u64 = S.Word_4(a) * S.Word_3(b);
const product44: u64 = S.Word_4(a) * S.Word_4(b);
- const sum0: u128 = u128(product44);
- const sum1: u128 = u128(product34) +%
- u128(product43);
- const sum2: u128 = u128(product24) +%
- u128(product33) +%
- u128(product42);
- const sum3: u128 = u128(product14) +%
- u128(product23) +%
- u128(product32) +%
- u128(product41);
- const sum4: u128 = u128(product13) +%
- u128(product22) +%
- u128(product31);
- const sum5: u128 = u128(product12) +%
- u128(product21);
- const sum6: u128 = u128(product11);
+ const sum0: u128 = @as(u128, product44);
+ const sum1: u128 = @as(u128, product34) +%
+ @as(u128, product43);
+ const sum2: u128 = @as(u128, product24) +%
+ @as(u128, product33) +%
+ @as(u128, product42);
+ const sum3: u128 = @as(u128, product14) +%
+ @as(u128, product23) +%
+ @as(u128, product32) +%
+ @as(u128, product41);
+ const sum4: u128 = @as(u128, product13) +%
+ @as(u128, product22) +%
+ @as(u128, product31);
+ const sum5: u128 = @as(u128, product12) +%
+ @as(u128, product21);
+ const sum6: u128 = @as(u128, product11);
const r0: u128 = (sum0 & Word_FullMask) +%
((sum1 & Word_LoMask) << 32);
@@ -316,7 +316,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
@setRuntimeSafety(builtin.is_test);
const Z = @IntType(false, T.bit_count);
const significandBits = std.math.floatMantissaBits(T);
- const implicitBit = Z(1) << significandBits;
+ const implicitBit = @as(Z, 1) << significandBits;
const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
diff --git a/lib/std/special/compiler_rt/divsf3.zig b/lib/std/special/compiler_rt/divsf3.zig
index 447653fbe1..4ee2eed36c 100644
--- a/lib/std/special/compiler_rt/divsf3.zig
+++ b/lib/std/special/compiler_rt/divsf3.zig
@@ -13,11 +13,11 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
const significandBits = std.math.floatMantissaBits(f32);
const exponentBits = std.math.floatExponentBits(f32);
- const signBit = (Z(1) << (significandBits + exponentBits));
+ const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (Z(1) << significandBits);
+ const implicitBit = (@as(Z, 1) << significandBits);
const quietBit = implicitBit >> 1;
const significandMask = implicitBit - 1;
@@ -90,7 +90,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits.
const q31b = bSignificand << 8;
- var reciprocal = u32(0x7504f333) -% q31b;
+ var reciprocal = @as(u32, 0x7504f333) -% q31b;
// Now refine the reciprocal estimate using a Newton-Raphson iteration:
//
@@ -100,12 +100,12 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
// with each iteration, so after three iterations, we have about 28 binary
// digits of accuracy.
var correction: u32 = undefined;
- correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);
- reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);
- correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);
- reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);
- correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);
- reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);
+ correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
+ reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
+ correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
+ reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
+ correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
+ reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
// Exhaustive testing shows that the error in reciprocal after three steps
// is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our
@@ -127,7 +127,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
// is the error in the reciprocal of b scaled by the maximum
// possible value of a. As a consequence of this error bound,
// either q or nextafter(q) is the correctly rounded
- var quotient: Z = @truncate(u32, u64(reciprocal) *% (aSignificand << 1) >> 32);
+ var quotient: Z = @truncate(u32, @as(u64, reciprocal) *% (aSignificand << 1) >> 32);
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
// In either case, we are going to compute a residual of the form
@@ -189,7 +189,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
@setRuntimeSafety(builtin.is_test);
const Z = @IntType(false, T.bit_count);
const significandBits = std.math.floatMantissaBits(T);
- const implicitBit = Z(1) << significandBits;
+ const implicitBit = @as(Z, 1) << significandBits;
const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
diff --git a/lib/std/special/compiler_rt/divti3_test.zig b/lib/std/special/compiler_rt/divti3_test.zig
index e1c1babae7..8601cfae03 100644
--- a/lib/std/special/compiler_rt/divti3_test.zig
+++ b/lib/std/special/compiler_rt/divti3_test.zig
@@ -14,8 +14,8 @@ test "divti3" {
test__divti3(-2, 1, -2);
test__divti3(-2, -1, 2);
- test__divti3(@bitCast(i128, u128(0x8 << 124)), 1, @bitCast(i128, u128(0x8 << 124)));
- test__divti3(@bitCast(i128, u128(0x8 << 124)), -1, @bitCast(i128, u128(0x8 << 124)));
- test__divti3(@bitCast(i128, u128(0x8 << 124)), -2, @bitCast(i128, u128(0x4 << 124)));
- test__divti3(@bitCast(i128, u128(0x8 << 124)), 2, @bitCast(i128, u128(0xc << 124)));
+ test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 1, @bitCast(i128, @as(u128, 0x8 << 124)));
+ test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -1, @bitCast(i128, @as(u128, 0x8 << 124)));
+ test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -2, @bitCast(i128, @as(u128, 0x4 << 124)));
+ test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 2, @bitCast(i128, @as(u128, 0xc << 124)));
}
diff --git a/lib/std/special/compiler_rt/extendXfYf2.zig b/lib/std/special/compiler_rt/extendXfYf2.zig
index e10667843f..3bdc5164e2 100644
--- a/lib/std/special/compiler_rt/extendXfYf2.zig
+++ b/lib/std/special/compiler_rt/extendXfYf2.zig
@@ -49,7 +49,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
const dstInfExp = (1 << dstExpBits) - 1;
const dstExpBias = dstInfExp >> 1;
- const dstMinNormal: dst_rep_t = dst_rep_t(1) << dstSigBits;
+ const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
// Break a into a sign and representation of the absolute value
const aRep: src_rep_t = @bitCast(src_rep_t, a);
@@ -61,7 +61,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
// a is a normal number.
// Extend to the destination type by shifting the significand and
// exponent into the proper position and rebiasing the exponent.
- absResult = dst_rep_t(aAbs) << (dstSigBits - srcSigBits);
+ absResult = @as(dst_rep_t, aAbs) << (dstSigBits - srcSigBits);
absResult += (dstExpBias - srcExpBias) << dstSigBits;
} else if (aAbs >= srcInfinity) {
// a is NaN or infinity.
@@ -69,15 +69,15 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
// bit (if needed) and right-aligning the rest of the trailing NaN
// payload field.
absResult = dstInfExp << dstSigBits;
- absResult |= dst_rep_t(aAbs & srcQNaN) << (dstSigBits - srcSigBits);
- absResult |= dst_rep_t(aAbs & srcNaNCode) << (dstSigBits - srcSigBits);
+ absResult |= @as(dst_rep_t, aAbs & srcQNaN) << (dstSigBits - srcSigBits);
+ absResult |= @as(dst_rep_t, aAbs & srcNaNCode) << (dstSigBits - srcSigBits);
} else if (aAbs != 0) {
// a is denormal.
// renormalize the significand and clear the leading bit, then insert
// the correct adjusted exponent in the destination type.
const scale: u32 = @clz(src_rep_t, aAbs) -
- @clz(src_rep_t, src_rep_t(srcMinNormal));
- absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);
+ @clz(src_rep_t, @as(src_rep_t, srcMinNormal));
+ absResult = @as(dst_rep_t, aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);
absResult ^= dstMinNormal;
const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
absResult |= @intCast(dst_rep_t, resultExponent) << dstSigBits;
@@ -87,7 +87,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
}
// Apply the signbit to (dst_t)abs(a).
- const result: dst_rep_t align(@alignOf(dst_t)) = absResult | dst_rep_t(sign) << (dstBits - srcBits);
+ const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);
return @bitCast(dst_t, result);
}
diff --git a/lib/std/special/compiler_rt/extendXfYf2_test.zig b/lib/std/special/compiler_rt/extendXfYf2_test.zig
index 6f8111c8fb..aa2faae901 100644
--- a/lib/std/special/compiler_rt/extendXfYf2_test.zig
+++ b/lib/std/special/compiler_rt/extendXfYf2_test.zig
@@ -134,11 +134,11 @@ test "extendsftf2" {
}
fn makeQNaN64() f64 {
- return @bitCast(f64, u64(0x7ff8000000000000));
+ return @bitCast(f64, @as(u64, 0x7ff8000000000000));
}
fn makeInf64() f64 {
- return @bitCast(f64, u64(0x7ff0000000000000));
+ return @bitCast(f64, @as(u64, 0x7ff0000000000000));
}
fn makeNaN64(rand: u64) f64 {
@@ -146,7 +146,7 @@ fn makeNaN64(rand: u64) f64 {
}
fn makeQNaN32() f32 {
- return @bitCast(f32, u32(0x7fc00000));
+ return @bitCast(f32, @as(u32, 0x7fc00000));
}
fn makeNaN32(rand: u32) f32 {
@@ -154,5 +154,5 @@ fn makeNaN32(rand: u32) f32 {
}
fn makeInf32() f32 {
- return @bitCast(f32, u32(0x7f800000));
+ return @bitCast(f32, @as(u32, 0x7f800000));
}
diff --git a/lib/std/special/compiler_rt/fixdfdi_test.zig b/lib/std/special/compiler_rt/fixdfdi_test.zig
index 1ba8a4f87d..e06d641824 100644
--- a/lib/std/special/compiler_rt/fixdfdi_test.zig
+++ b/lib/std/special/compiler_rt/fixdfdi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixdfdi(a: f64, expected: i64) void {
const x = __fixdfdi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixdfsi_test.zig b/lib/std/special/compiler_rt/fixdfsi_test.zig
index fa5ff72e8f..da53468c7d 100644
--- a/lib/std/special/compiler_rt/fixdfsi_test.zig
+++ b/lib/std/special/compiler_rt/fixdfsi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixdfsi(a: f64, expected: i32) void {
const x = __fixdfsi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixdfti_test.zig b/lib/std/special/compiler_rt/fixdfti_test.zig
index 4ab2c04cd1..b0c9049ba8 100644
--- a/lib/std/special/compiler_rt/fixdfti_test.zig
+++ b/lib/std/special/compiler_rt/fixdfti_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixdfti(a: f64, expected: i128) void {
const x = __fixdfti(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixint.zig b/lib/std/special/compiler_rt/fixint.zig
index fd31798cc2..426ee1d58a 100644
--- a/lib/std/special/compiler_rt/fixint.zig
+++ b/lib/std/special/compiler_rt/fixint.zig
@@ -25,11 +25,11 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
const typeWidth = rep_t.bit_count;
const exponentBits = (typeWidth - significandBits - 1);
- const signBit = (rep_t(1) << (significandBits + exponentBits));
+ const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (rep_t(1) << significandBits);
+ const implicitBit = (@as(rep_t, 1) << significandBits);
const significandMask = (implicitBit - 1);
// Break a into sign, exponent, significand
@@ -51,7 +51,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
// If the value is too large for the integer type, saturate.
if (@intCast(usize, exponent) >= fixint_t.bit_count) {
- return if (negative) fixint_t(minInt(fixint_t)) else fixint_t(maxInt(fixint_t));
+ return if (negative) @as(fixint_t, minInt(fixint_t)) else @as(fixint_t, maxInt(fixint_t));
}
// If 0 <= exponent < significandBits, right shift else left shift
diff --git a/lib/std/special/compiler_rt/fixint_test.zig b/lib/std/special/compiler_rt/fixint_test.zig
index a876e17263..d5f7b3898d 100644
--- a/lib/std/special/compiler_rt/fixint_test.zig
+++ b/lib/std/special/compiler_rt/fixint_test.zig
@@ -81,8 +81,8 @@ test "fixint.i3" {
test "fixint.i32" {
test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));
test__fixint(f64, i32, -math.f64_max, math.minInt(i32));
- test__fixint(f64, i32, f64(math.minInt(i32)), math.minInt(i32));
- test__fixint(f64, i32, f64(math.minInt(i32)) + 1, math.minInt(i32) + 1);
+ test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32));
+ test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1);
test__fixint(f64, i32, -2.0, -2);
test__fixint(f64, i32, -1.9, -1);
test__fixint(f64, i32, -1.1, -1);
@@ -96,8 +96,8 @@ test "fixint.i32" {
test__fixint(f64, i32, 0.1, 0);
test__fixint(f64, i32, 0.9, 0);
test__fixint(f64, i32, 1.0, 1);
- test__fixint(f64, i32, f64(math.maxInt(i32)) - 1, math.maxInt(i32) - 1);
- test__fixint(f64, i32, f64(math.maxInt(i32)), math.maxInt(i32));
+ test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1);
+ test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32));
test__fixint(f64, i32, math.f64_max, math.maxInt(i32));
test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));
}
@@ -105,9 +105,9 @@ test "fixint.i32" {
test "fixint.i64" {
test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));
test__fixint(f64, i64, -math.f64_max, math.minInt(i64));
- test__fixint(f64, i64, f64(math.minInt(i64)), math.minInt(i64));
- test__fixint(f64, i64, f64(math.minInt(i64)) + 1, math.minInt(i64));
- test__fixint(f64, i64, f64(math.minInt(i64) / 2), math.minInt(i64) / 2);
+ test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64));
+ test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64));
+ test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2);
test__fixint(f64, i64, -2.0, -2);
test__fixint(f64, i64, -1.9, -1);
test__fixint(f64, i64, -1.1, -1);
@@ -121,8 +121,8 @@ test "fixint.i64" {
test__fixint(f64, i64, 0.1, 0);
test__fixint(f64, i64, 0.9, 0);
test__fixint(f64, i64, 1.0, 1);
- test__fixint(f64, i64, f64(math.maxInt(i64)) - 1, math.maxInt(i64));
- test__fixint(f64, i64, f64(math.maxInt(i64)), math.maxInt(i64));
+ test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64));
+ test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64));
test__fixint(f64, i64, math.f64_max, math.maxInt(i64));
test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));
}
@@ -130,8 +130,8 @@ test "fixint.i64" {
test "fixint.i128" {
test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));
test__fixint(f64, i128, -math.f64_max, math.minInt(i128));
- test__fixint(f64, i128, f64(math.minInt(i128)), math.minInt(i128));
- test__fixint(f64, i128, f64(math.minInt(i128)) + 1, math.minInt(i128));
+ test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128));
+ test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128));
test__fixint(f64, i128, -2.0, -2);
test__fixint(f64, i128, -1.9, -1);
test__fixint(f64, i128, -1.1, -1);
@@ -145,8 +145,8 @@ test "fixint.i128" {
test__fixint(f64, i128, 0.1, 0);
test__fixint(f64, i128, 0.9, 0);
test__fixint(f64, i128, 1.0, 1);
- test__fixint(f64, i128, f64(math.maxInt(i128)) - 1, math.maxInt(i128));
- test__fixint(f64, i128, f64(math.maxInt(i128)), math.maxInt(i128));
+ test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128));
+ test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128));
test__fixint(f64, i128, math.f64_max, math.maxInt(i128));
test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));
}
diff --git a/lib/std/special/compiler_rt/fixsfdi_test.zig b/lib/std/special/compiler_rt/fixsfdi_test.zig
index bfd715425c..02844946a7 100644
--- a/lib/std/special/compiler_rt/fixsfdi_test.zig
+++ b/lib/std/special/compiler_rt/fixsfdi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixsfdi(a: f32, expected: i64) void {
const x = __fixsfdi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixsfsi_test.zig b/lib/std/special/compiler_rt/fixsfsi_test.zig
index 30406fea22..69d8309de0 100644
--- a/lib/std/special/compiler_rt/fixsfsi_test.zig
+++ b/lib/std/special/compiler_rt/fixsfsi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixsfsi(a: f32, expected: i32) void {
const x = __fixsfsi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixsfti_test.zig b/lib/std/special/compiler_rt/fixsfti_test.zig
index 7136f7cfe8..cecfeda557 100644
--- a/lib/std/special/compiler_rt/fixsfti_test.zig
+++ b/lib/std/special/compiler_rt/fixsfti_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixsfti(a: f32, expected: i128) void {
const x = __fixsfti(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixtfdi_test.zig b/lib/std/special/compiler_rt/fixtfdi_test.zig
index 7c63547642..b45001e18e 100644
--- a/lib/std/special/compiler_rt/fixtfdi_test.zig
+++ b/lib/std/special/compiler_rt/fixtfdi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixtfdi(a: f128, expected: i64) void {
const x = __fixtfdi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixtfsi_test.zig b/lib/std/special/compiler_rt/fixtfsi_test.zig
index da769089df..c6f6623995 100644
--- a/lib/std/special/compiler_rt/fixtfsi_test.zig
+++ b/lib/std/special/compiler_rt/fixtfsi_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixtfsi(a: f128, expected: i32) void {
const x = __fixtfsi(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixtfti_test.zig b/lib/std/special/compiler_rt/fixtfti_test.zig
index 02dba7fd61..b36c5beb4e 100644
--- a/lib/std/special/compiler_rt/fixtfti_test.zig
+++ b/lib/std/special/compiler_rt/fixtfti_test.zig
@@ -6,7 +6,7 @@ const warn = std.debug.warn;
fn test__fixtfti(a: f128, expected: i128) void {
const x = __fixtfti(a);
- //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
+ //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
testing.expect(x == expected);
}
diff --git a/lib/std/special/compiler_rt/fixuint.zig b/lib/std/special/compiler_rt/fixuint.zig
index 55a113b368..977d3c16c9 100644
--- a/lib/std/special/compiler_rt/fixuint.zig
+++ b/lib/std/special/compiler_rt/fixuint.zig
@@ -19,11 +19,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
};
const typeWidth = rep_t.bit_count;
const exponentBits = (typeWidth - significandBits - 1);
- const signBit = (rep_t(1) << (significandBits + exponentBits));
+ const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (rep_t(1) << significandBits);
+ const implicitBit = (@as(rep_t, 1) << significandBits);
const significandMask = (implicitBit - 1);
// Break a into sign, exponent, significand
@@ -31,7 +31,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
const absMask = signBit - 1;
const aAbs: rep_t = aRep & absMask;
- const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1);
+ const sign = if ((aRep & signBit) != 0) @as(i32, -1) else @as(i32, 1);
const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
const significand: rep_t = (aAbs & significandMask) | implicitBit;
@@ -39,7 +39,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
if (sign == -1 or exponent < 0) return 0;
// If the value is too large for the integer type, saturate.
- if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~fixuint_t(0);
+ if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~@as(fixuint_t, 0);
// If 0 <= exponent < significandBits, right shift to get the result.
// Otherwise, shift left.
diff --git a/lib/std/special/compiler_rt/fixunstfsi_test.zig b/lib/std/special/compiler_rt/fixunstfsi_test.zig
index e709636912..286567629a 100644
--- a/lib/std/special/compiler_rt/fixunstfsi_test.zig
+++ b/lib/std/special/compiler_rt/fixunstfsi_test.zig
@@ -6,7 +6,7 @@ fn test__fixunstfsi(a: f128, expected: u32) void {
testing.expect(x == expected);
}
-const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
+const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
test "fixunstfsi" {
test__fixunstfsi(inf128, 0xffffffff);
diff --git a/lib/std/special/compiler_rt/fixunstfti_test.zig b/lib/std/special/compiler_rt/fixunstfti_test.zig
index 833e4779dd..62a9bbfecf 100644
--- a/lib/std/special/compiler_rt/fixunstfti_test.zig
+++ b/lib/std/special/compiler_rt/fixunstfti_test.zig
@@ -6,7 +6,7 @@ fn test__fixunstfti(a: f128, expected: u128) void {
testing.expect(x == expected);
}
-const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
+const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
test "fixunstfti" {
test__fixunstfti(inf128, 0xffffffffffffffffffffffffffffffff);
diff --git a/lib/std/special/compiler_rt/floatsiXf.zig b/lib/std/special/compiler_rt/floatsiXf.zig
index 7e05a3ebf7..714681834d 100644
--- a/lib/std/special/compiler_rt/floatsiXf.zig
+++ b/lib/std/special/compiler_rt/floatsiXf.zig
@@ -6,24 +6,24 @@ fn floatsiXf(comptime T: type, a: i32) T {
@setRuntimeSafety(builtin.is_test);
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
if (a == 0) {
- return T(0.0);
+ return @as(T, 0.0);
}
const significandBits = std.math.floatMantissaBits(T);
const exponentBits = std.math.floatExponentBits(T);
const exponentBias = ((1 << exponentBits - 1) - 1);
- const implicitBit = Z(1) << significandBits;
- const signBit = Z(1 << Z.bit_count - 1);
+ const implicitBit = @as(Z, 1) << significandBits;
+ const signBit = @as(Z, 1 << Z.bit_count - 1);
const sign = a >> 31;
// Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).
const abs_a = (a ^ sign) -% sign;
// The exponent is the width of abs(a)
- const exp = Z(31 - @clz(i32, abs_a));
+ const exp = @as(Z, 31 - @clz(i32, abs_a));
const sign_bit = if (sign < 0) signBit else 0;
diff --git a/lib/std/special/compiler_rt/floattidf.zig b/lib/std/special/compiler_rt/floattidf.zig
index 42ef6df7e4..1e83674598 100644
--- a/lib/std/special/compiler_rt/floattidf.zig
+++ b/lib/std/special/compiler_rt/floattidf.zig
@@ -47,7 +47,7 @@ pub extern fn __floattidf(arg: i128) f64 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
- if ((a & (u128(1) << DBL_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << DBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/floattisf.zig b/lib/std/special/compiler_rt/floattisf.zig
index f397d130ef..0c02bfff1f 100644
--- a/lib/std/special/compiler_rt/floattisf.zig
+++ b/lib/std/special/compiler_rt/floattisf.zig
@@ -48,7 +48,7 @@ pub extern fn __floattisf(arg: i128) f32 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
- if ((a & (u128(1) << FLT_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << FLT_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/floattitf.zig b/lib/std/special/compiler_rt/floattitf.zig
index b05282e293..aac22e36d0 100644
--- a/lib/std/special/compiler_rt/floattitf.zig
+++ b/lib/std/special/compiler_rt/floattitf.zig
@@ -47,7 +47,7 @@ pub extern fn __floattitf(arg: i128) f128 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
- if ((a & (u128(1) << LDBL_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << LDBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/floatunsidf.zig b/lib/std/special/compiler_rt/floatunsidf.zig
index efeb4c2672..d744009aea 100644
--- a/lib/std/special/compiler_rt/floatunsidf.zig
+++ b/lib/std/special/compiler_rt/floatunsidf.zig
@@ -2,7 +2,7 @@ const builtin = @import("builtin");
const std = @import("std");
const maxInt = std.math.maxInt;
-const implicitBit = u64(1) << 52;
+const implicitBit = @as(u64, 1) << 52;
pub extern fn __floatunsidf(arg: u32) f64 {
@setRuntimeSafety(builtin.is_test);
@@ -10,10 +10,10 @@ pub extern fn __floatunsidf(arg: u32) f64 {
if (arg == 0) return 0.0;
// The exponent is the width of abs(a)
- const exp = u64(31) - @clz(u32, arg);
+ const exp = @as(u64, 31) - @clz(u32, arg);
// Shift a into the significand field and clear the implicit bit
const shift = @intCast(u6, 52 - exp);
- const mant = u64(arg) << shift ^ implicitBit;
+ const mant = @as(u64, arg) << shift ^ implicitBit;
return @bitCast(f64, mant | (exp + 1023) << 52);
}
diff --git a/lib/std/special/compiler_rt/floatuntidf.zig b/lib/std/special/compiler_rt/floatuntidf.zig
index 2cd38c7308..5d3a201058 100644
--- a/lib/std/special/compiler_rt/floatuntidf.zig
+++ b/lib/std/special/compiler_rt/floatuntidf.zig
@@ -32,7 +32,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
const shift_amt = @bitCast(i32, N + (DBL_MANT_DIG + 2)) - sd;
const shift_amt_u7 = @intCast(u7, shift_amt);
a = (a >> @intCast(u7, sd - (DBL_MANT_DIG + 2))) |
- @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);
+ @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
},
}
// finish
@@ -40,7 +40,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
- if ((a & (u128(1) << DBL_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << DBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/floatuntisf.zig b/lib/std/special/compiler_rt/floatuntisf.zig
index 1b42b267d9..e450ad9a48 100644
--- a/lib/std/special/compiler_rt/floatuntisf.zig
+++ b/lib/std/special/compiler_rt/floatuntisf.zig
@@ -32,7 +32,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
const shift_amt = @bitCast(i32, N + (FLT_MANT_DIG + 2)) - sd;
const shift_amt_u7 = @intCast(u7, shift_amt);
a = (a >> @intCast(u7, sd - (FLT_MANT_DIG + 2))) |
- @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);
+ @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
},
}
// finish
@@ -40,7 +40,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
- if ((a & (u128(1) << FLT_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << FLT_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/floatuntitf.zig b/lib/std/special/compiler_rt/floatuntitf.zig
index eddcf92efd..f92942e034 100644
--- a/lib/std/special/compiler_rt/floatuntitf.zig
+++ b/lib/std/special/compiler_rt/floatuntitf.zig
@@ -32,7 +32,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
const shift_amt = @bitCast(i32, N + (LDBL_MANT_DIG + 2)) - sd;
const shift_amt_u7 = @intCast(u7, shift_amt);
a = (a >> @intCast(u7, sd - (LDBL_MANT_DIG + 2))) |
- @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);
+ @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
},
}
// finish
@@ -40,7 +40,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
- if ((a & (u128(1) << LDBL_MANT_DIG)) != 0) {
+ if ((a & (@as(u128, 1) << LDBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
diff --git a/lib/std/special/compiler_rt/mulXf3.zig b/lib/std/special/compiler_rt/mulXf3.zig
index 51d40ad26f..11ee0b49a4 100644
--- a/lib/std/special/compiler_rt/mulXf3.zig
+++ b/lib/std/special/compiler_rt/mulXf3.zig
@@ -24,11 +24,11 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
const significandBits = std.math.floatMantissaBits(T);
const exponentBits = std.math.floatExponentBits(T);
- const signBit = (Z(1) << (significandBits + exponentBits));
+ const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
const exponentBias = (maxExponent >> 1);
- const implicitBit = (Z(1) << significandBits);
+ const implicitBit = (@as(Z, 1) << significandBits);
const quietBit = implicitBit >> 1;
const significandMask = implicitBit - 1;
@@ -122,7 +122,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
// a zero of the appropriate sign. Mathematically there is no need to
// handle this case separately, but we make it a special case to
// simplify the shift logic.
- const shift: u32 = @truncate(u32, Z(1) -% @bitCast(u32, productExponent));
+ const shift: u32 = @truncate(u32, @as(Z, 1) -% @bitCast(u32, productExponent));
if (shift >= typeWidth) return @bitCast(T, productSign);
// Otherwise, shift the significand of the result so that the round
@@ -131,7 +131,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
} else {
// Result is normal before rounding; insert the exponent.
productHi &= significandMask;
- productHi |= Z(@bitCast(u32, productExponent)) << significandBits;
+ productHi |= @as(Z, @bitCast(u32, productExponent)) << significandBits;
}
// Insert the sign of the result:
@@ -150,7 +150,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
switch (Z) {
u32 => {
// 32x32 --> 64 bit multiply
- const product = u64(a) * u64(b);
+ const product = @as(u64, a) * @as(u64, b);
hi.* = @truncate(u32, product >> 32);
lo.* = @truncate(u32, product);
},
@@ -179,9 +179,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
},
u128 => {
- const Word_LoMask = u64(0x00000000ffffffff);
- const Word_HiMask = u64(0xffffffff00000000);
- const Word_FullMask = u64(0xffffffffffffffff);
+ const Word_LoMask = @as(u64, 0x00000000ffffffff);
+ const Word_HiMask = @as(u64, 0xffffffff00000000);
+ const Word_FullMask = @as(u64, 0xffffffffffffffff);
const S = struct {
fn Word_1(x: u128) u64 {
return @truncate(u32, x >> 96);
@@ -217,22 +217,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
const product43: u64 = S.Word_4(a) * S.Word_3(b);
const product44: u64 = S.Word_4(a) * S.Word_4(b);
- const sum0: u128 = u128(product44);
- const sum1: u128 = u128(product34) +%
- u128(product43);
- const sum2: u128 = u128(product24) +%
- u128(product33) +%
- u128(product42);
- const sum3: u128 = u128(product14) +%
- u128(product23) +%
- u128(product32) +%
- u128(product41);
- const sum4: u128 = u128(product13) +%
- u128(product22) +%
- u128(product31);
- const sum5: u128 = u128(product12) +%
- u128(product21);
- const sum6: u128 = u128(product11);
+ const sum0: u128 = @as(u128, product44);
+ const sum1: u128 = @as(u128, product34) +%
+ @as(u128, product43);
+ const sum2: u128 = @as(u128, product24) +%
+ @as(u128, product33) +%
+ @as(u128, product42);
+ const sum3: u128 = @as(u128, product14) +%
+ @as(u128, product23) +%
+ @as(u128, product32) +%
+ @as(u128, product41);
+ const sum4: u128 = @as(u128, product13) +%
+ @as(u128, product22) +%
+ @as(u128, product31);
+ const sum5: u128 = @as(u128, product12) +%
+ @as(u128, product21);
+ const sum6: u128 = @as(u128, product11);
const r0: u128 = (sum0 & Word_FullMask) +%
((sum1 & Word_LoMask) << 32);
@@ -258,7 +258,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
@setRuntimeSafety(builtin.is_test);
const Z = @IntType(false, T.bit_count);
const significandBits = std.math.floatMantissaBits(T);
- const implicitBit = Z(1) << significandBits;
+ const implicitBit = @as(Z, 1) << significandBits;
const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
diff --git a/lib/std/special/compiler_rt/mulXf3_test.zig b/lib/std/special/compiler_rt/mulXf3_test.zig
index 1c0c0fc043..57dc385321 100644
--- a/lib/std/special/compiler_rt/mulXf3_test.zig
+++ b/lib/std/special/compiler_rt/mulXf3_test.zig
@@ -2,8 +2,8 @@
//
// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c
-const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);
-const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);
+const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
+const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64);
const __multf3 = @import("mulXf3.zig").__multf3;
@@ -39,7 +39,7 @@ fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
}
fn makeNaN128(rand: u64) f128 {
- const int_result = u128(0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
+ const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
const float_result = @bitCast(f128, int_result);
return float_result;
}
@@ -55,15 +55,15 @@ test "multf3" {
// any * any
test__multf3(
- @bitCast(f128, u128(0x40042eab345678439abcdefea5678234)),
- @bitCast(f128, u128(0x3ffeedcb34a235253948765432134675)),
+ @bitCast(f128, @as(u128, 0x40042eab345678439abcdefea5678234)),
+ @bitCast(f128, @as(u128, 0x3ffeedcb34a235253948765432134675)),
0x400423e7f9e3c9fc,
0xd906c2c2a85777c4,
);
test__multf3(
- @bitCast(f128, u128(0x3fcd353e45674d89abacc3a2ebf3ff50)),
- @bitCast(f128, u128(0x3ff6ed8764648369535adf4be3214568)),
+ @bitCast(f128, @as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50)),
+ @bitCast(f128, @as(u128, 0x3ff6ed8764648369535adf4be3214568)),
0x3fc52a163c6223fc,
0xc94c4bf0430768b4,
);
@@ -76,8 +76,8 @@ test "multf3" {
);
test__multf3(
- @bitCast(f128, u128(0x3f154356473c82a9fabf2d22ace345df)),
- @bitCast(f128, u128(0x3e38eda98765476743ab21da23d45679)),
+ @bitCast(f128, @as(u128, 0x3f154356473c82a9fabf2d22ace345df)),
+ @bitCast(f128, @as(u128, 0x3e38eda98765476743ab21da23d45679)),
0x3d4f37c1a3137cae,
0xfc6807048bc2836a,
);
diff --git a/lib/std/special/compiler_rt/muldi3.zig b/lib/std/special/compiler_rt/muldi3.zig
index 7700777c16..3efc5a9ac6 100644
--- a/lib/std/special/compiler_rt/muldi3.zig
+++ b/lib/std/special/compiler_rt/muldi3.zig
@@ -21,7 +21,7 @@ fn __muldsi3(a: u32, b: u32) i64 {
@setRuntimeSafety(builtin.is_test);
const bits_in_word_2 = @sizeOf(i32) * 8 / 2;
- const lower_mask = (~u32(0)) >> bits_in_word_2;
+ const lower_mask = (~@as(u32, 0)) >> bits_in_word_2;
var r: dwords = undefined;
r.s.low = (a & lower_mask) *% (b & lower_mask);
diff --git a/lib/std/special/compiler_rt/mulodi4.zig b/lib/std/special/compiler_rt/mulodi4.zig
index 82e9ef3253..21c7fd1f97 100644
--- a/lib/std/special/compiler_rt/mulodi4.zig
+++ b/lib/std/special/compiler_rt/mulodi4.zig
@@ -6,7 +6,7 @@ const minInt = std.math.minInt;
pub extern fn __mulodi4(a: i64, b: i64, overflow: *c_int) i64 {
@setRuntimeSafety(builtin.is_test);
- const min = @bitCast(i64, u64(1 << (i64.bit_count - 1)));
+ const min = @bitCast(i64, @as(u64, 1 << (i64.bit_count - 1)));
const max = ~min;
overflow.* = 0;
diff --git a/lib/std/special/compiler_rt/mulodi4_test.zig b/lib/std/special/compiler_rt/mulodi4_test.zig
index 7575c77044..803d60e8fa 100644
--- a/lib/std/special/compiler_rt/mulodi4_test.zig
+++ b/lib/std/special/compiler_rt/mulodi4_test.zig
@@ -52,34 +52,34 @@ test "mulodi4" {
test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1);
test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);
- test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, u64(0x8000000000000001)), 0);
- test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 0);
+ test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
+ test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0);
test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0);
test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);
test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);
- test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, u64(0x8000000000000001)), 1);
- test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 1);
+ test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
+ test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -2, @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 0, 0, 0);
- test__mulodi4(0, @bitCast(i64, u64(0x8000000000000000)), 0, 0);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)), 0);
- test__mulodi4(1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 0);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0, 0);
+ test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
+ test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -2, @bitCast(i64, u64(0x8000000000000001)), 1);
- test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 1);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);
- test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 0, 0, 0);
- test__mulodi4(0, @bitCast(i64, u64(0x8000000000000001)), 0, 0);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 1, @bitCast(i64, u64(0x8000000000000001)), 0);
- test__mulodi4(1, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 0);
- test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);
- test__mulodi4(2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000000)), 1);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
+ test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);
+ test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0, 0);
+ test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
+ test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
+ test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
+ test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
}
diff --git a/lib/std/special/compiler_rt/muloti4.zig b/lib/std/special/compiler_rt/muloti4.zig
index ccde8e3e6c..ad6ad43808 100644
--- a/lib/std/special/compiler_rt/muloti4.zig
+++ b/lib/std/special/compiler_rt/muloti4.zig
@@ -4,7 +4,7 @@ const compiler_rt = @import("../compiler_rt.zig");
pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
@setRuntimeSafety(builtin.is_test);
- const min = @bitCast(i128, u128(1 << (i128.bit_count - 1)));
+ const min = @bitCast(i128, @as(u128, 1 << (i128.bit_count - 1)));
const max = ~min;
overflow.* = 0;
diff --git a/lib/std/special/compiler_rt/muloti4_test.zig b/lib/std/special/compiler_rt/muloti4_test.zig
index 00144a8839..f94a13e04f 100644
--- a/lib/std/special/compiler_rt/muloti4_test.zig
+++ b/lib/std/special/compiler_rt/muloti4_test.zig
@@ -39,38 +39,38 @@ test "muloti4" {
test__muloti4(2097152, -4398046511103, -9223372036852678656, 0);
test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0);
- test__muloti4(@bitCast(i128, u128(0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, u128(0x000000000000000000B504F333F9DE5B)), @bitCast(i128, u128(0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0);
- test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
- test__muloti4(-2, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, @as(u128, 0x000000000000000000B504F333F9DE5B)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
+ test__muloti4(-2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
- test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -1, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);
- test__muloti4(-1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);
- test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0);
- test__muloti4(0, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0);
- test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
- test__muloti4(1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
- test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
- test__muloti4(2, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
+ test__muloti4(-1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0);
+ test__muloti4(0, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
+ test__muloti4(1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
+ test__muloti4(2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), -2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(-2, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), -1, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(-1, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 0, 0, 0);
- test__muloti4(0, @bitCast(i128, u128(0x80000000000000000000000000000000)), 0, 0);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 1, @bitCast(i128, u128(0x80000000000000000000000000000000)), 0);
- test__muloti4(1, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 0);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(2, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0, 0);
+ test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
+ test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), -2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
- test__muloti4(-2, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), -1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
- test__muloti4(-1, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 0, 0, 0);
- test__muloti4(0, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0, 0);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 1, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);
- test__muloti4(1, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);
- test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
- test__muloti4(2, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
+ test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
+ test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0, 0);
+ test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
+ test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
+ test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
+ test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
}
diff --git a/lib/std/special/compiler_rt/multi3.zig b/lib/std/special/compiler_rt/multi3.zig
index 799b1f575d..f3b74b85d9 100644
--- a/lib/std/special/compiler_rt/multi3.zig
+++ b/lib/std/special/compiler_rt/multi3.zig
@@ -21,7 +21,7 @@ pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 {
fn __mulddi3(a: u64, b: u64) i128 {
const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2;
- const lower_mask = ~u64(0) >> bits_in_dword_2;
+ const lower_mask = ~@as(u64, 0) >> bits_in_dword_2;
var r: twords = undefined;
r.s.low = (a & lower_mask) *% (b & lower_mask);
var t: u64 = r.s.low >> bits_in_dword_2;
diff --git a/lib/std/special/compiler_rt/negXf2.zig b/lib/std/special/compiler_rt/negXf2.zig
index b71a503c1d..c4be085d62 100644
--- a/lib/std/special/compiler_rt/negXf2.zig
+++ b/lib/std/special/compiler_rt/negXf2.zig
@@ -15,7 +15,7 @@ fn negXf2(comptime T: type, a: T) T {
const significandBits = std.math.floatMantissaBits(T);
const exponentBits = std.math.floatExponentBits(T);
- const signBit = (Z(1) << (significandBits + exponentBits));
+ const signBit = (@as(Z, 1) << (significandBits + exponentBits));
return @bitCast(T, @bitCast(Z, a) ^ signBit);
}
diff --git a/lib/std/special/compiler_rt/popcountdi2_test.zig b/lib/std/special/compiler_rt/popcountdi2_test.zig
index bedcbcd1de..fe02786e15 100644
--- a/lib/std/special/compiler_rt/popcountdi2_test.zig
+++ b/lib/std/special/compiler_rt/popcountdi2_test.zig
@@ -20,8 +20,8 @@ test "popcountdi2" {
test__popcountdi2(0);
test__popcountdi2(1);
test__popcountdi2(2);
- test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFD)));
- test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFE)));
- test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFF)));
+ test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFD)));
+ test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFE)));
+ test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFF)));
// TODO some fuzz testing
}
diff --git a/lib/std/special/compiler_rt/truncXfYf2.zig b/lib/std/special/compiler_rt/truncXfYf2.zig
index e4c4aa38a7..d231c0d416 100644
--- a/lib/std/special/compiler_rt/truncXfYf2.zig
+++ b/lib/std/special/compiler_rt/truncXfYf2.zig
@@ -69,7 +69,7 @@ inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
// destination format. We can convert by simply right-shifting with
// rounding and adjusting the exponent.
absResult = @truncate(dst_rep_t, aAbs >> (srcSigBits - dstSigBits));
- absResult -%= dst_rep_t(srcExpBias - dstExpBias) << dstSigBits;
+ absResult -%= @as(dst_rep_t, srcExpBias - dstExpBias) << dstSigBits;
const roundBits: src_rep_t = aAbs & roundMask;
if (roundBits > halfway) {
diff --git a/lib/std/special/compiler_rt/truncXfYf2_test.zig b/lib/std/special/compiler_rt/truncXfYf2_test.zig
index eccf7efb7e..d1dd837ddc 100644
--- a/lib/std/special/compiler_rt/truncXfYf2_test.zig
+++ b/lib/std/special/compiler_rt/truncXfYf2_test.zig
@@ -152,11 +152,11 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
test "trunctfsf2" {
// qnan
- test__trunctfsf2(@bitCast(f128, u128(0x7fff800000000000 << 64)), 0x7fc00000);
+ test__trunctfsf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
// nan
- test__trunctfsf2(@bitCast(f128, u128((0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);
+ test__trunctfsf2(@bitCast(f128, @as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);
// inf
- test__trunctfsf2(@bitCast(f128, u128(0x7fff000000000000 << 64)), 0x7f800000);
+ test__trunctfsf2(@bitCast(f128, @as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
// zero
test__trunctfsf2(0.0, 0x0);
@@ -187,11 +187,11 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
test "trunctfdf2" {
// qnan
- test__trunctfdf2(@bitCast(f128, u128(0x7fff800000000000 << 64)), 0x7ff8000000000000);
+ test__trunctfdf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
// nan
- test__trunctfdf2(@bitCast(f128, u128((0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);
+ test__trunctfdf2(@bitCast(f128, @as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);
// inf
- test__trunctfdf2(@bitCast(f128, u128(0x7fff000000000000 << 64)), 0x7ff0000000000000);
+ test__trunctfdf2(@bitCast(f128, @as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
// zero
test__trunctfdf2(0.0, 0x0);
@@ -224,11 +224,11 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
test "truncdfsf2" {
// nan & qnan
- test__truncdfsf2(@bitCast(f64, u64(0x7ff8000000000000)), 0x7fc00000);
- test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000001)), 0x7fc00000);
+ test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff8000000000000)), 0x7fc00000);
+ test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff0000000000001)), 0x7fc00000);
// inf
- test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000000)), 0x7f800000);
- test__truncdfsf2(@bitCast(f64, u64(0xfff0000000000000)), 0xff800000);
+ test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff0000000000000)), 0x7f800000);
+ test__truncdfsf2(@bitCast(f64, @as(u64, 0xfff0000000000000)), 0xff800000);
test__truncdfsf2(0.0, 0x0);
test__truncdfsf2(1.0, 0x3f800000);
diff --git a/lib/std/special/compiler_rt/udivmod.zig b/lib/std/special/compiler_rt/udivmod.zig
index c3066153f3..96fb7b3bdd 100644
--- a/lib/std/special/compiler_rt/udivmod.zig
+++ b/lib/std/special/compiler_rt/udivmod.zig
@@ -76,7 +76,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
// K K
// ---
// K 0
- sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));
+ sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
// 0 <= sr <= SingleInt.bit_count - 2 or sr large
if (sr > SingleInt.bit_count - 2) {
if (maybe_rem) |rem| {
@@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
// K X
// ---
// 0 K
- sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high]));
+ sr = 1 + SingleInt.bit_count + @as(c_uint, @clz(SingleInt, d[low])) - @as(c_uint, @clz(SingleInt, n[high]));
// 2 <= sr <= DoubleInt.bit_count - 1
// q.all = a << (DoubleInt.bit_count - sr);
// r.all = a >> sr;
@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
// K X
// ---
// K K
- sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));
+ sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
// 0 <= sr <= SingleInt.bit_count - 1 or sr large
if (sr > SingleInt.bit_count - 1) {
if (maybe_rem) |rem| {
diff --git a/lib/std/target.zig b/lib/std/target.zig
index d297312b4e..d84ef47347 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -581,7 +581,7 @@ pub const Target = union(enum) {
};
pub fn getExternalExecutor(self: Target) Executor {
- if (@TagType(Target)(self) == .Native) return .native;
+ if (@as(@TagType(Target),self) == .Native) return .native;
// If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
if (self.getOs() == builtin.os) {
diff --git a/lib/std/thread.zig b/lib/std/thread.zig
index fbfb1afd1e..4e15354055 100644
--- a/lib/std/thread.zig
+++ b/lib/std/thread.zig
@@ -344,7 +344,7 @@ pub const Thread = struct {
pub fn cpuCount() CpuCountError!usize {
if (builtin.os == .linux) {
const cpu_set = try os.sched_getaffinity(0);
- return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
+ return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
}
if (builtin.os == .windows) {
var system_info: windows.SYSTEM_INFO = undefined;
diff --git a/lib/std/time.zig b/lib/std/time.zig
index 04dbb908e2..716c999577 100644
--- a/lib/std/time.zig
+++ b/lib/std/time.zig
@@ -38,7 +38,7 @@ pub fn milliTimestamp() u64 {
const hns_per_ms = (ns_per_s / 100) / ms_per_s;
const epoch_adj = epoch.windows * ms_per_s;
- const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+ const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
return @divFloor(ft64, hns_per_ms) - -epoch_adj;
}
if (builtin.os == .wasi and !builtin.link_libc) {
@@ -142,10 +142,10 @@ pub const Timer = struct {
// seccomp is going to block us it will at least do so consistently
var ts: os.timespec = undefined;
os.clock_getres(monotonic_clock_id, &ts) catch return error.TimerUnsupported;
- self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
+ self.resolution = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
os.clock_gettime(monotonic_clock_id, &ts) catch return error.TimerUnsupported;
- self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
+ self.start_time = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
}
return self;
@@ -185,7 +185,7 @@ pub const Timer = struct {
}
var ts: os.timespec = undefined;
os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
- return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
+ return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
}
};
diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig
index 2e96147166..5509f5f9dd 100644
--- a/lib/std/unicode.zig
+++ b/lib/std/unicode.zig
@@ -68,7 +68,7 @@ const Utf8DecodeError = Utf8Decode2Error || Utf8Decode3Error || Utf8Decode4Error
/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
pub fn utf8Decode(bytes: []const u8) Utf8DecodeError!u32 {
return switch (bytes.len) {
- 1 => u32(bytes[0]),
+ 1 => @as(u32, bytes[0]),
2 => utf8Decode2(bytes),
3 => utf8Decode3(bytes),
4 => utf8Decode4(bytes),
@@ -226,7 +226,7 @@ pub const Utf8Iterator = struct {
const slice = it.nextCodepointSlice() orelse return null;
switch (slice.len) {
- 1 => return u32(slice[0]),
+ 1 => return @as(u32, slice[0]),
2 => return utf8Decode2(slice) catch unreachable,
3 => return utf8Decode3(slice) catch unreachable,
4 => return utf8Decode4(slice) catch unreachable,
@@ -250,15 +250,15 @@ pub const Utf16LeIterator = struct {
assert(it.i <= it.bytes.len);
if (it.i == it.bytes.len) return null;
const c0: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
- if (c0 & ~u32(0x03ff) == 0xd800) {
+ if (c0 & ~@as(u32, 0x03ff) == 0xd800) {
// surrogate pair
it.i += 2;
if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf;
const c1: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
- if (c1 & ~u32(0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf;
+ if (c1 & ~@as(u32, 0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf;
it.i += 2;
return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff));
- } else if (c0 & ~u32(0x03ff) == 0xdc00) {
+ } else if (c0 & ~@as(u32, 0x03ff) == 0xdc00) {
return error.UnexpectedSecondSurrogateHalf;
} else {
it.i += 2;
diff --git a/lib/std/valgrind.zig b/lib/std/valgrind.zig
index 0d7f79dfa2..a8ebbbd8a4 100644
--- a/lib/std/valgrind.zig
+++ b/lib/std/valgrind.zig
@@ -76,7 +76,7 @@ pub const ClientRequest = extern enum {
InnerThreads = 6402,
};
pub fn ToolBase(base: [2]u8) u32 {
- return (u32(base[0] & 0xff) << 24) | (u32(base[1] & 0xff) << 16);
+ return (@as(u32, base[0] & 0xff) << 24) | (@as(u32, base[1] & 0xff) << 16);
}
pub fn IsTool(base: [2]u8, code: usize) bool {
return ToolBase(base) == (code & 0xffff0000);
diff --git a/lib/std/zig/parse_string_literal.zig b/lib/std/zig/parse_string_literal.zig
index acae0b64c7..a6bdff4a02 100644
--- a/lib/std/zig/parse_string_literal.zig
+++ b/lib/std/zig/parse_string_literal.zig
@@ -19,7 +19,7 @@ pub fn parseStringLiteral(
bytes: []const u8,
bad_index: *usize, // populated if error.InvalidCharacter is returned
) ParseStringLiteralError![]u8 {
- const first_index = if (bytes[0] == 'c') usize(2) else usize(1);
+ const first_index = if (bytes[0] == 'c') @as(usize, 2) else @as(usize, 1);
assert(bytes[bytes.len - 1] == '"');
var list = std.ArrayList(u8).init(allocator);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 28bd287c8a..28497ad6f1 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -37,7 +37,7 @@ test "zig fmt: while else err prong with no block" {
\\test "" {
\\ const result = while (returnError()) |value| {
\\ break value;
- \\ } else |err| i32(2);
+ \\ } else |err| @as(i32, 2);
\\ expect(result == 2);
\\}
\\
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 996cfc29e4..81ba8e941c 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -410,8 +410,8 @@ fn renderExpression(
switch (prefix_op_node.op) {
ast.Node.PrefixOp.Op.PtrType => |ptr_info| {
const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) {
- Token.Id.AsteriskAsterisk => usize(1),
- else => usize(0),
+ Token.Id.AsteriskAsterisk => @as(usize, 1),
+ else => @as(usize, 0),
};
try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // *
if (ptr_info.allowzero_token) |allowzero_token| {
@@ -2097,7 +2097,7 @@ fn renderTokenOffset(
while (true) {
assert(loc.line != 0);
- const newline_count = if (loc.line == 1) u8(1) else u8(2);
+ const newline_count = if (loc.line == 1) @as(u8, 1) else @as(u8, 2);
try stream.writeByteNTimes('\n', newline_count);
try stream.writeByteNTimes(' ', indent);
try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index 19488ba873..b401b25ade 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -350,7 +350,7 @@ pub const Tokenizer = struct {
};
} else {
// Skip the UTF-8 BOM if present
- const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else usize(0);
+ const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else @as(usize, 0);
return Tokenizer{
.buffer = buffer,
.index = src_start,
diff --git a/test/compare_output.zig b/test/compare_output.zig
index cbc74c8be2..4c0cc23632 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -122,7 +122,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub fn main() void {
\\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
- \\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
+ \\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", @as(u32, 12), @as(u16, 0x12), @as(u8, 'a')) catch unreachable;
\\}
, "Hello, world!\n 12 12 a\n");
@@ -166,54 +166,54 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ _ = c.printf(c"\n");
\\
\\ _ = c.printf(c"0.0: %.013a\n",
- \\ f64(0.0));
+ \\ @as(f64, 0.0));
\\ _ = c.printf(c"0e0: %.013a\n",
- \\ f64(0e0));
+ \\ @as(f64, 0e0));
\\ _ = c.printf(c"0.0e0: %.013a\n",
- \\ f64(0.0e0));
+ \\ @as(f64, 0.0e0));
\\ _ = c.printf(c"000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
- \\ f64(000000000000000000000000000000000000000000000000000000000.0e0));
+ \\ @as(f64, 000000000000000000000000000000000000000000000000000000000.0e0));
\\ _ = c.printf(c"0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
- \\ f64(0.000000000000000000000000000000000000000000000000000000000e0));
+ \\ @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0));
\\ _ = c.printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
- \\ f64(0.0e000000000000000000000000000000000000000000000000000000000));
+ \\ @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000));
\\ _ = c.printf(c"1.0: %.013a\n",
- \\ f64(1.0));
+ \\ @as(f64, 1.0));
\\ _ = c.printf(c"10.0: %.013a\n",
- \\ f64(10.0));
+ \\ @as(f64, 10.0));
\\ _ = c.printf(c"10.5: %.013a\n",
- \\ f64(10.5));
+ \\ @as(f64, 10.5));
\\ _ = c.printf(c"10.5e5: %.013a\n",
- \\ f64(10.5e5));
+ \\ @as(f64, 10.5e5));
\\ _ = c.printf(c"10.5e+5: %.013a\n",
- \\ f64(10.5e+5));
+ \\ @as(f64, 10.5e+5));
\\ _ = c.printf(c"50.0e-2: %.013a\n",
- \\ f64(50.0e-2));
+ \\ @as(f64, 50.0e-2));
\\ _ = c.printf(c"50e-2: %.013a\n",
- \\ f64(50e-2));
+ \\ @as(f64, 50e-2));
\\
\\ _ = c.printf(c"\n");
\\
\\ _ = c.printf(c"0x1.0: %.013a\n",
- \\ f64(0x1.0));
+ \\ @as(f64, 0x1.0));
\\ _ = c.printf(c"0x10.0: %.013a\n",
- \\ f64(0x10.0));
+ \\ @as(f64, 0x10.0));
\\ _ = c.printf(c"0x100.0: %.013a\n",
- \\ f64(0x100.0));
+ \\ @as(f64, 0x100.0));
\\ _ = c.printf(c"0x103.0: %.013a\n",
- \\ f64(0x103.0));
+ \\ @as(f64, 0x103.0));
\\ _ = c.printf(c"0x103.7: %.013a\n",
- \\ f64(0x103.7));
+ \\ @as(f64, 0x103.7));
\\ _ = c.printf(c"0x103.70: %.013a\n",
- \\ f64(0x103.70));
+ \\ @as(f64, 0x103.70));
\\ _ = c.printf(c"0x103.70p4: %.013a\n",
- \\ f64(0x103.70p4));
+ \\ @as(f64, 0x103.70p4));
\\ _ = c.printf(c"0x103.70p5: %.013a\n",
- \\ f64(0x103.70p5));
+ \\ @as(f64, 0x103.70p5));
\\ _ = c.printf(c"0x103.70p+5: %.013a\n",
- \\ f64(0x103.70p+5));
+ \\ @as(f64, 0x103.70p+5));
\\ _ = c.printf(c"0x103.70p-5: %.013a\n",
- \\ f64(0x103.70p-5));
+ \\ @as(f64, 0x103.70p-5));
\\
\\ return 0;
\\}
@@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ const x: f64 = small;
\\ const y = @floatToInt(i32, x);
\\ const z = @intToFloat(f64, y);
- \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4));
+ \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
\\ return 0;
\\}
, "3.25\n3\n3.00\n-0.40\n");
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 6cdc5d1cda..c7f286ce3f 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -186,7 +186,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"shift amount has to be an integer type",
\\export fn entry() void {
- \\ const x = 1 << &u8(10);
+ \\ const x = 1 << &@as(u8, 10);
\\}
,
"tmp.zig:2:23: error: shift amount has to be an integer type, but found '*u8'",
@@ -196,7 +196,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"bit shifting only works on integer types",
\\export fn entry() void {
- \\ const x = &u8(1) << 10;
+ \\ const x = &@as(u8, 1) << 10;
\\}
,
"tmp.zig:2:18: error: bit shifting operation expected integer type, found '*u8'",
@@ -241,7 +241,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var x: []align(true) i32 = undefined;
\\}
\\export fn entry2() void {
- \\ var x: *align(f64(12.34)) i32 = undefined;
+ \\ var x: *align(@as(f64, 12.34)) i32 = undefined;
\\}
,
"tmp.zig:2:20: error: expected type 'u29', found 'bool'",
@@ -1297,7 +1297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@truncate undefined value",
\\export fn entry() void {
- \\ var z = @truncate(u8, u16(undefined));
+ \\ var z = @truncate(u8, @as(u16, undefined));
\\}
,
"tmp.zig:2:30: error: use of undefined value here causes undefined behavior",
@@ -1686,7 +1686,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"non float passed to @floatToInt",
\\export fn entry() void {
- \\ const x = @floatToInt(i32, i32(54));
+ \\ const x = @floatToInt(i32, @as(i32, 54));
\\}
,
"tmp.zig:2:35: error: expected float type, found 'i32'",
@@ -2197,7 +2197,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"error when evaluating return type",
\\const Foo = struct {
- \\ map: i32(i32),
+ \\ map: @as(i32, i32),
\\
\\ fn init() Foo {
\\ return undefined;
@@ -2338,7 +2338,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"var not allowed in structs",
\\export fn entry() void {
- \\ var s = (struct{v: var}){.v=i32(10)};
+ \\ var s = (struct{v: var}){.v=@as(i32, 10)};
\\}
,
"tmp.zig:2:23: error: invalid token: 'var'",
@@ -2657,7 +2657,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"cast negative integer literal to usize",
\\export fn entry() void {
- \\ const x = usize(-10);
+ \\ const x = @as(usize, -10);
\\}
,
"tmp.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",
@@ -3384,7 +3384,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x : i32 = if (b) h: { break :h 1; };
\\}
\\fn g(b: bool) void {
- \\ const y = if (b) h: { break :h i32(1); };
+ \\ const y = if (b) h: { break :h @as(i32, 1); };
\\}
\\export fn entry() void { f(true); g(true); }
,
@@ -3520,7 +3520,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"cast unreachable",
\\fn f() i32 {
- \\ return i32(return 1);
+ \\ return @as(i32, return 1);
\\}
\\export fn entry() void { _ = f(); }
,
@@ -3595,7 +3595,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ switch (n) {
\\ Number.One => 1,
\\ Number.Two => 2,
- \\ Number.Three => i32(3),
+ \\ Number.Three => @as(i32, 3),
\\ }
\\}
\\
@@ -3616,7 +3616,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ switch (n) {
\\ Number.One => 1,
\\ Number.Two => 2,
- \\ Number.Three => i32(3),
+ \\ Number.Three => @as(i32, 3),
\\ Number.Four => 4,
\\ Number.Two => 2,
\\ }
@@ -3640,7 +3640,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ switch (n) {
\\ Number.One => 1,
\\ Number.Two => 2,
- \\ Number.Three => i32(3),
+ \\ Number.Three => @as(i32, 3),
\\ Number.Four => 4,
\\ Number.Two => 2,
\\ else => 10,
@@ -3685,7 +3685,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"switch expression - duplicate or overlapping integer value",
\\fn foo(x: u8) u8 {
\\ return switch (x) {
- \\ 0 ... 100 => u8(0),
+ \\ 0 ... 100 => @as(u8, 0),
\\ 101 ... 200 => 1,
\\ 201, 203 ... 207 => 2,
\\ 206 ... 255 => 3,
@@ -3722,7 +3722,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"array concatenation with wrong type",
\\const src = "aoeu";
- \\const derp = usize(1234);
+ \\const derp = @as(usize, 1234);
\\const a = derp ++ "foo";
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
@@ -3887,7 +3887,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"division by zero",
\\const lit_int_x = 1 / 0;
\\const lit_float_x = 1.0 / 0.0;
- \\const int_x = u32(1) / u32(0);
+ \\const int_x = @as(u32, 1) / @as(u32, 0);
\\const float_x = f32(1.0) / f32(0.0);
\\
\\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }
@@ -4590,7 +4590,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\var bytes: [ext()]u8 = undefined;
\\export fn f() void {
\\ for (bytes) |*b, i| {
- \\ b.* = u8(i);
+ \\ b.* = @as(u8, i);
\\ }
\\}
,
@@ -4874,7 +4874,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\
\\fn foo() i32 {
- \\ return add(i32(1234));
+ \\ return add(@as(i32, 1234));
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
@@ -4886,7 +4886,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"pass integer literal to var args",
\\fn add(args: ...) i32 {
- \\ var sum = i32(0);
+ \\ var sum = @as(i32, 0);
\\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
\\ sum += args[i];
\\ }}
@@ -5581,7 +5581,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"explicit cast float literal to integer when there is a fraction component",
\\export fn entry() i32 {
- \\ return i32(12.34);
+ \\ return @as(i32, 12.34);
\\}
,
"tmp.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
@@ -5599,7 +5599,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@shlExact shifts out 1 bits",
\\comptime {
- \\ const x = @shlExact(u8(0b01010101), 2);
+ \\ const x = @shlExact(@as(u8, 0b01010101), 2);
\\}
,
"tmp.zig:2:15: error: operation caused overflow",
@@ -5608,7 +5608,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@shrExact shifts out 1 bits",
\\comptime {
- \\ const x = @shrExact(u8(0b10101010), 2);
+ \\ const x = @shrExact(@as(u8, 0b10101010), 2);
\\}
,
"tmp.zig:2:15: error: exact shift shifted out 1 bits",
@@ -5699,7 +5699,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@alignCast expects pointer or slice",
\\export fn entry() void {
- \\ @alignCast(4, u32(3));
+ \\ @alignCast(4, @as(u32, 3));
\\}
,
"tmp.zig:2:22: error: expected pointer or slice, found 'u32'",
@@ -5744,7 +5744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\const Derp = @OpaqueType();
\\extern fn bar(d: *Derp) void;
\\export fn foo() void {
- \\ var x = u8(1);
+ \\ var x = @as(u8, 1);
\\ bar(@ptrCast(*c_void, &x));
\\}
,
@@ -5800,7 +5800,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"wrong types given to atomic order args in cmpxchg",
\\export fn entry() void {
\\ var x: i32 = 1234;
- \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}
+ \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
\\}
,
"tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
@@ -5810,7 +5810,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"wrong types given to @export",
\\extern fn entry() void { }
\\comptime {
- \\ @export("entry", entry, u32(1234));
+ \\ @export("entry", entry, @as(u32, 1234));
\\}
,
"tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 95d2dbac93..49b757451b 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -1,7 +1,7 @@
comptime {
- _ = @import("behavior/align.zig");
+ //_ = @import("behavior/align.zig");
_ = @import("behavior/alignof.zig");
- _ = @import("behavior/array.zig");
+ //_ = @import("behavior/array.zig");
_ = @import("behavior/asm.zig");
_ = @import("behavior/async_fn.zig");
_ = @import("behavior/atomics.zig");
@@ -50,7 +50,7 @@ comptime {
_ = @import("behavior/bugs/920.zig");
_ = @import("behavior/byteswap.zig");
_ = @import("behavior/byval_arg_var.zig");
- _ = @import("behavior/cast.zig");
+ //_ = @import("behavior/cast.zig");
_ = @import("behavior/const_slice_child.zig");
_ = @import("behavior/defer.zig");
_ = @import("behavior/enum.zig");
@@ -59,7 +59,7 @@ comptime {
_ = @import("behavior/eval.zig");
_ = @import("behavior/field_parent_ptr.zig");
_ = @import("behavior/floatop.zig");
- _ = @import("behavior/fn.zig");
+ //_ = @import("behavior/fn.zig");
_ = @import("behavior/fn_in_struct_in_comptime.zig");
_ = @import("behavior/fn_delegation.zig");
_ = @import("behavior/for.zig");
@@ -73,7 +73,7 @@ comptime {
_ = @import("behavior/ir_block_deps.zig");
_ = @import("behavior/math.zig");
_ = @import("behavior/merge_error_sets.zig");
- _ = @import("behavior/misc.zig");
+ //_ = @import("behavior/misc.zig");
_ = @import("behavior/muladd.zig");
_ = @import("behavior/namespace_depends_on_compile_var.zig");
_ = @import("behavior/new_stack_call.zig");
diff --git a/test/stage1/behavior/align.zig b/test/stage1/behavior/align.zig
index bb40270cda..7f9ccaff1e 100644
--- a/test/stage1/behavior/align.zig
+++ b/test/stage1/behavior/align.zig
@@ -7,7 +7,7 @@ var foo: u8 align(4) = 100;
test "global variable alignment" {
expect(@typeOf(&foo).alignment == 4);
expect(@typeOf(&foo) == *align(4) u8);
- const slice = (*[1]u8)(&foo)[0..];
+ const slice = @as(*[1]u8, &foo)[0..];
expect(@typeOf(slice) == []align(4) u8);
}
@@ -61,7 +61,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
test "implicitly decreasing slice alignment" {
const a: u32 align(4) = 3;
const b: u32 align(8) = 4;
- expect(addUnalignedSlice((*const [1]u32)(&a)[0..], (*const [1]u32)(&b)[0..]) == 7);
+ expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7);
}
fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
return a[0] + b[0];
diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig
index 462977066e..f9ca1efdb9 100644
--- a/test/stage1/behavior/array.zig
+++ b/test/stage1/behavior/array.zig
@@ -12,7 +12,7 @@ test "arrays" {
}
i = 0;
- var accumulator = u32(0);
+ var accumulator = @as(u32, 0);
while (i < 5) {
accumulator += array[i];
@@ -149,7 +149,7 @@ test "implicit cast single-item pointer" {
fn testImplicitCastSingleItemPtr() void {
var byte: u8 = 100;
- const slice = (*[1]u8)(&byte)[0..];
+ const slice = @as(*[1]u8, &byte)[0..];
slice[0] += 1;
expect(byte == 101);
}
diff --git a/test/stage1/behavior/asm.zig b/test/stage1/behavior/asm.zig
index 3fe0654a6a..9278d45d5d 100644
--- a/test/stage1/behavior/asm.zig
+++ b/test/stage1/behavior/asm.zig
@@ -45,42 +45,42 @@ test "alternative constraints" {
test "sized integer/float in asm input" {
asm volatile (""
:
- : [_] "m" (usize(3))
+ : [_] "m" (@as(usize, 3))
: ""
);
asm volatile (""
:
- : [_] "m" (i15(-3))
+ : [_] "m" (@as(i15, -3))
: ""
);
asm volatile (""
:
- : [_] "m" (u3(3))
+ : [_] "m" (@as(u3, 3))
: ""
);
asm volatile (""
:
- : [_] "m" (i3(3))
+ : [_] "m" (@as(i3, 3))
: ""
);
asm volatile (""
:
- : [_] "m" (u121(3))
+ : [_] "m" (@as(u121, 3))
: ""
);
asm volatile (""
:
- : [_] "m" (i121(3))
+ : [_] "m" (@as(i121, 3))
: ""
);
asm volatile (""
:
- : [_] "m" (f32(3.17))
+ : [_] "m" (@as(f32, 3.17))
: ""
);
asm volatile (""
:
- : [_] "m" (f64(3.17))
+ : [_] "m" (@as(f64, 3.17))
: ""
);
}
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 8445bcb5b2..99efa0e7be 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -191,7 +191,7 @@ async fn testSuspendBlock() void {
// Test to make sure that @frame() works as advertised (issue #1296)
// var our_handle: anyframe = @frame();
- expect(a_promise == anyframe(@frame()));
+ expect(a_promise == @as(anyframe, @frame()));
global_result = true;
}
@@ -543,7 +543,7 @@ test "pass string literal to async function" {
fn hello(msg: []const u8) void {
frame = @frame();
suspend;
- expectEqual(([]const u8)("hello"), msg);
+ expectEqual(@as([]const u8, "hello"), msg);
ok = true;
}
};
@@ -1048,7 +1048,7 @@ test "using @typeOf on a generic function call" {
return await @asyncCall(frame, {}, amain, x - 1);
}
};
- _ = async S.amain(u32(1));
+ _ = async S.amain(@as(u32, 1));
resume S.global_frame;
expect(S.global_ok);
}
@@ -1080,8 +1080,8 @@ test "recursive call of await @asyncCall with struct return type" {
};
};
var res: S.Foo = undefined;
- var frame: @typeOf(async S.amain(u32(1))) = undefined;
- _ = @asyncCall(&frame, &res, S.amain, u32(1));
+ var frame: @typeOf(async S.amain(@as(u32, 1))) = undefined;
+ _ = @asyncCall(&frame, &res, S.amain, @as(u32, 1));
resume S.global_frame;
expect(S.global_ok);
expect(res.x == 1);
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index 8c4a186032..d49589bdcc 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -98,12 +98,12 @@ test "cmpxchg with ignored result" {
_ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
- expectEqual(i32(5678), x);
+ expectEqual(@as(i32, 5678), x);
}
-var a_global_variable = u32(1234);
+var a_global_variable = @as(u32, 1234);
test "cmpxchg on a global variable" {
_ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
- expectEqual(u32(42), a_global_variable);
+ expectEqual(@as(u32, 42), a_global_variable);
}
diff --git a/test/stage1/behavior/bitreverse.zig b/test/stage1/behavior/bitreverse.zig
index 2b0eb71fb6..8de2d5d2ca 100644
--- a/test/stage1/behavior/bitreverse.zig
+++ b/test/stage1/behavior/bitreverse.zig
@@ -46,24 +46,24 @@ fn testBitReverse() void {
expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
// using comptime_ints, signed, positive
- expect(@bitReverse(u8, u8(0)) == 0);
- expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
- expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
- expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
- expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
- expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
- expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
- expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
- expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
- expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
+ expect(@bitReverse(u8, @as(u8, 0)) == 0);
+ expect(@bitReverse(i8, @bitCast(i8, @as(u8, 0x92))) == @bitCast(i8, @as(u8, 0x49)));
+ expect(@bitReverse(i16, @bitCast(i16, @as(u16, 0x1234))) == @bitCast(i16, @as(u16, 0x2c48)));
+ expect(@bitReverse(i24, @bitCast(i24, @as(u24, 0x123456))) == @bitCast(i24, @as(u24, 0x6a2c48)));
+ expect(@bitReverse(i32, @bitCast(i32, @as(u32, 0x12345678))) == @bitCast(i32, @as(u32, 0x1e6a2c48)));
+ expect(@bitReverse(i40, @bitCast(i40, @as(u40, 0x123456789a))) == @bitCast(i40, @as(u40, 0x591e6a2c48)));
+ expect(@bitReverse(i48, @bitCast(i48, @as(u48, 0x123456789abc))) == @bitCast(i48, @as(u48, 0x3d591e6a2c48)));
+ expect(@bitReverse(i56, @bitCast(i56, @as(u56, 0x123456789abcde))) == @bitCast(i56, @as(u56, 0x7b3d591e6a2c48)));
+ expect(@bitReverse(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1))) == @bitCast(i64, @as(u64, 0x8f7b3d591e6a2c48)));
+ expect(@bitReverse(i128, @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181))) == @bitCast(i128, @as(u128, 0x818e868a828c84888f7b3d591e6a2c48)));
// using signed, negative. Compare to runtime ints returned from llvm.
var neg8: i8 = -18;
- expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8));
+ expect(@bitReverse(i8, @as(i8, -18)) == @bitReverse(i8, neg8));
var neg16: i16 = -32694;
- expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16));
+ expect(@bitReverse(i16, @as(i16, -32694)) == @bitReverse(i16, neg16));
var neg24: i24 = -6773785;
- expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24));
+ expect(@bitReverse(i24, @as(i24, -6773785)) == @bitReverse(i24, neg24));
var neg32: i32 = -16773785;
- expect(@bitReverse(i32, i32(-16773785)) == @bitReverse(i32, neg32));
+ expect(@bitReverse(i32, @as(i32, -16773785)) == @bitReverse(i32, neg32));
}
diff --git a/test/stage1/behavior/bool.zig b/test/stage1/behavior/bool.zig
index dfc2279005..ef9383244e 100644
--- a/test/stage1/behavior/bool.zig
+++ b/test/stage1/behavior/bool.zig
@@ -8,14 +8,14 @@ test "bool literals" {
test "cast bool to int" {
const t = true;
const f = false;
- expect(@boolToInt(t) == u32(1));
- expect(@boolToInt(f) == u32(0));
+ expect(@boolToInt(t) == @as(u32, 1));
+ expect(@boolToInt(f) == @as(u32, 0));
nonConstCastBoolToInt(t, f);
}
fn nonConstCastBoolToInt(t: bool, f: bool) void {
- expect(@boolToInt(t) == u32(1));
- expect(@boolToInt(f) == u32(0));
+ expect(@boolToInt(t) == @as(u32, 1));
+ expect(@boolToInt(f) == @as(u32, 0));
}
test "bool cmp" {
diff --git a/test/stage1/behavior/bugs/1322.zig b/test/stage1/behavior/bugs/1322.zig
index f1d61baa3a..3231a985e7 100644
--- a/test/stage1/behavior/bugs/1322.zig
+++ b/test/stage1/behavior/bugs/1322.zig
@@ -13,7 +13,7 @@ const C = struct {};
test "tagged union with all void fields but a meaningful tag" {
var a: A = A{ .b = B{ .c = C{} } };
- std.testing.expect(@TagType(B)(a.b) == @TagType(B).c);
+ std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).c);
a = A{ .b = B.None };
- std.testing.expect(@TagType(B)(a.b) == @TagType(B).None);
+ std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).None);
}
diff --git a/test/stage1/behavior/bugs/1421.zig b/test/stage1/behavior/bugs/1421.zig
index 48cf1ae2a6..da0ba41680 100644
--- a/test/stage1/behavior/bugs/1421.zig
+++ b/test/stage1/behavior/bugs/1421.zig
@@ -10,5 +10,5 @@ const S = struct {
test "functions with return type required to be comptime are generic" {
const ti = S.method();
- expect(builtin.TypeId(ti) == builtin.TypeId.Struct);
+ expect(@as(builtin.TypeId, ti) == builtin.TypeId.Struct);
}
diff --git a/test/stage1/behavior/bugs/2114.zig b/test/stage1/behavior/bugs/2114.zig
index e266279564..5b664e64ef 100644
--- a/test/stage1/behavior/bugs/2114.zig
+++ b/test/stage1/behavior/bugs/2114.zig
@@ -12,8 +12,8 @@ test "fixed" {
}
fn testClz() void {
- expect(ctz(u128(0x40000000000000000000000000000000)) == 126);
- expect(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1)) == u128(0x80000000000000000000000000000000));
- expect(ctz(u128(0x80000000000000000000000000000000)) == 127);
- expect(ctz(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1))) == 127);
+ expect(ctz(@as(u128, 0x40000000000000000000000000000000)) == 126);
+ expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000));
+ expect(ctz(@as(u128, 0x80000000000000000000000000000000)) == 127);
+ expect(ctz(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127);
}
diff --git a/test/stage1/behavior/bugs/3046.zig b/test/stage1/behavior/bugs/3046.zig
index 709198fd58..b62474f9ba 100644
--- a/test/stage1/behavior/bugs/3046.zig
+++ b/test/stage1/behavior/bugs/3046.zig
@@ -13,7 +13,7 @@ var some_struct: SomeStruct = undefined;
test "fixed" {
some_struct = SomeStruct{
- .field = couldFail() catch |_| i32(0),
+ .field = couldFail() catch |_| @as(i32, 0),
};
expect(some_struct.field == 1);
}
diff --git a/test/stage1/behavior/byteswap.zig b/test/stage1/behavior/byteswap.zig
index 5408b893f5..c799ba4849 100644
--- a/test/stage1/behavior/byteswap.zig
+++ b/test/stage1/behavior/byteswap.zig
@@ -11,24 +11,24 @@ test "@byteSwap integers" {
t(u24, 0x123456, 0x563412);
t(u32, 0x12345678, 0x78563412);
t(u40, 0x123456789a, 0x9a78563412);
- t(i48, 0x123456789abc, @bitCast(i48, u48(0xbc9a78563412)));
+ t(i48, 0x123456789abc, @bitCast(i48, @as(u48, 0xbc9a78563412)));
t(u56, 0x123456789abcde, 0xdebc9a78563412);
t(u64, 0x123456789abcdef1, 0xf1debc9a78563412);
t(u128, 0x123456789abcdef11121314151617181, 0x8171615141312111f1debc9a78563412);
- t(u0, u0(0), 0);
- t(i8, i8(-50), -50);
- t(i16, @bitCast(i16, u16(0x1234)), @bitCast(i16, u16(0x3412)));
- t(i24, @bitCast(i24, u24(0x123456)), @bitCast(i24, u24(0x563412)));
- t(i32, @bitCast(i32, u32(0x12345678)), @bitCast(i32, u32(0x78563412)));
- t(u40, @bitCast(i40, u40(0x123456789a)), u40(0x9a78563412));
- t(i48, @bitCast(i48, u48(0x123456789abc)), @bitCast(i48, u48(0xbc9a78563412)));
- t(i56, @bitCast(i56, u56(0x123456789abcde)), @bitCast(i56, u56(0xdebc9a78563412)));
- t(i64, @bitCast(i64, u64(0x123456789abcdef1)), @bitCast(i64, u64(0xf1debc9a78563412)));
+ t(u0, @as(u0, 0), 0);
+ t(i8, @as(i8, -50), -50);
+ t(i16, @bitCast(i16, @as(u16, 0x1234)), @bitCast(i16, @as(u16, 0x3412)));
+ t(i24, @bitCast(i24, @as(u24, 0x123456)), @bitCast(i24, @as(u24, 0x563412)));
+ t(i32, @bitCast(i32, @as(u32, 0x12345678)), @bitCast(i32, @as(u32, 0x78563412)));
+ t(u40, @bitCast(i40, @as(u40, 0x123456789a)), @as(u40, 0x9a78563412));
+ t(i48, @bitCast(i48, @as(u48, 0x123456789abc)), @bitCast(i48, @as(u48, 0xbc9a78563412)));
+ t(i56, @bitCast(i56, @as(u56, 0x123456789abcde)), @bitCast(i56, @as(u56, 0xdebc9a78563412)));
+ t(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1)), @bitCast(i64, @as(u64, 0xf1debc9a78563412)));
t(
i128,
- @bitCast(i128, u128(0x123456789abcdef11121314151617181)),
- @bitCast(i128, u128(0x8171615141312111f1debc9a78563412)),
+ @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181)),
+ @bitCast(i128, @as(u128, 0x8171615141312111f1debc9a78563412)),
);
}
fn t(comptime I: type, input: I, expected_output: I) void {
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index e5650bc3fc..c4fcbce0c1 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -4,7 +4,7 @@ const mem = std.mem;
const maxInt = std.math.maxInt;
test "int to ptr cast" {
- const x = usize(13);
+ const x = @as(usize, 13);
const y = @intToPtr(*u8, x);
const z = @ptrToInt(y);
expect(z == 13);
@@ -90,7 +90,7 @@ const A = struct {
a: i32,
};
fn castToOptionalTypeError(z: i32) void {
- const x = i32(1);
+ const x = @as(i32, 1);
const y: anyerror!?i32 = x;
expect((try y).? == 1);
@@ -134,10 +134,10 @@ test "peer type resolution: ?T and T" {
}
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
if (c) {
- return if (b) null else usize(0);
+ return if (b) null else @as(usize, 0);
}
- return usize(3);
+ return @as(usize, 3);
}
test "peer type resolution: [0]u8 and []const u8" {
@@ -256,7 +256,7 @@ test "@floatToInt" {
}
fn testFloatToInts() void {
- const x = i32(1e4);
+ const x = @as(i32, 1e4);
expect(x == 10000);
const y = @floatToInt(i32, f32(1e4));
expect(y == 10000);
@@ -442,7 +442,7 @@ fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
}
test "*usize to *void" {
- var i = usize(0);
+ var i = @as(usize, 0);
var v = @ptrCast(*void, &i);
v.* = {};
}
diff --git a/test/stage1/behavior/defer.zig b/test/stage1/behavior/defer.zig
index 6c0e2a432a..5a643609fd 100644
--- a/test/stage1/behavior/defer.zig
+++ b/test/stage1/behavior/defer.zig
@@ -52,7 +52,7 @@ fn testBreakContInDefer(x: usize) void {
}
test "defer and labeled break" {
- var i = usize(0);
+ var i = @as(usize, 0);
blk: {
defer i += 1;
diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig
index 6084dad3cb..f20523487d 100644
--- a/test/stage1/behavior/enum.zig
+++ b/test/stage1/behavior/enum.zig
@@ -788,7 +788,7 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
expect(1234 == switch (x) {
MultipleChoice.A => 1,
MultipleChoice.B => 2,
- MultipleChoice.C => u32(1234),
+ MultipleChoice.C => @as(u32, 1234),
MultipleChoice.D => 4,
});
}
@@ -816,7 +816,7 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
MultipleChoice2.C => 3,
- MultipleChoice2.D => u32(1234),
+ MultipleChoice2.D => @as(u32, 1234),
MultipleChoice2.Unspecified1 => 5,
MultipleChoice2.Unspecified2 => 6,
MultipleChoice2.Unspecified3 => 7,
diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig
index 983f790cbe..8ee1b30907 100644
--- a/test/stage1/behavior/error.zig
+++ b/test/stage1/behavior/error.zig
@@ -51,7 +51,7 @@ test "error binary operator" {
expect(b == 10);
}
fn errBinaryOperatorG(x: bool) anyerror!isize {
- return if (x) error.ItBroke else isize(10);
+ return if (x) error.ItBroke else @as(isize, 10);
}
test "unwrap simple value from error" {
@@ -295,7 +295,7 @@ test "nested error union function call in optional unwrap" {
test "widen cast integer payload of error union function call" {
const S = struct {
fn errorable() !u64 {
- var x = u64(try number());
+ var x = @as(u64, try number());
return x;
}
diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig
index 58d662d768..fa899d0cb2 100644
--- a/test/stage1/behavior/eval.zig
+++ b/test/stage1/behavior/eval.zig
@@ -405,19 +405,19 @@ test "float literal at compile time not lossy" {
}
test "f32 at compile time is lossy" {
- expect(f32(1 << 24) + 1 == 1 << 24);
+ expect(@as(f32, 1 << 24) + 1 == 1 << 24);
}
test "f64 at compile time is lossy" {
- expect(f64(1 << 53) + 1 == 1 << 53);
+ expect(@as(f64, 1 << 53) + 1 == 1 << 53);
}
test "f128 at compile time is lossy" {
- expect(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
+ expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
}
comptime {
- expect(f128(1 << 113) == 10384593717069655257060992658440192);
+ expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192);
}
pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
@@ -434,9 +434,9 @@ test "string literal used as comptime slice is memoized" {
}
test "comptime slice of undefined pointer of length 0" {
- const slice1 = ([*]i32)(undefined)[0..0];
+ const slice1 = @as([*]i32, undefined)[0..0];
expect(slice1.len == 0);
- const slice2 = ([*]i32)(undefined)[100..100];
+ const slice2 = @as([*]i32, undefined)[100..100];
expect(slice2.len == 0);
}
@@ -444,10 +444,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {
comptime var i: usize = 0;
inline while (i < 4) : (i += 1) {
s[i] = 0;
- s[i] |= u32(b[i * 4 + 0]) << 24;
- s[i] |= u32(b[i * 4 + 1]) << 16;
- s[i] |= u32(b[i * 4 + 2]) << 8;
- s[i] |= u32(b[i * 4 + 3]) << 0;
+ s[i] |= @as(u32, b[i * 4 + 0]) << 24;
+ s[i] |= @as(u32, b[i * 4 + 1]) << 16;
+ s[i] |= @as(u32, b[i * 4 + 2]) << 8;
+ s[i] |= @as(u32, b[i * 4 + 3]) << 0;
}
}
@@ -557,14 +557,14 @@ test "array concat of slices gives slice" {
test "comptime shlWithOverflow" {
const ct_shifted: u64 = comptime amt: {
- var amt = u64(0);
- _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
+ var amt = @as(u64, 0);
+ _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt);
break :amt amt;
};
const rt_shifted: u64 = amt: {
- var amt = u64(0);
- _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
+ var amt = @as(u64, 0);
+ _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt);
break :amt amt;
};
@@ -670,7 +670,7 @@ fn loopNTimes(comptime n: usize) void {
}
test "variable inside inline loop that has different types on different iterations" {
- testVarInsideInlineLoop(true, u32(42));
+ testVarInsideInlineLoop(true, @as(u32, 42));
}
fn testVarInsideInlineLoop(args: ...) void {
@@ -757,11 +757,11 @@ test "comptime bitwise operators" {
expect(-3 | -1 == -1);
expect(3 ^ -1 == -4);
expect(-3 ^ -1 == 2);
- expect(~i8(-1) == 0);
- expect(~i128(-1) == 0);
+ expect(~@as(i8, -1) == 0);
+ expect(~@as(i128, -1) == 0);
expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611);
expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);
- expect(~u128(0) == 0xffffffffffffffffffffffffffffffff);
+ expect(~@as(u128, 0) == 0xffffffffffffffffffffffffffffffff);
}
}
diff --git a/test/stage1/behavior/floatop.zig b/test/stage1/behavior/floatop.zig
index de2f6815a6..eb386d75f9 100644
--- a/test/stage1/behavior/floatop.zig
+++ b/test/stage1/behavior/floatop.zig
@@ -117,11 +117,11 @@ test "@ln" {
fn testLn() void {
{
var a: f32 = e;
- expect(@ln(f32, a) == 1 or @ln(f32, a) == @bitCast(f32, u32(0x3f7fffff)));
+ expect(@ln(f32, a) == 1 or @ln(f32, a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
}
{
var a: f64 = e;
- expect(@ln(f64, a) == 1 or @ln(f64, a) == @bitCast(f64, u64(0x3ff0000000000000)));
+ expect(@ln(f64, a) == 1 or @ln(f64, a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
}
}
diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig
index 6b9c8b8fe7..1fc586f39f 100644
--- a/test/stage1/behavior/fn.zig
+++ b/test/stage1/behavior/fn.zig
@@ -29,7 +29,7 @@ test "mutable local variables" {
var zero: i32 = 0;
expect(zero == 0);
- var i = i32(0);
+ var i = @as(i32, 0);
while (i != 3) {
i += 1;
}
@@ -43,7 +43,7 @@ test "separate block scopes" {
}
const c = x: {
- const no_conflict = i32(10);
+ const no_conflict = @as(i32, 10);
break :x no_conflict;
};
expect(c == 10);
diff --git a/test/stage1/behavior/if.zig b/test/stage1/behavior/if.zig
index d299817f46..9e93ceb656 100644
--- a/test/stage1/behavior/if.zig
+++ b/test/stage1/behavior/if.zig
@@ -32,7 +32,7 @@ fn elseIfExpressionF(c: u8) u8 {
} else if (c == 1) {
return 1;
} else {
- return u8(2);
+ return @as(u8, 2);
}
}
@@ -58,7 +58,7 @@ test "labeled break inside comptime if inside runtime if" {
var c = true;
if (c) {
answer = if (true) blk: {
- break :blk i32(42);
+ break :blk @as(i32, 42);
};
}
expect(answer == 42);
diff --git a/test/stage1/behavior/import.zig b/test/stage1/behavior/import.zig
index aa6e9d82ba..2aa2ec4e60 100644
--- a/test/stage1/behavior/import.zig
+++ b/test/stage1/behavior/import.zig
@@ -3,7 +3,7 @@ const expectEqual = @import("std").testing.expectEqual;
const a_namespace = @import("import/a_namespace.zig");
test "call fn via namespace lookup" {
- expectEqual(i32(1234), a_namespace.foo());
+ expectEqual(@as(i32, 1234), a_namespace.foo());
}
test "importing the same thing gives the same import" {
@@ -14,5 +14,5 @@ test "import in non-toplevel scope" {
const S = struct {
usingnamespace @import("import/a_namespace.zig");
};
- expectEqual(i32(1234), S.foo());
+ expectEqual(@as(i32, 1234), S.foo());
}
diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig
index 1ff63e3e23..37a23fa325 100644
--- a/test/stage1/behavior/math.zig
+++ b/test/stage1/behavior/math.zig
@@ -186,9 +186,9 @@ fn testThreeExprInARow(f: bool, t: bool) void {
assertFalse(90 >> 1 >> 2 != 90 >> 3);
assertFalse(100 - 1 + 1000 != 1099);
assertFalse(5 * 4 / 2 % 3 != 1);
- assertFalse(i32(i32(5)) != 5);
+ assertFalse(@as(i32, @as(i32, 5)) != 5);
assertFalse(!!false);
- assertFalse(i32(7) != --(i32(7)));
+ assertFalse(@as(i32, 7) != --(@as(i32, 7)));
}
fn assertFalse(b: bool) void {
expect(!b);
@@ -256,10 +256,10 @@ const DivResult = struct {
test "binary not" {
expect(comptime x: {
- break :x ~u16(0b1010101010101010) == 0b0101010101010101;
+ break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
});
expect(comptime x: {
- break :x ~u64(2147483647) == 18446744071562067968;
+ break :x ~@as(u64, 2147483647) == 18446744071562067968;
});
testBinaryNot(0b1010101010101010);
}
@@ -472,7 +472,7 @@ test "comptime_int multiplication" {
test "comptime_int shifting" {
comptime {
- expect((u128(1) << 127) == 0x80000000000000000000000000000000);
+ expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000);
}
}
@@ -480,13 +480,13 @@ test "comptime_int multi-limb shift and mask" {
comptime {
var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
- expect(u32(a & 0xffffffff) == 0xaaaaaaab);
+ expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab);
a >>= 32;
- expect(u32(a & 0xffffffff) == 0xeeeeeeef);
+ expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef);
a >>= 32;
- expect(u32(a & 0xffffffff) == 0xa0000001);
+ expect(@as(u32, a & 0xffffffff) == 0xa0000001);
a >>= 32;
- expect(u32(a & 0xffffffff) == 0xefffffff);
+ expect(@as(u32, a & 0xffffffff) == 0xefffffff);
a >>= 32;
expect(a == 0);
@@ -552,7 +552,7 @@ fn should_not_be_zero(x: f128) void {
test "comptime float rem int" {
comptime {
- var x = f32(1) % 2;
+ var x = @as(f32, 1) % 2;
expect(x == 1.0);
}
}
@@ -568,8 +568,8 @@ test "remainder division" {
}
fn remdiv(comptime T: type) void {
- expect(T(1) == T(1) % T(2));
- expect(T(1) == T(7) % T(3));
+ expect(@as(T, 1) == @as(T, 1) % @as(T, 2));
+ expect(@as(T, 1) == @as(T, 7) % @as(T, 3));
}
test "@sqrt" {
diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig
index 65ac83bcf0..75bf23622a 100644
--- a/test/stage1/behavior/misc.zig
+++ b/test/stage1/behavior/misc.zig
@@ -268,7 +268,7 @@ fn outer() i64 {
}
test "pointer dereferencing" {
- var x = i32(3);
+ var x = @as(i32, 3);
const y = &x;
y.* += 1;
@@ -500,7 +500,7 @@ fn TypeFromFn(comptime T: type) type {
}
test "double implicit cast in same expression" {
- var x = i32(u16(nine()));
+ var x = @as(i32, @as(u16, nine()));
expect(x == 9);
}
fn nine() u8 {
@@ -761,7 +761,7 @@ test "nested optional field in struct" {
fn maybe(x: bool) anyerror!?u32 {
return switch (x) {
- true => u32(42),
+ true => @as(u32, 42),
else => null,
};
}
diff --git a/test/stage1/behavior/popcount.zig b/test/stage1/behavior/popcount.zig
index 044864cede..884a7bdb6d 100644
--- a/test/stage1/behavior/popcount.zig
+++ b/test/stage1/behavior/popcount.zig
@@ -35,7 +35,7 @@ fn testPopCount() void {
expect(@popCount(i8, x) == 2);
}
comptime {
- expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2);
+ expect(@popCount(u8, @bitCast(u8, @as(i8, -120))) == 2);
}
comptime {
expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
diff --git a/test/stage1/behavior/pub_enum.zig b/test/stage1/behavior/pub_enum.zig
index 6275be7a01..0613df94d9 100644
--- a/test/stage1/behavior/pub_enum.zig
+++ b/test/stage1/behavior/pub_enum.zig
@@ -9,5 +9,5 @@ fn pubEnumTest(foo: other.APubEnum) void {
}
test "cast with imported symbol" {
- expect(other.size_t(42) == 42);
+ expect(@as(other.size_t, 42) == 42);
}
diff --git a/test/stage1/behavior/shuffle.zig b/test/stage1/behavior/shuffle.zig
index a8daf6557a..1985c8dc76 100644
--- a/test/stage1/behavior/shuffle.zig
+++ b/test/stage1/behavior/shuffle.zig
@@ -7,39 +7,39 @@ test "@shuffle" {
fn doTheTest() void {
var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
- const mask: @Vector(4, i32) = [4]i32{ 0, ~i32(2), 3, ~i32(3) };
+ const mask: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) };
var res = @shuffle(i32, v, x, mask);
- expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 40, 4 }));
+ expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 }));
// Implicit cast from array (of mask)
- res = @shuffle(i32, v, x, [4]i32{ 0, ~i32(2), 3, ~i32(3) });
- expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 40, 4 }));
+ res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) });
+ expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 }));
// Undefined
const mask2: @Vector(4, i32) = [4]i32{ 3, 1, 2, 0 };
res = @shuffle(i32, v, undefined, mask2);
- expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 40, -2, 30, 2147483647 }));
+ expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 40, -2, 30, 2147483647 }));
// Upcasting of b
var v2: @Vector(2, i32) = [2]i32{ 2147483647, undefined };
- const mask3: @Vector(4, i32) = [4]i32{ ~i32(0), 2, ~i32(0), 3 };
+ const mask3: @Vector(4, i32) = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 };
res = @shuffle(i32, x, v2, mask3);
- expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 2147483647, 4 }));
+ expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 2147483647, 4 }));
// Upcasting of a
var v3: @Vector(2, i32) = [2]i32{ 2147483647, -2 };
- const mask4: @Vector(4, i32) = [4]i32{ 0, ~i32(2), 1, ~i32(3) };
+ const mask4: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) };
res = @shuffle(i32, v3, x, mask4);
- expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, -2, 4 }));
+ expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, -2, 4 }));
// bool
// Disabled because of #3317
if (@import("builtin").arch != .mipsel) {
var x2: @Vector(4, bool) = [4]bool{ false, true, false, true };
var v4: @Vector(2, bool) = [2]bool{ true, false };
- const mask5: @Vector(4, i32) = [4]i32{ 0, ~i32(1), 1, 2 };
+ const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
var res2 = @shuffle(bool, x2, v4, mask5);
- expect(mem.eql(bool, ([4]bool)(res2), [4]bool{ false, false, true, false }));
+ expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false }));
}
// TODO re-enable when LLVM codegen is fixed
@@ -47,9 +47,9 @@ test "@shuffle" {
if (false) {
var x2: @Vector(3, bool) = [3]bool{ false, true, false };
var v4: @Vector(2, bool) = [2]bool{ true, false };
- const mask5: @Vector(4, i32) = [4]i32{ 0, ~i32(1), 1, 2 };
+ const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
var res2 = @shuffle(bool, x2, v4, mask5);
- expect(mem.eql(bool, ([4]bool)(res2), [4]bool{ false, false, true, false }));
+ expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false }));
}
}
};
diff --git a/test/stage1/behavior/slicetobytes.zig b/test/stage1/behavior/slicetobytes.zig
index b86b38beaf..c0eb4a8f9b 100644
--- a/test/stage1/behavior/slicetobytes.zig
+++ b/test/stage1/behavior/slicetobytes.zig
@@ -10,7 +10,7 @@ test "@sliceToBytes packed struct at runtime and comptime" {
const S = struct {
fn doTheTest() void {
var foo: Foo = undefined;
- var slice = @sliceToBytes(((*[1]Foo)(&foo))[0..1]);
+ var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]);
slice[0] = 0x13;
switch (builtin.endian) {
builtin.Endian.Big => {
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index ede31c0162..76ecad6b43 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -388,8 +388,8 @@ test "runtime struct initialization of bitfield" {
expect(s2.y == @intCast(u4, x2));
}
-var x1 = u4(1);
-var x2 = u8(2);
+var x1 = @as(u4, 1);
+var x2 = @as(u8, 2);
const Nibbles = packed struct {
x: u4,
@@ -545,9 +545,9 @@ test "packed struct with fp fields" {
s.data[1] = 2.0;
s.data[2] = 3.0;
s.frob();
- expectEqual(f32(6.0), s.data[0]);
- expectEqual(f32(11.0), s.data[1]);
- expectEqual(f32(20.0), s.data[2]);
+ expectEqual(@as(f32, 6.0), s.data[0]);
+ expectEqual(@as(f32, 11.0), s.data[1]);
+ expectEqual(@as(f32, 20.0), s.data[2]);
}
test "use within struct scope" {
@@ -558,7 +558,7 @@ test "use within struct scope" {
}
};
};
- expectEqual(i32(42), S.inner());
+ expectEqual(@as(i32, 42), S.inner());
}
test "default struct initialization fields" {
@@ -583,7 +583,7 @@ test "extern fn returns struct by value" {
const S = struct {
fn entry() void {
var x = makeBar(10);
- expectEqual(i32(10), x.handle);
+ expectEqual(@as(i32, 10), x.handle);
}
const ExternBar = extern struct {
@@ -614,7 +614,7 @@ test "for loop over pointers to struct, getting field from struct pointer" {
const ArrayList = struct {
fn toSlice(self: *ArrayList) []*Foo {
- return ([*]*Foo)(undefined)[0..0];
+ return @as([*]*Foo, undefined)[0..0];
}
};
diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig
index 936dbed786..1a18a5c440 100644
--- a/test/stage1/behavior/switch.zig
+++ b/test/stage1/behavior/switch.zig
@@ -68,7 +68,7 @@ test "switch statement" {
}
fn nonConstSwitch(foo: SwitchStatmentFoo) void {
const val = switch (foo) {
- SwitchStatmentFoo.A => i32(1),
+ SwitchStatmentFoo.A => @as(i32, 1),
SwitchStatmentFoo.B => 2,
SwitchStatmentFoo.C => 3,
SwitchStatmentFoo.D => 4,
@@ -127,7 +127,7 @@ test "switch with multiple expressions" {
const x = switch (returnsFive()) {
1, 2, 3 => 1,
4, 5, 6 => 2,
- else => i32(3),
+ else => @as(i32, 3),
};
expect(x == 2);
}
@@ -186,7 +186,7 @@ fn testSwitchHandleAllCases() void {
fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
return switch (x) {
- 0 => u2(3),
+ 0 => @as(u2, 3),
1 => 2,
2 => 1,
3 => 0,
@@ -195,7 +195,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
fn testSwitchHandleAllCasesRange(x: u8) u8 {
return switch (x) {
- 0...100 => u8(0),
+ 0...100 => @as(u8, 0),
101...200 => 1,
201, 203 => 2,
202 => 4,
diff --git a/test/stage1/behavior/try.zig b/test/stage1/behavior/try.zig
index 9c700f6260..9e93183c3b 100644
--- a/test/stage1/behavior/try.zig
+++ b/test/stage1/behavior/try.zig
@@ -8,7 +8,7 @@ test "try on error union" {
fn tryOnErrorUnionImpl() void {
const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
error.ItBroke, error.NoMem => 1,
- error.CrappedOut => i32(2),
+ error.CrappedOut => @as(i32, 2),
else => unreachable,
};
expect(x == 11);
@@ -19,10 +19,10 @@ fn returnsTen() anyerror!i32 {
}
test "try without vars" {
- const result1 = if (failIfTrue(true)) 1 else |_| i32(2);
+ const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2);
expect(result1 == 2);
- const result2 = if (failIfTrue(false)) 1 else |_| i32(2);
+ const result2 = if (failIfTrue(false)) 1 else |_| @as(i32, 2);
expect(result2 == 1);
}
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index aafce2990c..ed64e3e430 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -13,7 +13,7 @@ test "type info: tag type, void info" {
fn testBasic() void {
expect(@TagType(TypeInfo) == TypeId);
const void_info = @typeInfo(void);
- expect(TypeId(void_info) == TypeId.Void);
+ expect(@as(TypeId, void_info) == TypeId.Void);
expect(void_info.Void == {});
}
@@ -24,12 +24,12 @@ test "type info: integer, floating point type info" {
fn testIntFloat() void {
const u8_info = @typeInfo(u8);
- expect(TypeId(u8_info) == TypeId.Int);
+ expect(@as(TypeId, u8_info) == TypeId.Int);
expect(!u8_info.Int.is_signed);
expect(u8_info.Int.bits == 8);
const f64_info = @typeInfo(f64);
- expect(TypeId(f64_info) == TypeId.Float);
+ expect(@as(TypeId, f64_info) == TypeId.Float);
expect(f64_info.Float.bits == 64);
}
@@ -40,7 +40,7 @@ test "type info: pointer type info" {
fn testPointer() void {
const u32_ptr_info = @typeInfo(*u32);
- expect(TypeId(u32_ptr_info) == TypeId.Pointer);
+ expect(@as(TypeId, u32_ptr_info) == TypeId.Pointer);
expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
expect(u32_ptr_info.Pointer.is_const == false);
expect(u32_ptr_info.Pointer.is_volatile == false);
@@ -55,7 +55,7 @@ test "type info: unknown length pointer type info" {
fn testUnknownLenPtr() void {
const u32_ptr_info = @typeInfo([*]const volatile f64);
- expect(TypeId(u32_ptr_info) == TypeId.Pointer);
+ expect(@as(TypeId,u32_ptr_info) == TypeId.Pointer);
expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
expect(u32_ptr_info.Pointer.is_const == true);
expect(u32_ptr_info.Pointer.is_volatile == true);
@@ -70,7 +70,7 @@ test "type info: C pointer type info" {
fn testCPtr() void {
const ptr_info = @typeInfo([*c]align(4) const i8);
- expect(TypeId(ptr_info) == TypeId.Pointer);
+ expect(@as(TypeId,ptr_info) == TypeId.Pointer);
expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);
expect(ptr_info.Pointer.is_const);
expect(!ptr_info.Pointer.is_volatile);
@@ -85,7 +85,7 @@ test "type info: slice type info" {
fn testSlice() void {
const u32_slice_info = @typeInfo([]u32);
- expect(TypeId(u32_slice_info) == TypeId.Pointer);
+ expect(@as(TypeId, u32_slice_info) == TypeId.Pointer);
expect(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
expect(u32_slice_info.Pointer.is_const == false);
expect(u32_slice_info.Pointer.is_volatile == false);
@@ -100,7 +100,7 @@ test "type info: array type info" {
fn testArray() void {
const arr_info = @typeInfo([42]bool);
- expect(TypeId(arr_info) == TypeId.Array);
+ expect(@as(TypeId, arr_info) == TypeId.Array);
expect(arr_info.Array.len == 42);
expect(arr_info.Array.child == bool);
}
@@ -112,7 +112,7 @@ test "type info: optional type info" {
fn testOptional() void {
const null_info = @typeInfo(?void);
- expect(TypeId(null_info) == TypeId.Optional);
+ expect(@as(TypeId, null_info) == TypeId.Optional);
expect(null_info.Optional.child == void);
}
@@ -129,18 +129,18 @@ fn testErrorSet() void {
};
const error_set_info = @typeInfo(TestErrorSet);
- expect(TypeId(error_set_info) == TypeId.ErrorSet);
+ expect(@as(TypeId, error_set_info) == TypeId.ErrorSet);
expect(error_set_info.ErrorSet.?.len == 3);
expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "First"));
expect(error_set_info.ErrorSet.?[2].value == @errorToInt(TestErrorSet.Third));
const error_union_info = @typeInfo(TestErrorSet!usize);
- expect(TypeId(error_union_info) == TypeId.ErrorUnion);
+ expect(@as(TypeId, error_union_info) == TypeId.ErrorUnion);
expect(error_union_info.ErrorUnion.error_set == TestErrorSet);
expect(error_union_info.ErrorUnion.payload == usize);
const global_info = @typeInfo(anyerror);
- expect(TypeId(global_info) == TypeId.ErrorSet);
+ expect(@as(TypeId, global_info) == TypeId.ErrorSet);
expect(global_info.ErrorSet == null);
}
@@ -158,7 +158,7 @@ fn testEnum() void {
};
const os_info = @typeInfo(Os);
- expect(TypeId(os_info) == TypeId.Enum);
+ expect(@as(TypeId, os_info) == TypeId.Enum);
expect(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
expect(os_info.Enum.fields.len == 4);
expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
@@ -174,7 +174,7 @@ test "type info: union info" {
fn testUnion() void {
const typeinfo_info = @typeInfo(TypeInfo);
- expect(TypeId(typeinfo_info) == TypeId.Union);
+ expect(@as(TypeId, typeinfo_info) == TypeId.Union);
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
expect(typeinfo_info.Union.tag_type.? == TypeId);
expect(typeinfo_info.Union.fields.len == 26);
@@ -189,7 +189,7 @@ fn testUnion() void {
};
const notag_union_info = @typeInfo(TestNoTagUnion);
- expect(TypeId(notag_union_info) == TypeId.Union);
+ expect(@as(TypeId, notag_union_info) == TypeId.Union);
expect(notag_union_info.Union.tag_type == null);
expect(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
expect(notag_union_info.Union.fields.len == 2);
@@ -214,7 +214,7 @@ test "type info: struct info" {
fn testStruct() void {
const struct_info = @typeInfo(TestStruct);
- expect(TypeId(struct_info) == TypeId.Struct);
+ expect(@as(TypeId, struct_info) == TypeId.Struct);
expect(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
expect(struct_info.Struct.fields.len == 3);
expect(struct_info.Struct.fields[1].offset == null);
@@ -244,7 +244,7 @@ test "type info: function type info" {
fn testFunction() void {
const fn_info = @typeInfo(@typeOf(foo));
- expect(TypeId(fn_info) == TypeId.Fn);
+ expect(@as(TypeId, fn_info) == TypeId.Fn);
expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
expect(fn_info.Fn.is_generic);
expect(fn_info.Fn.args.len == 2);
@@ -253,7 +253,7 @@ fn testFunction() void {
const test_instance: TestStruct = undefined;
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
- expect(TypeId(bound_fn_info) == TypeId.BoundFn);
+ expect(@as(TypeId, bound_fn_info) == TypeId.BoundFn);
expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
}
@@ -275,7 +275,7 @@ test "type info: vectors" {
fn testVector() void {
const vec_info = @typeInfo(@Vector(4, i32));
- expect(TypeId(vec_info) == TypeId.Vector);
+ expect(@as(TypeId, vec_info) == TypeId.Vector);
expect(vec_info.Vector.len == 4);
expect(vec_info.Vector.child == i32);
}
@@ -288,13 +288,13 @@ test "type info: anyframe and anyframe->T" {
fn testAnyFrame() void {
{
const anyframe_info = @typeInfo(anyframe->i32);
- expect(TypeId(anyframe_info) == .AnyFrame);
+ expect(@as(TypeId,anyframe_info) == .AnyFrame);
expect(anyframe_info.AnyFrame.child.? == i32);
}
{
const anyframe_info = @typeInfo(anyframe);
- expect(TypeId(anyframe_info) == .AnyFrame);
+ expect(@as(TypeId,anyframe_info) == .AnyFrame);
expect(anyframe_info.AnyFrame.child == null);
}
}
@@ -334,7 +334,7 @@ test "type info: extern fns with and without lib names" {
if (std.mem.eql(u8, decl.name, "bar1")) {
expect(decl.data.Fn.lib_name == null);
} else {
- std.testing.expectEqual(([]const u8)("cool"), decl.data.Fn.lib_name.?);
+ std.testing.expectEqual(@as([]const u8,"cool"), decl.data.Fn.lib_name.?);
}
}
}
@@ -342,7 +342,7 @@ test "type info: extern fns with and without lib names" {
test "data field is a compile-time value" {
const S = struct {
- const Bar = isize(-1);
+ const Bar = @as(isize, -1);
};
comptime expect(@typeInfo(S).Struct.decls[0].data.Var == isize);
}
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index 40adf601c4..40af5c4fd4 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -14,7 +14,7 @@ const Agg = struct {
const v1 = Value{ .Int = 1234 };
const v2 = Value{ .Array = [_]u8{3} ** 9 };
-const err = (anyerror!Agg)(Agg{
+const err = @as(anyerror!Agg, Agg{
.val1 = v1,
.val2 = v2,
});
@@ -110,11 +110,11 @@ fn doTest() void {
}
fn bar(value: Payload) i32 {
- expect(Letter(value) == Letter.A);
+ expect(@as(Letter,value) == Letter.A);
return switch (value) {
Payload.A => |x| return x - 1244,
- Payload.B => |x| if (x == 12.34) i32(20) else 21,
- Payload.C => |x| if (x) i32(30) else 31,
+ Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
+ Payload.C => |x| if (x) @as(i32, 30) else 31,
};
}
@@ -127,7 +127,7 @@ const MultipleChoice = union(enum(u32)) {
test "simple union(enum(u32))" {
var x = MultipleChoice.C;
expect(x == MultipleChoice.C);
- expect(@enumToInt(@TagType(MultipleChoice)(x)) == 60);
+ expect(@enumToInt(@as(@TagType(MultipleChoice), x)) == 60);
}
const MultipleChoice2 = union(enum(u32)) {
@@ -149,11 +149,11 @@ test "union(enum(u32)) with specified and unspecified tag values" {
}
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
- expect(@enumToInt(@TagType(MultipleChoice2)(x)) == 60);
+ expect(@enumToInt(@as(@TagType(MultipleChoice2), x)) == 60);
expect(1123 == switch (x) {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
- MultipleChoice2.C => |v| i32(1000) + v,
+ MultipleChoice2.C => |v| @as(i32, 1000) + v,
MultipleChoice2.D => 4,
MultipleChoice2.Unspecified1 => 5,
MultipleChoice2.Unspecified2 => 6,
@@ -208,12 +208,12 @@ test "cast union to tag type of union" {
}
fn testCastUnionToTagType(x: TheUnion) void {
- expect(TheTag(x) == TheTag.B);
+ expect(@as(TheTag,x) == TheTag.B);
}
test "cast tag type of union to union" {
var x: Value2 = Letter2.B;
- expect(Letter2(x) == Letter2.B);
+ expect(@as(Letter2, x) == Letter2.B);
}
const Letter2 = enum {
A,
@@ -297,7 +297,7 @@ const TaggedUnionWithAVoid = union(enum) {
fn testTaggedUnionInit(x: var) bool {
const y = TaggedUnionWithAVoid{ .A = x };
- return @TagType(TaggedUnionWithAVoid)(y) == TaggedUnionWithAVoid.A;
+ return @as(@TagType(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A;
}
pub const UnionEnumNoPayloads = union(enum) {
@@ -326,7 +326,7 @@ test "union with only 1 field casted to its enum type" {
var e = Expr{ .Literal = Literal{ .Bool = true } };
const Tag = @TagType(Expr);
comptime expect(@TagType(Tag) == u0);
- var t = Tag(e);
+ var t = @as(Tag, e);
expect(t == Expr.Literal);
}
@@ -346,7 +346,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
var e = Expr{ .Literal = Literal{ .Bool = true } };
comptime expect(@TagType(Tag) == comptime_int);
- var t = Tag(e);
+ var t = @as(Tag, e);
expect(t == Expr.Literal);
expect(@enumToInt(t) == 33);
comptime expect(@enumToInt(t) == 33);
diff --git a/test/stage1/behavior/var_args.zig b/test/stage1/behavior/var_args.zig
index 191893ff8b..19df436481 100644
--- a/test/stage1/behavior/var_args.zig
+++ b/test/stage1/behavior/var_args.zig
@@ -1,7 +1,7 @@
const expect = @import("std").testing.expect;
fn add(args: ...) i32 {
- var sum = i32(0);
+ var sum = @as(i32, 0);
{
comptime var i: usize = 0;
inline while (i < args.len) : (i += 1) {
@@ -12,8 +12,8 @@ fn add(args: ...) i32 {
}
test "add arbitrary args" {
- expect(add(i32(1), i32(2), i32(3), i32(4)) == 10);
- expect(add(i32(1234)) == 1234);
+ expect(add(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
+ expect(add(@as(i32, 1234)) == 1234);
expect(add() == 0);
}
@@ -26,8 +26,8 @@ test "send void arg to var args" {
}
test "pass args directly" {
- expect(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10);
- expect(addSomeStuff(i32(1234)) == 1234);
+ expect(addSomeStuff(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
+ expect(addSomeStuff(@as(i32, 1234)) == 1234);
expect(addSomeStuff() == 0);
}
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index f747f7c184..f7b98b294f 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -20,11 +20,11 @@ test "vector wrap operators" {
fn doTheTest() void {
var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
- expect(mem.eql(i32, ([4]i32)(v +% x), [4]i32{ -2147483648, 2147483645, 33, 44 }));
- expect(mem.eql(i32, ([4]i32)(v -% x), [4]i32{ 2147483646, 2147483647, 27, 36 }));
- expect(mem.eql(i32, ([4]i32)(v *% x), [4]i32{ 2147483647, 2, 90, 160 }));
+ expect(mem.eql(i32, @as([4]i32, v +% x), [4]i32{ -2147483648, 2147483645, 33, 44 }));
+ expect(mem.eql(i32, @as([4]i32, v -% x), [4]i32{ 2147483646, 2147483647, 27, 36 }));
+ expect(mem.eql(i32, @as([4]i32, v *% x), [4]i32{ 2147483647, 2, 90, 160 }));
var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };
- expect(mem.eql(i32, ([4]i32)(-%z), [4]i32{ -1, -2, -3, -2147483648 }));
+ expect(mem.eql(i32, @as([4]i32, -%z), [4]i32{ -1, -2, -3, -2147483648 }));
}
};
S.doTheTest();
@@ -36,12 +36,12 @@ test "vector bin compares with mem.eql" {
fn doTheTest() void {
var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };
- expect(mem.eql(bool, ([4]bool)(v == x), [4]bool{ false, false, true, false }));
- expect(mem.eql(bool, ([4]bool)(v != x), [4]bool{ true, true, false, true }));
- expect(mem.eql(bool, ([4]bool)(v < x), [4]bool{ false, true, false, false }));
- expect(mem.eql(bool, ([4]bool)(v > x), [4]bool{ true, false, false, true }));
- expect(mem.eql(bool, ([4]bool)(v <= x), [4]bool{ false, true, true, false }));
- expect(mem.eql(bool, ([4]bool)(v >= x), [4]bool{ true, false, true, true }));
+ expect(mem.eql(bool, @as([4]bool, v == x), [4]bool{ false, false, true, false }));
+ expect(mem.eql(bool, @as([4]bool, v != x), [4]bool{ true, true, false, true }));
+ expect(mem.eql(bool, @as([4]bool, v < x), [4]bool{ false, true, false, false }));
+ expect(mem.eql(bool, @as([4]bool, v > x), [4]bool{ true, false, false, true }));
+ expect(mem.eql(bool, @as([4]bool, v <= x), [4]bool{ false, true, true, false }));
+ expect(mem.eql(bool, @as([4]bool, v >= x), [4]bool{ true, false, true, true }));
}
};
S.doTheTest();
@@ -53,10 +53,10 @@ test "vector int operators" {
fn doTheTest() void {
var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
- expect(mem.eql(i32, ([4]i32)(v + x), [4]i32{ 11, 22, 33, 44 }));
- expect(mem.eql(i32, ([4]i32)(v - x), [4]i32{ 9, 18, 27, 36 }));
- expect(mem.eql(i32, ([4]i32)(v * x), [4]i32{ 10, 40, 90, 160 }));
- expect(mem.eql(i32, ([4]i32)(-v), [4]i32{ -10, -20, -30, -40 }));
+ expect(mem.eql(i32, @as([4]i32, v + x), [4]i32{ 11, 22, 33, 44 }));
+ expect(mem.eql(i32, @as([4]i32, v - x), [4]i32{ 9, 18, 27, 36 }));
+ expect(mem.eql(i32, @as([4]i32, v * x), [4]i32{ 10, 40, 90, 160 }));
+ expect(mem.eql(i32, @as([4]i32, -v), [4]i32{ -10, -20, -30, -40 }));
}
};
S.doTheTest();
@@ -68,10 +68,10 @@ test "vector float operators" {
fn doTheTest() void {
var v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 };
var x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 };
- expect(mem.eql(f32, ([4]f32)(v + x), [4]f32{ 11, 22, 33, 44 }));
- expect(mem.eql(f32, ([4]f32)(v - x), [4]f32{ 9, 18, 27, 36 }));
- expect(mem.eql(f32, ([4]f32)(v * x), [4]f32{ 10, 40, 90, 160 }));
- expect(mem.eql(f32, ([4]f32)(-x), [4]f32{ -1, -2, -3, -4 }));
+ expect(mem.eql(f32, @as([4]f32, v + x), [4]f32{ 11, 22, 33, 44 }));
+ expect(mem.eql(f32, @as([4]f32, v - x), [4]f32{ 9, 18, 27, 36 }));
+ expect(mem.eql(f32, @as([4]f32, v * x), [4]f32{ 10, 40, 90, 160 }));
+ expect(mem.eql(f32, @as([4]f32, -x), [4]f32{ -1, -2, -3, -4 }));
}
};
S.doTheTest();
@@ -83,9 +83,9 @@ test "vector bit operators" {
fn doTheTest() void {
var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
- expect(mem.eql(u8, ([4]u8)(v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
- expect(mem.eql(u8, ([4]u8)(v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
- expect(mem.eql(u8, ([4]u8)(v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
+ expect(mem.eql(u8, @as([4]u8, v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
+ expect(mem.eql(u8, @as([4]u8, v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
+ expect(mem.eql(u8, @as([4]u8, v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
}
};
S.doTheTest();
@@ -120,22 +120,22 @@ test "vector casts of sizes not divisable by 8" {
{
var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };
var x: [4]u3 = v;
- expect(mem.eql(u3, x, ([4]u3)(v)));
+ expect(mem.eql(u3, x, @as([4]u3, v)));
}
{
var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };
var x: [4]u2 = v;
- expect(mem.eql(u2, x, ([4]u2)(v)));
+ expect(mem.eql(u2, x, @as([4]u2, v)));
}
{
var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };
var x: [4]u1 = v;
- expect(mem.eql(u1, x, ([4]u1)(v)));
+ expect(mem.eql(u1, x, @as([4]u1, v)));
}
{
var v: @Vector(4, bool) = [4]bool{ false, false, true, false };
var x: [4]bool = v;
- expect(mem.eql(bool, x, ([4]bool)(v)));
+ expect(mem.eql(bool, x, @as([4]bool, v)));
}
}
};
diff --git a/test/stage1/behavior/void.zig b/test/stage1/behavior/void.zig
index 19e879d157..80df9fe4f9 100644
--- a/test/stage1/behavior/void.zig
+++ b/test/stage1/behavior/void.zig
@@ -26,7 +26,7 @@ test "iterate over a void slice" {
}
fn times(n: usize) []const void {
- return ([*]void)(undefined)[0..n];
+ return @as([*]void, undefined)[0..n];
}
test "void optional" {
diff --git a/test/stage1/behavior/while.zig b/test/stage1/behavior/while.zig
index 58ff713c23..0d0ef3a69f 100644
--- a/test/stage1/behavior/while.zig
+++ b/test/stage1/behavior/while.zig
@@ -137,7 +137,7 @@ test "while on optional with else result follow else prong" {
const result = while (returnNull()) |value| {
break value;
} else
- i32(2);
+ @as(i32, 2);
expect(result == 2);
}
@@ -145,7 +145,7 @@ test "while on optional with else result follow break prong" {
const result = while (returnOptional(10)) |value| {
break value;
} else
- i32(2);
+ @as(i32, 2);
expect(result == 10);
}
@@ -153,7 +153,7 @@ test "while on error union with else result follow else prong" {
const result = while (returnError()) |value| {
break value;
} else |err|
- i32(2);
+ @as(i32, 2);
expect(result == 2);
}
@@ -161,23 +161,23 @@ test "while on error union with else result follow break prong" {
const result = while (returnSuccess(10)) |value| {
break value;
} else |err|
- i32(2);
+ @as(i32, 2);
expect(result == 10);
}
test "while on bool with else result follow else prong" {
const result = while (returnFalse()) {
- break i32(10);
+ break @as(i32, 10);
} else
- i32(2);
+ @as(i32, 2);
expect(result == 2);
}
test "while on bool with else result follow break prong" {
const result = while (returnTrue()) {
- break i32(10);
+ break @as(i32, 10);
} else
- i32(2);
+ @as(i32, 2);
expect(result == 10);
}
diff --git a/test/tests.zig b/test/tests.zig
index 84a9c979cd..2bb0f33487 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -411,7 +411,7 @@ pub fn addPkgTests(
const ArchTag = @TagType(builtin.Arch);
if (test_target.disable_native and
test_target.target.getOs() == builtin.os and
- ArchTag(test_target.target.getArch()) == ArchTag(builtin.arch))
+ @as(ArchTag,test_target.target.getArch()) == @as(ArchTag,builtin.arch))
{
continue;
}
@@ -429,7 +429,7 @@ pub fn addPkgTests(
"bare";
const triple_prefix = if (test_target.target == .Native)
- ([]const u8)("native")
+ @as([]const u8,"native")
else
test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;
diff --git a/test/translate_c.zig b/test/translate_c.zig
index a79d12fbfb..54e4131155 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -28,9 +28,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub fn foo() void {
\\ var a: c_int = undefined;
- \\ var b: u8 = u8(123);
+ \\ var b: u8 = @as(u8, 123);
\\ const c: c_int = undefined;
- \\ const d: c_uint = c_uint(440);
+ \\ const d: c_uint = @as(c_uint, 440);
\\}
);
@@ -561,7 +561,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("u integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_uint(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_uint, 32);
);
cases.add("l integer suffix after hex literal",
@@ -676,7 +676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn log2(_arg_a: c_uint) c_int {
\\ var a = _arg_a;
\\ var i: c_int = 0;
- \\ while (a > c_uint(0)) {
+ \\ while (a > @as(c_uint, 0)) {
\\ a >>= @import("std").math.Log2Int(c_uint)(1);
\\ }
\\ return i;
@@ -848,7 +848,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn log2(_arg_a: u32) c_int {
\\ var a = _arg_a;
\\ var i: c_int = 0;
- \\ while (a > c_uint(0)) {
+ \\ while (a > @as(c_uint, 0)) {
\\ a >>= u5(1);
\\ }
\\ return i;
@@ -937,7 +937,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub export fn float_to_int(a: f32) c_int {
- \\ return c_int(a);
+ \\ return @as(c_int, a);
\\}
);
@@ -1103,35 +1103,35 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub export fn foo() void {
- \\ var a: c_uint = c_uint(0);
+ \\ var a: c_uint = @as(c_uint, 0);
\\ a +%= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* +% c_uint(1));
+ \\ _ref.* = (_ref.* +% @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a -%= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* -% c_uint(1));
+ \\ _ref.* = (_ref.* -% @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a *%= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* *% c_uint(1));
+ \\ _ref.* = (_ref.* *% @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a &= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* & c_uint(1));
+ \\ _ref.* = (_ref.* & @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a |= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* | c_uint(1));
+ \\ _ref.* = (_ref.* | @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a ^= (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* ^ c_uint(1));
+ \\ _ref.* = (_ref.* ^ @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a >>= @import("std").math.Log2Int(c_uint)((x: {
@@ -1174,7 +1174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub export fn foo() void {
\\ var i: c_int = 0;
- \\ var u: c_uint = c_uint(0);
+ \\ var u: c_uint = @as(c_uint, 0);
\\ i += 1;
\\ i -= 1;
\\ u +%= 1;
@@ -1222,7 +1222,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub export fn foo() void {
\\ var i: c_int = 0;
- \\ var u: c_uint = c_uint(0);
+ \\ var u: c_uint = @as(c_uint, 0);
\\ i += 1;
\\ i -= 1;
\\ u +%= 1;
@@ -1646,7 +1646,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.addC(
"u integer suffix after 0 (zero) in macro definition",
"#define ZERO 0U",
- "pub const ZERO = c_uint(0);",
+ "pub const ZERO = @as(c_uint, 0);",
);
cases.addC(
@@ -1688,7 +1688,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.addC(
"bitwise not on u-suffixed 0 (zero) in macro definition",
"#define NOT_ZERO (~0U)",
- "pub const NOT_ZERO = ~c_uint(0);",
+ "pub const NOT_ZERO = ~@as(c_uint, 0);",
);
cases.addC("implicit casts",
@@ -1733,9 +1733,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ fn_int(1094861636);
\\ fn_f32(@intToFloat(f32, 3));
\\ fn_f64(@intToFloat(f64, 3));
- \\ fn_char(u8('3'));
- \\ fn_char(u8('\x01'));
- \\ fn_char(u8(0));
+ \\ fn_char(@as(u8, '3'));
+ \\ fn_char(@as(u8, '\x01'));
+ \\ fn_char(@as(u8, 0));
\\ fn_f32(3.000000);
\\ fn_f64(3.000000);
\\ fn_bool(true);
@@ -1798,17 +1798,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\
,
\\pub export fn escapes() [*c]const u8 {
- \\ var a: u8 = u8('\'');
- \\ var b: u8 = u8('\\');
- \\ var c: u8 = u8('\x07');
- \\ var d: u8 = u8('\x08');
- \\ var e: u8 = u8('\x0c');
- \\ var f: u8 = u8('\n');
- \\ var g: u8 = u8('\r');
- \\ var h: u8 = u8('\t');
- \\ var i: u8 = u8('\x0b');
- \\ var j: u8 = u8('\x00');
- \\ var k: u8 = u8('\"');
+ \\ var a: u8 = @as(u8, '\'');
+ \\ var b: u8 = @as(u8, '\\');
+ \\ var c: u8 = @as(u8, '\x07');
+ \\ var d: u8 = @as(u8, '\x08');
+ \\ var e: u8 = @as(u8, '\x0c');
+ \\ var f: u8 = @as(u8, '\n');
+ \\ var g: u8 = @as(u8, '\r');
+ \\ var h: u8 = @as(u8, '\t');
+ \\ var i: u8 = @as(u8, '\x0b');
+ \\ var j: u8 = @as(u8, '\x00');
+ \\ var k: u8 = @as(u8, '\"');
\\ return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
\\}
\\
From fa34dfcce7bfe44840c0cf1ac450c2dc457ce94a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 14:46:48 -0500
Subject: [PATCH 035/129] fix result loc of cast not finding parent
---
src/ir.cpp | 2 +-
test/stage1/behavior.zig | 4 ++--
test/stage1/behavior/misc.zig | 10 +++++-----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index ae5987d030..4ce988e689 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15733,7 +15733,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
casted_value = nullptr;
}
- if (casted_value == nullptr || type_is_invalid(casted_value->value.type)) {
+ if (casted_value != nullptr && type_is_invalid(casted_value->value.type)) {
return casted_value;
}
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 49b757451b..d786090dc1 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -1,5 +1,5 @@
comptime {
- //_ = @import("behavior/align.zig");
+ _ = @import("behavior/align.zig");
_ = @import("behavior/alignof.zig");
//_ = @import("behavior/array.zig");
_ = @import("behavior/asm.zig");
@@ -73,7 +73,7 @@ comptime {
_ = @import("behavior/ir_block_deps.zig");
_ = @import("behavior/math.zig");
_ = @import("behavior/merge_error_sets.zig");
- //_ = @import("behavior/misc.zig");
+ _ = @import("behavior/misc.zig");
_ = @import("behavior/muladd.zig");
_ = @import("behavior/namespace_depends_on_compile_var.zig");
_ = @import("behavior/new_stack_call.zig");
diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig
index 75bf23622a..1a227a5b93 100644
--- a/test/stage1/behavior/misc.zig
+++ b/test/stage1/behavior/misc.zig
@@ -241,14 +241,14 @@ fn memFree(comptime T: type, memory: []T) void {}
test "cast undefined" {
const array: [100]u8 = undefined;
- const slice = ([]const u8)(array);
+ const slice = @as([]const u8, array);
testCastUndefined(slice);
}
fn testCastUndefined(x: []const u8) void {}
test "cast small unsigned to larger signed" {
- expect(castSmallUnsignedToLargerSigned1(200) == i16(200));
- expect(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
+ expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200));
+ expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999));
}
fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
return x;
@@ -350,7 +350,7 @@ fn testTakeAddressOfParameter(f: f32) void {
}
test "pointer comparison" {
- const a = ([]const u8)("a");
+ const a = @as([]const u8, "a");
const b = &a;
expect(ptrEql(b, b));
}
@@ -642,7 +642,7 @@ test "self reference through fn ptr field" {
test "volatile load and store" {
var number: i32 = 1234;
- const ptr = (*volatile i32)(&number);
+ const ptr = @as(*volatile i32, &number);
ptr.* += 1;
expect(ptr.* == 1235);
}
From 8954a1bae5540b390188ee728a13a5d33957546e Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 17:14:31 -0500
Subject: [PATCH 036/129] more regressions fixed
---
src/ir.cpp | 47 +++++++++++++++++++++++------------
test/stage1/behavior.zig | 4 +--
test/stage1/behavior/cast.zig | 12 ++++-----
3 files changed, 39 insertions(+), 24 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 4ce988e689..f7bfba6a99 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15537,6 +15537,26 @@ static bool ir_result_has_type(ResultLoc *result_loc) {
zig_unreachable();
}
+static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr,
+ ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime)
+{
+ Error err;
+
+ IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
+ if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
+ alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
+ PtrLenSingle, 0, 0, 0, false);
+ set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
+ ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
+ if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
+ fn_entry->alloca_gen_list.append(alloca_gen);
+ }
+ result_loc->written = true;
+ result_loc->resolved_loc = &alloca_gen->base;
+ return result_loc->resolved_loc;
+}
+
// when calling this function, at the callsite must check for result type noreturn and propagate it up
static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime)
@@ -15559,19 +15579,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
return nullptr;
}
// need to return a result location and don't have one. use a stack allocation
- IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
- if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))
- return ira->codegen->invalid_instruction;
- alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
- PtrLenSingle, 0, 0, 0, false);
- set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
- fn_entry->alloca_gen_list.append(alloca_gen);
- }
- result_loc->written = true;
- result_loc->resolved_loc = &alloca_gen->base;
- return result_loc->resolved_loc;
+ return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
+ force_runtime, non_null_comptime);
}
case ResultLocIdVar: {
ResultLocVar *result_loc_var = reinterpret_cast(result_loc);
@@ -15710,6 +15719,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
return result_loc->resolved_loc;
}
case ResultLocIdCast: {
+ if (!non_null_comptime && value != nullptr && value->value.special != ConstValSpecialRuntime)
+ return nullptr;
ResultLocCast *result_cast = reinterpret_cast(result_loc);
ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
if (type_is_invalid(dest_type))
@@ -15720,9 +15731,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
if (const_cast_result.id == ConstCastResultIdInvalid)
return ira->codegen->invalid_instruction;
if (const_cast_result.id != ConstCastResultIdOk) {
- // We will not be able to provide a result location for this value. Allow the
- // code to create a new result location and then type coerce to the old one.
- return nullptr;
+ // We will not be able to provide a result location for this value. Create
+ // a new result location.
+ return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
+ force_runtime, non_null_comptime);
}
// In this case we can pointer cast the result location.
@@ -15755,6 +15767,9 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) {
return ira->codegen->invalid_instruction;
}
+ if (!type_has_bits(value_type)) {
+ parent_ptr_align = 0;
+ }
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type,
parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index d786090dc1..d0d38d844d 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -1,7 +1,7 @@
comptime {
_ = @import("behavior/align.zig");
_ = @import("behavior/alignof.zig");
- //_ = @import("behavior/array.zig");
+ _ = @import("behavior/array.zig");
_ = @import("behavior/asm.zig");
_ = @import("behavior/async_fn.zig");
_ = @import("behavior/atomics.zig");
@@ -50,7 +50,7 @@ comptime {
_ = @import("behavior/bugs/920.zig");
_ = @import("behavior/byteswap.zig");
_ = @import("behavior/byval_arg_var.zig");
- //_ = @import("behavior/cast.zig");
+ _ = @import("behavior/cast.zig");
_ = @import("behavior/const_slice_child.zig");
_ = @import("behavior/defer.zig");
_ = @import("behavior/enum.zig");
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index c4fcbce0c1..98d987a73f 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -75,8 +75,8 @@ test "peer resolve array and const slice" {
comptime testPeerResolveArrayConstSlice(true);
}
fn testPeerResolveArrayConstSlice(b: bool) void {
- const value1 = if (b) "aoeu" else ([]const u8)("zz");
- const value2 = if (b) ([]const u8)("zz") else "aoeu";
+ const value1 = if (b) "aoeu" else @as([]const u8, "zz");
+ const value2 = if (b) @as([]const u8, "zz") else "aoeu";
expect(mem.eql(u8, value1, "aoeu"));
expect(mem.eql(u8, value2, "zz"));
}
@@ -258,7 +258,7 @@ test "@floatToInt" {
fn testFloatToInts() void {
const x = @as(i32, 1e4);
expect(x == 10000);
- const y = @floatToInt(i32, f32(1e4));
+ const y = @floatToInt(i32, @as(f32, 1e4));
expect(y == 10000);
expectFloatToInt(f16, 255.1, u8, 255);
expectFloatToInt(f16, 127.2, i8, 127);
@@ -392,7 +392,7 @@ fn MakeType(comptime T: type) type {
}
fn getNonNull() ?T {
- return T(undefined);
+ return @as(T, undefined);
}
};
}
@@ -535,12 +535,12 @@ test "peer type resolution: unreachable, error set, unreachable" {
}
test "implicit cast comptime_int to comptime_float" {
- comptime expect(comptime_float(10) == f32(10));
+ comptime expect(@as(comptime_float, 10) == @as(f32, 10));
expect(2 == 2.0);
}
test "implicit cast *[0]T to E![]const u8" {
- var x = (anyerror![]const u8)(&[0]u8{});
+ var x = @as(anyerror![]const u8, &[0]u8{});
expect((x catch unreachable).len == 0);
}
From a2acc2787242fdee189ec4197c0dd847b8245139 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 18:13:17 -0500
Subject: [PATCH 037/129] behavior tests passing
---
src/ir.cpp | 4 ++++
test/stage1/behavior.zig | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index f7bfba6a99..148be3b507 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -17542,6 +17542,10 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) {
if (peer_parent->parent->id == ResultLocIdReturn) {
resolved_type = ira->explicit_return_type;
+ } else if (peer_parent->parent->id == ResultLocIdCast) {
+ resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
+ if (type_is_invalid(resolved_type))
+ return ira->codegen->invalid_instruction;
} else {
ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index d0d38d844d..95d2dbac93 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -59,7 +59,7 @@ comptime {
_ = @import("behavior/eval.zig");
_ = @import("behavior/field_parent_ptr.zig");
_ = @import("behavior/floatop.zig");
- //_ = @import("behavior/fn.zig");
+ _ = @import("behavior/fn.zig");
_ = @import("behavior/fn_in_struct_in_comptime.zig");
_ = @import("behavior/fn_delegation.zig");
_ = @import("behavior/for.zig");
From aa0daea5415dd2a20e4d7c2fd047b7bcee6c9ea4 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 18:52:09 -0500
Subject: [PATCH 038/129] update more of the std lib to use `@as`
---
lib/std/bloom_filter.zig | 16 ++++++------
lib/std/crypto/x25519.zig | 46 ++++++++++++++++-----------------
lib/std/debug/leb128.zig | 2 +-
lib/std/fmt.zig | 22 ++++++++--------
lib/std/fmt/parse_float.zig | 6 ++---
lib/std/heap.zig | 4 +--
lib/std/io.zig | 26 +++++++++----------
lib/std/io/test.zig | 24 ++++++++---------
lib/std/lazy_init.zig | 2 +-
lib/std/math.zig | 24 ++++++++---------
lib/std/math/big/int.zig | 20 +++++++-------
lib/std/math/complex.zig | 8 +++---
lib/std/math/complex/acos.zig | 2 +-
lib/std/math/complex/ldexp.zig | 2 +-
lib/std/math/exp.zig | 2 +-
lib/std/math/ln.zig | 2 +-
lib/std/math/log.zig | 4 +--
lib/std/math/log10.zig | 2 +-
lib/std/math/sqrt.zig | 4 +--
lib/std/meta.zig | 2 +-
lib/std/net.zig | 8 +++---
lib/std/os/linux/test.zig | 6 ++---
lib/std/packed_int_array.zig | 18 ++++++-------
lib/std/rand.zig | 8 +++---
lib/std/unicode.zig | 16 ++++++------
src-self-hosted/stage1.zig | 2 +-
src-self-hosted/translate_c.zig | 2 +-
test/compile_errors.zig | 10 +++----
28 files changed, 145 insertions(+), 145 deletions(-)
diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig
index 2734e7d54f..6c4d713076 100644
--- a/lib/std/bloom_filter.zig
+++ b/lib/std/bloom_filter.zig
@@ -28,7 +28,7 @@ pub fn BloomFilter(
assert(n_items > 0);
assert(math.isPowerOfTwo(n_items));
assert(K > 0);
- const cellEmpty = if (Cell == bool) false else Cell(0);
+ const cellEmpty = if (Cell == bool) false else @as(Cell, 0);
const cellMax = if (Cell == bool) true else math.maxInt(Cell);
const n_bytes = (n_items * comptime std.meta.bitCount(Cell)) / 8;
assert(n_bytes > 0);
@@ -137,7 +137,7 @@ pub fn BloomFilter(
var i: usize = 0;
while (i < n_items) : (i += 1) {
const cell = self.getCell(@intCast(Index, i));
- n += if (if (Cell == bool) cell else cell > 0) Index(1) else Index(0);
+ n += if (if (Cell == bool) cell else cell > 0) @as(Index, 1) else @as(Index, 0);
}
}
return n;
@@ -161,7 +161,7 @@ fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {
test "std.BloomFilter" {
inline for ([_]type{ bool, u1, u2, u3, u4 }) |Cell| {
- const emptyCell = if (Cell == bool) false else Cell(0);
+ const emptyCell = if (Cell == bool) false else @as(Cell, 0);
const BF = BloomFilter(128 * 8, 8, Cell, builtin.endian, hashFunc);
var bf = BF{};
var i: usize = undefined;
@@ -170,7 +170,7 @@ test "std.BloomFilter" {
while (i < BF.items) : (i += 1) {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
- testing.expectEqual(BF.Index(0), bf.popCount());
+ testing.expectEqual(@as(BF.Index, 0), bf.popCount());
testing.expectEqual(@as(f64, 0), bf.estimateItems());
// fill in a few items
bf.incrementCell(42);
@@ -196,7 +196,7 @@ test "std.BloomFilter" {
while (i < BF.items) : (i += 1) {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
- testing.expectEqual(BF.Index(0), bf.popCount());
+ testing.expectEqual(@as(BF.Index, 0), bf.popCount());
testing.expectEqual(@as(f64, 0), bf.estimateItems());
// Lets add a string
@@ -218,7 +218,7 @@ test "std.BloomFilter" {
while (i < BF.items) : (i += 1) {
testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
}
- testing.expectEqual(BF.Index(0), bf.popCount());
+ testing.expectEqual(@as(BF.Index, 0), bf.popCount());
testing.expectEqual(@as(f64, 0), bf.estimateItems());
comptime var teststrings = [_][]const u8{
@@ -246,12 +246,12 @@ test "std.BloomFilter" {
inline for (teststrings) |str| {
testing.expectEqual(true, larger_bf.contains(str));
}
- testing.expectEqual(u12(bf.popCount()) * (4096 / 1024), larger_bf.popCount());
+ testing.expectEqual(@as(u12, bf.popCount()) * (4096 / 1024), larger_bf.popCount());
const smaller_bf = bf.resize(64);
inline for (teststrings) |str| {
testing.expectEqual(true, smaller_bf.contains(str));
}
- testing.expect(bf.popCount() <= u10(smaller_bf.popCount()) * (1024 / 64));
+ testing.expect(bf.popCount() <= @as(u10, smaller_bf.popCount()) * (1024 / 64));
}
}
diff --git a/lib/std/crypto/x25519.zig b/lib/std/crypto/x25519.zig
index 223d65f8f4..cd908b0868 100644
--- a/lib/std/crypto/x25519.zig
+++ b/lib/std/crypto/x25519.zig
@@ -199,9 +199,9 @@ const Fe = struct {
inline fn carryRound(c: []i64, t: []i64, comptime i: comptime_int, comptime shift: comptime_int, comptime mult: comptime_int) void {
const j = (i + 1) % 10;
- c[i] = (t[i] + (i64(1) << shift)) >> (shift + 1);
+ c[i] = (t[i] + (@as(i64, 1) << shift)) >> (shift + 1);
t[j] += c[i] * mult;
- t[i] -= c[i] * (i64(1) << (shift + 1));
+ t[i] -= c[i] * (@as(i64, 1) << (shift + 1));
}
fn carry1(h: *Fe, t: []i64) void {
@@ -273,7 +273,7 @@ const Fe = struct {
var t: [10]i64 = undefined;
for (t[0..]) |_, i| {
- t[i] = i64(f.b[i]) * g;
+ t[i] = @as(i64, f.b[i]) * g;
}
carry1(h, t[0..]);
@@ -305,16 +305,16 @@ const Fe = struct {
// t's become h
var t: [10]i64 = undefined;
- t[0] = f[0] * i64(g[0]) + F[1] * i64(G[9]) + f[2] * i64(G[8]) + F[3] * i64(G[7]) + f[4] * i64(G[6]) + F[5] * i64(G[5]) + f[6] * i64(G[4]) + F[7] * i64(G[3]) + f[8] * i64(G[2]) + F[9] * i64(G[1]);
- t[1] = f[0] * i64(g[1]) + f[1] * i64(g[0]) + f[2] * i64(G[9]) + f[3] * i64(G[8]) + f[4] * i64(G[7]) + f[5] * i64(G[6]) + f[6] * i64(G[5]) + f[7] * i64(G[4]) + f[8] * i64(G[3]) + f[9] * i64(G[2]);
- t[2] = f[0] * i64(g[2]) + F[1] * i64(g[1]) + f[2] * i64(g[0]) + F[3] * i64(G[9]) + f[4] * i64(G[8]) + F[5] * i64(G[7]) + f[6] * i64(G[6]) + F[7] * i64(G[5]) + f[8] * i64(G[4]) + F[9] * i64(G[3]);
- t[3] = f[0] * i64(g[3]) + f[1] * i64(g[2]) + f[2] * i64(g[1]) + f[3] * i64(g[0]) + f[4] * i64(G[9]) + f[5] * i64(G[8]) + f[6] * i64(G[7]) + f[7] * i64(G[6]) + f[8] * i64(G[5]) + f[9] * i64(G[4]);
- t[4] = f[0] * i64(g[4]) + F[1] * i64(g[3]) + f[2] * i64(g[2]) + F[3] * i64(g[1]) + f[4] * i64(g[0]) + F[5] * i64(G[9]) + f[6] * i64(G[8]) + F[7] * i64(G[7]) + f[8] * i64(G[6]) + F[9] * i64(G[5]);
- t[5] = f[0] * i64(g[5]) + f[1] * i64(g[4]) + f[2] * i64(g[3]) + f[3] * i64(g[2]) + f[4] * i64(g[1]) + f[5] * i64(g[0]) + f[6] * i64(G[9]) + f[7] * i64(G[8]) + f[8] * i64(G[7]) + f[9] * i64(G[6]);
- t[6] = f[0] * i64(g[6]) + F[1] * i64(g[5]) + f[2] * i64(g[4]) + F[3] * i64(g[3]) + f[4] * i64(g[2]) + F[5] * i64(g[1]) + f[6] * i64(g[0]) + F[7] * i64(G[9]) + f[8] * i64(G[8]) + F[9] * i64(G[7]);
- t[7] = f[0] * i64(g[7]) + f[1] * i64(g[6]) + f[2] * i64(g[5]) + f[3] * i64(g[4]) + f[4] * i64(g[3]) + f[5] * i64(g[2]) + f[6] * i64(g[1]) + f[7] * i64(g[0]) + f[8] * i64(G[9]) + f[9] * i64(G[8]);
- t[8] = f[0] * i64(g[8]) + F[1] * i64(g[7]) + f[2] * i64(g[6]) + F[3] * i64(g[5]) + f[4] * i64(g[4]) + F[5] * i64(g[3]) + f[6] * i64(g[2]) + F[7] * i64(g[1]) + f[8] * i64(g[0]) + F[9] * i64(G[9]);
- t[9] = f[0] * i64(g[9]) + f[1] * i64(g[8]) + f[2] * i64(g[7]) + f[3] * i64(g[6]) + f[4] * i64(g[5]) + f[5] * i64(g[4]) + f[6] * i64(g[3]) + f[7] * i64(g[2]) + f[8] * i64(g[1]) + f[9] * i64(g[0]);
+ t[0] = f[0] * @as(i64, g[0]) + F[1] * @as(i64, G[9]) + f[2] * @as(i64, G[8]) + F[3] * @as(i64, G[7]) + f[4] * @as(i64, G[6]) + F[5] * @as(i64, G[5]) + f[6] * @as(i64, G[4]) + F[7] * @as(i64, G[3]) + f[8] * @as(i64, G[2]) + F[9] * @as(i64, G[1]);
+ t[1] = f[0] * @as(i64, g[1]) + f[1] * @as(i64, g[0]) + f[2] * @as(i64, G[9]) + f[3] * @as(i64, G[8]) + f[4] * @as(i64, G[7]) + f[5] * @as(i64, G[6]) + f[6] * @as(i64, G[5]) + f[7] * @as(i64, G[4]) + f[8] * @as(i64, G[3]) + f[9] * @as(i64, G[2]);
+ t[2] = f[0] * @as(i64, g[2]) + F[1] * @as(i64, g[1]) + f[2] * @as(i64, g[0]) + F[3] * @as(i64, G[9]) + f[4] * @as(i64, G[8]) + F[5] * @as(i64, G[7]) + f[6] * @as(i64, G[6]) + F[7] * @as(i64, G[5]) + f[8] * @as(i64, G[4]) + F[9] * @as(i64, G[3]);
+ t[3] = f[0] * @as(i64, g[3]) + f[1] * @as(i64, g[2]) + f[2] * @as(i64, g[1]) + f[3] * @as(i64, g[0]) + f[4] * @as(i64, G[9]) + f[5] * @as(i64, G[8]) + f[6] * @as(i64, G[7]) + f[7] * @as(i64, G[6]) + f[8] * @as(i64, G[5]) + f[9] * @as(i64, G[4]);
+ t[4] = f[0] * @as(i64, g[4]) + F[1] * @as(i64, g[3]) + f[2] * @as(i64, g[2]) + F[3] * @as(i64, g[1]) + f[4] * @as(i64, g[0]) + F[5] * @as(i64, G[9]) + f[6] * @as(i64, G[8]) + F[7] * @as(i64, G[7]) + f[8] * @as(i64, G[6]) + F[9] * @as(i64, G[5]);
+ t[5] = f[0] * @as(i64, g[5]) + f[1] * @as(i64, g[4]) + f[2] * @as(i64, g[3]) + f[3] * @as(i64, g[2]) + f[4] * @as(i64, g[1]) + f[5] * @as(i64, g[0]) + f[6] * @as(i64, G[9]) + f[7] * @as(i64, G[8]) + f[8] * @as(i64, G[7]) + f[9] * @as(i64, G[6]);
+ t[6] = f[0] * @as(i64, g[6]) + F[1] * @as(i64, g[5]) + f[2] * @as(i64, g[4]) + F[3] * @as(i64, g[3]) + f[4] * @as(i64, g[2]) + F[5] * @as(i64, g[1]) + f[6] * @as(i64, g[0]) + F[7] * @as(i64, G[9]) + f[8] * @as(i64, G[8]) + F[9] * @as(i64, G[7]);
+ t[7] = f[0] * @as(i64, g[7]) + f[1] * @as(i64, g[6]) + f[2] * @as(i64, g[5]) + f[3] * @as(i64, g[4]) + f[4] * @as(i64, g[3]) + f[5] * @as(i64, g[2]) + f[6] * @as(i64, g[1]) + f[7] * @as(i64, g[0]) + f[8] * @as(i64, G[9]) + f[9] * @as(i64, G[8]);
+ t[8] = f[0] * @as(i64, g[8]) + F[1] * @as(i64, g[7]) + f[2] * @as(i64, g[6]) + F[3] * @as(i64, g[5]) + f[4] * @as(i64, g[4]) + F[5] * @as(i64, g[3]) + f[6] * @as(i64, g[2]) + F[7] * @as(i64, g[1]) + f[8] * @as(i64, g[0]) + F[9] * @as(i64, G[9]);
+ t[9] = f[0] * @as(i64, g[9]) + f[1] * @as(i64, g[8]) + f[2] * @as(i64, g[7]) + f[3] * @as(i64, g[6]) + f[4] * @as(i64, g[5]) + f[5] * @as(i64, g[4]) + f[6] * @as(i64, g[3]) + f[7] * @as(i64, g[2]) + f[8] * @as(i64, g[1]) + f[9] * @as(i64, g[0]);
carry2(h, t[0..]);
}
@@ -348,16 +348,16 @@ const Fe = struct {
var t: [10]i64 = undefined;
- t[0] = f0 * i64(f0) + f1_2 * i64(f9_38) + f2_2 * i64(f8_19) + f3_2 * i64(f7_38) + f4_2 * i64(f6_19) + f5 * i64(f5_38);
- t[1] = f0_2 * i64(f1) + f2 * i64(f9_38) + f3_2 * i64(f8_19) + f4 * i64(f7_38) + f5_2 * i64(f6_19);
- t[2] = f0_2 * i64(f2) + f1_2 * i64(f1) + f3_2 * i64(f9_38) + f4_2 * i64(f8_19) + f5_2 * i64(f7_38) + f6 * i64(f6_19);
- t[3] = f0_2 * i64(f3) + f1_2 * i64(f2) + f4 * i64(f9_38) + f5_2 * i64(f8_19) + f6 * i64(f7_38);
- t[4] = f0_2 * i64(f4) + f1_2 * i64(f3_2) + f2 * i64(f2) + f5_2 * i64(f9_38) + f6_2 * i64(f8_19) + f7 * i64(f7_38);
- t[5] = f0_2 * i64(f5) + f1_2 * i64(f4) + f2_2 * i64(f3) + f6 * i64(f9_38) + f7_2 * i64(f8_19);
- t[6] = f0_2 * i64(f6) + f1_2 * i64(f5_2) + f2_2 * i64(f4) + f3_2 * i64(f3) + f7_2 * i64(f9_38) + f8 * i64(f8_19);
- t[7] = f0_2 * i64(f7) + f1_2 * i64(f6) + f2_2 * i64(f5) + f3_2 * i64(f4) + f8 * i64(f9_38);
- t[8] = f0_2 * i64(f8) + f1_2 * i64(f7_2) + f2_2 * i64(f6) + f3_2 * i64(f5_2) + f4 * i64(f4) + f9 * i64(f9_38);
- t[9] = f0_2 * i64(f9) + f1_2 * i64(f8) + f2_2 * i64(f7) + f3_2 * i64(f6) + f4 * i64(f5_2);
+ t[0] = f0 * @as(i64, f0) + f1_2 * @as(i64, f9_38) + f2_2 * @as(i64, f8_19) + f3_2 * @as(i64, f7_38) + f4_2 * @as(i64, f6_19) + f5 * @as(i64, f5_38);
+ t[1] = f0_2 * @as(i64, f1) + f2 * @as(i64, f9_38) + f3_2 * @as(i64, f8_19) + f4 * @as(i64, f7_38) + f5_2 * @as(i64, f6_19);
+ t[2] = f0_2 * @as(i64, f2) + f1_2 * @as(i64, f1) + f3_2 * @as(i64, f9_38) + f4_2 * @as(i64, f8_19) + f5_2 * @as(i64, f7_38) + f6 * @as(i64, f6_19);
+ t[3] = f0_2 * @as(i64, f3) + f1_2 * @as(i64, f2) + f4 * @as(i64, f9_38) + f5_2 * @as(i64, f8_19) + f6 * @as(i64, f7_38);
+ t[4] = f0_2 * @as(i64, f4) + f1_2 * @as(i64, f3_2) + f2 * @as(i64, f2) + f5_2 * @as(i64, f9_38) + f6_2 * @as(i64, f8_19) + f7 * @as(i64, f7_38);
+ t[5] = f0_2 * @as(i64, f5) + f1_2 * @as(i64, f4) + f2_2 * @as(i64, f3) + f6 * @as(i64, f9_38) + f7_2 * @as(i64, f8_19);
+ t[6] = f0_2 * @as(i64, f6) + f1_2 * @as(i64, f5_2) + f2_2 * @as(i64, f4) + f3_2 * @as(i64, f3) + f7_2 * @as(i64, f9_38) + f8 * @as(i64, f8_19);
+ t[7] = f0_2 * @as(i64, f7) + f1_2 * @as(i64, f6) + f2_2 * @as(i64, f5) + f3_2 * @as(i64, f4) + f8 * @as(i64, f9_38);
+ t[8] = f0_2 * @as(i64, f8) + f1_2 * @as(i64, f7_2) + f2_2 * @as(i64, f6) + f3_2 * @as(i64, f5_2) + f4 * @as(i64, f4) + f9 * @as(i64, f9_38);
+ t[9] = f0_2 * @as(i64, f9) + f1_2 * @as(i64, f8) + f2_2 * @as(i64, f7) + f3_2 * @as(i64, f6) + f4 * @as(i64, f5_2);
carry2(h, t[0..]);
}
diff --git a/lib/std/debug/leb128.zig b/lib/std/debug/leb128.zig
index ee1d1ac9ee..dba57e1f97 100644
--- a/lib/std/debug/leb128.zig
+++ b/lib/std/debug/leb128.zig
@@ -101,7 +101,7 @@ pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
return error.Overflow;
var operand: UT = undefined;
- if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
+ if (@shlWithOverflow(UT, @as(UT, byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
if (byte != 0x7f)
return error.Overflow;
}
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index c6f788deee..e901d8d3f7 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -382,10 +382,10 @@ pub fn formatType(
const info = @typeInfo(T).Union;
if (info.tag_type) |UnionTagType| {
try output(context, "{ .");
- try output(context, @tagName(UnionTagType(value)));
+ try output(context, @tagName(@as(UnionTagType, value)));
try output(context, " = ");
inline for (info.fields) |u_field| {
- if (@enumToInt(UnionTagType(value)) == u_field.enum_field.?.value) {
+ if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
try formatType(@field(value, u_field.name), "", options, context, Errors, output, max_depth - 1);
}
}
@@ -503,7 +503,7 @@ pub fn formatIntValue(
const int_value = if (@typeOf(value) == comptime_int) blk: {
const Int = math.IntFittingRange(value, value);
- break :blk Int(value);
+ break :blk @as(Int, value);
} else
value;
@@ -578,7 +578,7 @@ pub fn formatAsciiChar(
comptime Errors: type,
output: fn (@typeOf(context), []const u8) Errors!void,
) Errors!void {
- return output(context, (*const [1]u8)(&c)[0..]);
+ return output(context, @as(*const [1]u8, &c)[0..]);
}
pub fn formatBuf(
@@ -998,7 +998,7 @@ fn formatIntCallback(context: *FormatIntBuf, bytes: []const u8) (error{}!void) {
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
if (!T.is_signed) return parseUnsigned(T, buf, radix);
- if (buf.len == 0) return T(0);
+ if (buf.len == 0) return @as(T, 0);
if (buf[0] == '-') {
return math.negate(try parseUnsigned(T, buf[1..], radix));
} else if (buf[0] == '+') {
@@ -1325,8 +1325,8 @@ test "float.scientific" {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
- try testFmt("f32: 1.34000003e+00", "f32: {e}", f32(1.34));
- try testFmt("f32: 1.23400001e+01", "f32: {e}", f32(12.34));
+ try testFmt("f32: 1.34000003e+00", "f32: {e}", @as(f32, 1.34));
+ try testFmt("f32: 1.23400001e+01", "f32: {e}", @as(f32, 12.34));
try testFmt("f64: -1.234e+11", "f64: {e}", @as(f64, -12.34e10));
try testFmt("f64: 9.99996e-40", "f64: {e}", @as(f64, 9.999960e-40));
}
@@ -1365,12 +1365,12 @@ test "float.decimal" {
return error.SkipZigTest;
}
try testFmt("f64: 152314000000000000000000000000", "f64: {d}", @as(f64, 1.52314e+29));
- try testFmt("f32: 1.1", "f32: {d:.1}", f32(1.1234));
- try testFmt("f32: 1234.57", "f32: {d:.2}", f32(1234.567));
+ try testFmt("f32: 1.1", "f32: {d:.1}", @as(f32, 1.1234));
+ try testFmt("f32: 1234.57", "f32: {d:.2}", @as(f32, 1234.567));
// -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
// -11.12339... is rounded back up to -11.1234
- try testFmt("f32: -11.1234", "f32: {d:.4}", f32(-11.1234));
- try testFmt("f32: 91.12345", "f32: {d:.5}", f32(91.12345));
+ try testFmt("f32: -11.1234", "f32: {d:.4}", @as(f32, -11.1234));
+ try testFmt("f32: 91.12345", "f32: {d:.5}", @as(f32, 91.12345));
try testFmt("f64: 91.1234567890", "f64: {d:.10}", @as(f64, 91.12345678901235));
try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 0.0));
try testFmt("f64: 6", "f64: {d:.0}", @as(f64, 5.700));
diff --git a/lib/std/fmt/parse_float.zig b/lib/std/fmt/parse_float.zig
index aa3ac6d458..78ce0b7d0a 100644
--- a/lib/std/fmt/parse_float.zig
+++ b/lib/std/fmt/parse_float.zig
@@ -375,7 +375,7 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T {
return switch (try parseRepr(s, &r)) {
ParseResult.Ok => convertRepr(T, r),
ParseResult.PlusZero => 0.0,
- ParseResult.MinusZero => -T(0.0),
+ ParseResult.MinusZero => -@as(T, 0.0),
ParseResult.PlusInf => std.math.inf(T),
ParseResult.MinusInf => -std.math.inf(T),
};
@@ -426,8 +426,8 @@ test "fmt.parseFloat" {
expect(approxEq(T, try parseFloat(T, "1234e-2"), 12.34, epsilon));
expect(approxEq(T, try parseFloat(T, "123142.1"), 123142.1, epsilon));
- expect(approxEq(T, try parseFloat(T, "-123142.1124"), T(-123142.1124), epsilon));
- expect(approxEq(T, try parseFloat(T, "0.7062146892655368"), T(0.7062146892655368), epsilon));
+ expect(approxEq(T, try parseFloat(T, "-123142.1124"), @as(T, -123142.1124), epsilon));
+ expect(approxEq(T, try parseFloat(T, "0.7062146892655368"), @as(T, 0.7062146892655368), epsilon));
}
}
}
diff --git a/lib/std/heap.zig b/lib/std/heap.zig
index c9e9e3533d..24ab395734 100644
--- a/lib/std/heap.zig
+++ b/lib/std/heap.zig
@@ -893,10 +893,10 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
if (mem.page_size << 2 > maxInt(usize)) return;
const USizeShift = @IntType(false, std.math.log2(usize.bit_count));
- const large_align = u29(mem.page_size << 2);
+ const large_align = @as(u29, mem.page_size << 2);
var align_mask: usize = undefined;
- _ = @shlWithOverflow(usize, ~@as(usize, 0), USizeShift(@ctz(u29, large_align)), &align_mask);
+ _ = @shlWithOverflow(usize, ~@as(usize, 0), @as(USizeShift, @ctz(u29, large_align)), &align_mask);
var slice = try allocator.alignedAlloc(u8, large_align, 500);
testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
diff --git a/lib/std/io.zig b/lib/std/io.zig
index 4fcee6ec14..f2cbeff922 100644
--- a/lib/std/io.zig
+++ b/lib/std/io.zig
@@ -355,19 +355,19 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
out_bits.* = @as(usize, 0);
if (U == u0 or bits == 0) return 0;
- var out_buffer = Buf(0);
+ var out_buffer = @as(Buf, 0);
if (self.bit_count > 0) {
const n = if (self.bit_count >= bits) @intCast(u3, bits) else self.bit_count;
const shift = u7_bit_count - n;
switch (endian) {
builtin.Endian.Big => {
- out_buffer = Buf(self.bit_buffer >> shift);
+ out_buffer = @as(Buf, self.bit_buffer >> shift);
self.bit_buffer <<= n;
},
builtin.Endian.Little => {
const value = (self.bit_buffer << shift) >> shift;
- out_buffer = Buf(value);
+ out_buffer = @as(Buf, value);
self.bit_buffer >>= n;
},
}
@@ -393,28 +393,28 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
if (n >= u8_bit_count) {
out_buffer <<= @intCast(u3, u8_bit_count - 1);
out_buffer <<= 1;
- out_buffer |= Buf(next_byte);
+ out_buffer |= @as(Buf, next_byte);
out_bits.* += u8_bit_count;
continue;
}
const shift = @intCast(u3, u8_bit_count - n);
out_buffer <<= @intCast(BufShift, n);
- out_buffer |= Buf(next_byte >> shift);
+ out_buffer |= @as(Buf, next_byte >> shift);
out_bits.* += n;
self.bit_buffer = @truncate(u7, next_byte << @intCast(u3, n - 1));
self.bit_count = shift;
},
builtin.Endian.Little => {
if (n >= u8_bit_count) {
- out_buffer |= Buf(next_byte) << @intCast(BufShift, out_bits.*);
+ out_buffer |= @as(Buf, next_byte) << @intCast(BufShift, out_bits.*);
out_bits.* += u8_bit_count;
continue;
}
const shift = @intCast(u3, u8_bit_count - n);
const value = (next_byte << shift) >> shift;
- out_buffer |= Buf(value) << @intCast(BufShift, out_bits.*);
+ out_buffer |= @as(Buf, value) << @intCast(BufShift, out_bits.*);
out_bits.* += n;
self.bit_buffer = @truncate(u7, next_byte >> @intCast(u3, n));
self.bit_count = shift;
@@ -949,14 +949,14 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));
}
- var result = U(0);
+ var result = @as(U, 0);
for (buffer) |byte, i| {
switch (endian) {
builtin.Endian.Big => {
result = (result << u8_bit_count) | byte;
},
builtin.Endian.Little => {
- result |= U(byte) << @intCast(Log2U, u8_bit_count * i);
+ result |= @as(U, byte) << @intCast(Log2U, u8_bit_count * i);
},
}
}
@@ -1050,7 +1050,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
return;
}
- ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe
+ ptr.* = @as(OC, undefined); //make it non-null so the following .? is guaranteed safe
const val_ptr = &ptr.*.?;
try self.deserializeInto(val_ptr);
},
@@ -1154,7 +1154,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
switch (@typeId(T)) {
builtin.TypeId.Void => return,
- builtin.TypeId.Bool => try self.serializeInt(u1(@boolToInt(value))),
+ builtin.TypeId.Bool => try self.serializeInt(@as(u1, @boolToInt(value))),
builtin.TypeId.Float, builtin.TypeId.Int => try self.serializeInt(value),
builtin.TypeId.Struct => {
const info = @typeInfo(T);
@@ -1197,10 +1197,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
},
builtin.TypeId.Optional => {
if (value == null) {
- try self.serializeInt(u1(@boolToInt(false)));
+ try self.serializeInt(@as(u1, @boolToInt(false)));
return;
}
- try self.serializeInt(u1(@boolToInt(true)));
+ try self.serializeInt(@as(u1, @boolToInt(true)));
const OC = comptime meta.Child(T);
const val_ptr = &value.?;
diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig
index 1fa7fc594c..28b8371d9d 100644
--- a/lib/std/io/test.zig
+++ b/lib/std/io/test.zig
@@ -226,18 +226,18 @@ test "BitOutStream" {
const OutError = io.SliceOutStream.Error;
var bit_stream_be = io.BitOutStream(builtin.Endian.Big, OutError).init(&mem_out_be.stream);
- try bit_stream_be.writeBits(u2(1), 1);
- try bit_stream_be.writeBits(u5(2), 2);
+ try bit_stream_be.writeBits(@as(u2, 1), 1);
+ try bit_stream_be.writeBits(@as(u5, 2), 2);
try bit_stream_be.writeBits(@as(u128, 3), 3);
try bit_stream_be.writeBits(@as(u8, 4), 4);
- try bit_stream_be.writeBits(u9(5), 5);
- try bit_stream_be.writeBits(u1(1), 1);
+ try bit_stream_be.writeBits(@as(u9, 5), 5);
+ try bit_stream_be.writeBits(@as(u1, 1), 1);
expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
mem_out_be.pos = 0;
- try bit_stream_be.writeBits(u15(0b110011010000101), 15);
+ try bit_stream_be.writeBits(@as(u15, 0b110011010000101), 15);
try bit_stream_be.flushBits();
expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
@@ -345,8 +345,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
inline while (i <= max_test_bitsize) : (i += 1) {
const U = @IntType(false, i);
const S = @IntType(true, i);
- try serializer.serializeInt(U(i));
- if (i != 0) try serializer.serializeInt(S(-1)) else try serializer.serialize(S(0));
+ try serializer.serializeInt(@as(U, i));
+ if (i != 0) try serializer.serializeInt(@as(S, -1)) else try serializer.serialize(@as(S, 0));
}
try serializer.flush();
@@ -356,8 +356,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
const S = @IntType(true, i);
const x = try deserializer.deserializeInt(U);
const y = try deserializer.deserializeInt(S);
- expect(x == U(i));
- if (i != 0) expect(y == S(-1)) else expect(y == 0);
+ expect(x == @as(U, i));
+ if (i != 0) expect(y == @as(S, -1)) else expect(y == 0);
}
const u8_bit_count = comptime meta.bitCount(u8);
@@ -577,11 +577,11 @@ fn testBadData(comptime endian: builtin.Endian, comptime packing: io.Packing) !v
var in_stream = &in.stream;
var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
- try serializer.serialize(u14(3));
+ try serializer.serialize(@as(u14, 3));
expectError(error.InvalidEnumTag, deserializer.deserialize(A));
out.pos = 0;
- try serializer.serialize(u14(3));
- try serializer.serialize(u14(88));
+ try serializer.serialize(@as(u14, 3));
+ try serializer.serialize(@as(u14, 88));
expectError(error.InvalidEnumTag, deserializer.deserialize(C));
}
diff --git a/lib/std/lazy_init.zig b/lib/std/lazy_init.zig
index 7beabb9cde..add40a372d 100644
--- a/lib/std/lazy_init.zig
+++ b/lib/std/lazy_init.zig
@@ -39,7 +39,7 @@ fn LazyInit(comptime T: type) type {
},
2 => {
if (@sizeOf(T) == 0) {
- return T(undefined);
+ return @as(T, undefined);
} else {
return &self.data;
}
diff --git a/lib/std/math.zig b/lib/std/math.zig
index 7c672c7ae8..8e08cacc42 100644
--- a/lib/std/math.zig
+++ b/lib/std/math.zig
@@ -543,8 +543,8 @@ test "math.absFloat" {
comptime testAbsFloat();
}
fn testAbsFloat() void {
- testing.expect(absFloat(f32(-10.05)) == 10.05);
- testing.expect(absFloat(f32(10.05)) == 10.05);
+ testing.expect(absFloat(@as(f32, -10.05)) == 10.05);
+ testing.expect(absFloat(@as(f32, 10.05)) == 10.05);
}
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
@@ -731,8 +731,8 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
test "math.cast" {
testing.expectError(error.Overflow, cast(u8, @as(u32, 300)));
testing.expectError(error.Overflow, cast(i8, @as(i32, -200)));
- testing.expectError(error.Overflow, cast(u8, i8(-1)));
- testing.expectError(error.Overflow, cast(u64, i8(-1)));
+ testing.expectError(error.Overflow, cast(u8, @as(i8, -1)));
+ testing.expectError(error.Overflow, cast(u64, @as(i8, -1)));
testing.expect((try cast(u8, @as(u32, 255))) == @as(u8, 255));
testing.expect(@typeOf(try cast(u8, @as(u32, 255))) == u8);
@@ -786,9 +786,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
comptime assert(@typeId(T) == builtin.TypeId.Int);
comptime assert(!T.is_signed);
assert(value != 0);
- comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);
- comptime const shiftType = std.math.Log2Int(promotedType);
- return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
+ comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
+ comptime const shiftType = std.math.Log2Int(PromotedType);
+ return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
}
/// Returns the next power of two (if the value is not already a power of two).
@@ -797,8 +797,8 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {
comptime assert(@typeId(T) == builtin.TypeId.Int);
comptime assert(!T.is_signed);
- comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);
- comptime const overflowBit = promotedType(1) << T.bit_count;
+ comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
+ comptime const overflowBit = @as(PromotedType, 1) << T.bit_count;
var x = ceilPowerOfTwoPromote(T, value);
if (overflowBit & x != 0) {
return error.Overflow;
@@ -848,7 +848,7 @@ pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {
assert(x != 0);
const log2_val = log2_int(T, x);
- if (T(1) << log2_val == x)
+ if (@as(T, 1) << log2_val == x)
return log2_val;
return log2_val + 1;
}
@@ -870,8 +870,8 @@ pub fn lossyCast(comptime T: type, value: var) T {
switch (@typeInfo(@typeOf(value))) {
builtin.TypeId.Int => return @intToFloat(T, value),
builtin.TypeId.Float => return @floatCast(T, value),
- builtin.TypeId.ComptimeInt => return T(value),
- builtin.TypeId.ComptimeFloat => return T(value),
+ builtin.TypeId.ComptimeInt => return @as(T, value),
+ builtin.TypeId.ComptimeFloat => return @as(T, value),
else => @compileError("bad type"),
}
}
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index fa2424de07..0459b0b158 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -281,7 +281,7 @@ pub const Int = struct {
var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);
if (info.bits <= Limb.bit_count) {
- self.limbs[0] = Limb(w_value);
+ self.limbs[0] = @as(Limb, w_value);
self.metadata += 1;
} else {
var i: usize = 0;
@@ -453,7 +453,7 @@ pub const Int = struct {
for (self.limbs[0..self.len()]) |limb| {
var shift: usize = 0;
while (shift < Limb.bit_count) : (shift += base_shift) {
- const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1));
+ const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & @as(Limb, base - 1));
const ch = try digitToChar(r, base);
try digits.append(ch);
}
@@ -560,7 +560,7 @@ pub const Int = struct {
/// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
pub fn cmp(a: Int, b: Int) i8 {
if (a.isPositive() != b.isPositive()) {
- return if (a.isPositive()) i8(1) else -1;
+ return if (a.isPositive()) @as(i8, 1) else -1;
} else {
const r = cmpAbs(a, b);
return if (a.isPositive()) r else -r;
@@ -785,7 +785,7 @@ pub const Int = struct {
const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));
// r2 = b * c
- const bc = DoubleLimb(math.mulWide(Limb, b, c));
+ const bc = @as(DoubleLimb, math.mulWide(Limb, b, c));
const r2 = @truncate(Limb, bc);
const c2 = @truncate(Limb, bc >> Limb.bit_count);
@@ -1084,7 +1084,7 @@ pub const Int = struct {
rem.* = 0;
for (a) |_, ri| {
const i = a.len - ri - 1;
- const pdiv = ((DoubleLimb(rem.*) << Limb.bit_count) | a[i]);
+ const pdiv = ((@as(DoubleLimb, rem.*) << Limb.bit_count) | a[i]);
if (pdiv == 0) {
quo[i] = 0;
@@ -1143,9 +1143,9 @@ pub const Int = struct {
if (x.limbs[i] == y.limbs[t]) {
q.limbs[i - t - 1] = maxInt(Limb);
} else {
- const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]);
- const z = @intCast(Limb, num / DoubleLimb(y.limbs[t]));
- q.limbs[i - t - 1] = if (z > maxInt(Limb)) maxInt(Limb) else Limb(z);
+ const num = (@as(DoubleLimb, x.limbs[i]) << Limb.bit_count) | @as(DoubleLimb, x.limbs[i - 1]);
+ const z = @intCast(Limb, num / @as(DoubleLimb, y.limbs[t]));
+ q.limbs[i - t - 1] = if (z > maxInt(Limb)) maxInt(Limb) else @as(Limb, z);
}
// 3.2
@@ -1362,7 +1362,7 @@ test "big.int comptime_int set" {
comptime var i: usize = 0;
inline while (i < s_limb_count) : (i += 1) {
- const result = Limb(s & maxInt(Limb));
+ const result = @as(Limb, s & maxInt(Limb));
s >>= Limb.bit_count / 2;
s >>= Limb.bit_count / 2;
testing.expect(a.limbs[i] == result);
@@ -1377,7 +1377,7 @@ test "big.int comptime_int set negative" {
}
test "big.int int set unaligned small" {
- var a = try Int.initSet(al, u7(45));
+ var a = try Int.initSet(al, @as(u7, 45));
testing.expect(a.limbs[0] == 45);
testing.expect(a.isPositive() == true);
diff --git a/lib/std/math/complex.zig b/lib/std/math/complex.zig
index e5574f9cee..8bff2313fc 100644
--- a/lib/std/math/complex.zig
+++ b/lib/std/math/complex.zig
@@ -133,8 +133,8 @@ test "complex.div" {
const b = Complex(f32).new(2, 7);
const c = a.div(b);
- testing.expect(math.approxEq(f32, c.re, f32(31) / 53, epsilon) and
- math.approxEq(f32, c.im, f32(-29) / 53, epsilon));
+ testing.expect(math.approxEq(f32, c.re, @as(f32, 31) / 53, epsilon) and
+ math.approxEq(f32, c.im, @as(f32, -29) / 53, epsilon));
}
test "complex.conjugate" {
@@ -148,8 +148,8 @@ test "complex.reciprocal" {
const a = Complex(f32).new(5, 3);
const c = a.reciprocal();
- testing.expect(math.approxEq(f32, c.re, f32(5) / 34, epsilon) and
- math.approxEq(f32, c.im, f32(-3) / 34, epsilon));
+ testing.expect(math.approxEq(f32, c.re, @as(f32, 5) / 34, epsilon) and
+ math.approxEq(f32, c.im, @as(f32, -3) / 34, epsilon));
}
test "complex.magnitude" {
diff --git a/lib/std/math/complex/acos.zig b/lib/std/math/complex/acos.zig
index f3526cc9ff..b078ebf345 100644
--- a/lib/std/math/complex/acos.zig
+++ b/lib/std/math/complex/acos.zig
@@ -8,7 +8,7 @@ const Complex = cmath.Complex;
pub fn acos(z: var) Complex(@typeOf(z.re)) {
const T = @typeOf(z.re);
const q = cmath.asin(z);
- return Complex(T).new(T(math.pi) / 2 - q.re, -q.im);
+ return Complex(T).new(@as(T, math.pi) / 2 - q.re, -q.im);
}
const epsilon = 0.0001;
diff --git a/lib/std/math/complex/ldexp.zig b/lib/std/math/complex/ldexp.zig
index d74ac86148..d5d4cc64a6 100644
--- a/lib/std/math/complex/ldexp.zig
+++ b/lib/std/math/complex/ldexp.zig
@@ -65,7 +65,7 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {
fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {
var ex_expt: i32 = undefined;
const exp_x = frexp_exp64(z.re, &ex_expt);
- const exptf = i64(expt + ex_expt);
+ const exptf = @as(i64, expt + ex_expt);
const half_expt1 = @divTrunc(exptf, 2);
const scale1 = @bitCast(f64, (0x3ff + half_expt1) << 20);
diff --git a/lib/std/math/exp.zig b/lib/std/math/exp.zig
index e1297b11bc..986c35bf0d 100644
--- a/lib/std/math/exp.zig
+++ b/lib/std/math/exp.zig
@@ -134,7 +134,7 @@ fn exp64(x_: f64) f64 {
}
if (x < -708.39641853226410622) {
// underflow if x != -inf
- // math.forceEval(f32(-0x1.0p-149 / x));
+ // math.forceEval(@as(f32, -0x1.0p-149 / x));
if (x < -745.13321910194110842) {
return 0;
}
diff --git a/lib/std/math/ln.zig b/lib/std/math/ln.zig
index 362e44a869..fd5741a818 100644
--- a/lib/std/math/ln.zig
+++ b/lib/std/math/ln.zig
@@ -34,7 +34,7 @@ pub fn ln(x: var) @typeOf(x) {
return @typeOf(1)(math.floor(ln_64(@as(f64, x))));
},
TypeId.Int => {
- return T(math.floor(ln_64(@as(f64, x))));
+ return @as(T, math.floor(ln_64(@as(f64, x))));
},
else => @compileError("ln not implemented for " ++ @typeName(T)),
}
diff --git a/lib/std/math/log.zig b/lib/std/math/log.zig
index 84dbcf939d..40b716b005 100644
--- a/lib/std/math/log.zig
+++ b/lib/std/math/log.zig
@@ -64,8 +64,8 @@ test "math.log float" {
}
test "math.log float_special" {
- expect(log(f32, 2, 0.2301974) == math.log2(f32(0.2301974)));
- expect(log(f32, 10, 0.2301974) == math.log10(f32(0.2301974)));
+ expect(log(f32, 2, 0.2301974) == math.log2(@as(f32, 0.2301974)));
+ expect(log(f32, 10, 0.2301974) == math.log10(@as(f32, 0.2301974)));
expect(log(f64, 2, 213.23019799993) == math.log2(@as(f64, 213.23019799993)));
expect(log(f64, 10, 213.23019799993) == math.log10(@as(f64, 213.23019799993)));
diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig
index a4b3fef26b..f895e102a0 100644
--- a/lib/std/math/log10.zig
+++ b/lib/std/math/log10.zig
@@ -177,7 +177,7 @@ pub fn log10_64(x_: f64) f64 {
}
test "math.log10" {
- testing.expect(log10(f32(0.2)) == log10_32(0.2));
+ testing.expect(log10(@as(f32, 0.2)) == log10_32(0.2));
testing.expect(log10(@as(f64, 0.2)) == log10_64(0.2));
}
diff --git a/lib/std/math/sqrt.zig b/lib/std/math/sqrt.zig
index 1b74c34eda..89eda4ea2b 100644
--- a/lib/std/math/sqrt.zig
+++ b/lib/std/math/sqrt.zig
@@ -15,7 +15,7 @@ const maxInt = std.math.maxInt;
pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
const T = @typeOf(x);
switch (@typeId(T)) {
- TypeId.ComptimeFloat => return T(@sqrt(f64, x)), // TODO upgrade to f128
+ TypeId.ComptimeFloat => return @as(T, @sqrt(f64, x)), // TODO upgrade to f128
TypeId.Float => return @sqrt(T, x),
TypeId.ComptimeInt => comptime {
if (x > maxInt(u128)) {
@@ -24,7 +24,7 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ
if (x < 0) {
@compileError("sqrt on negative number");
}
- return T(sqrt_int(u128, x));
+ return @as(T, sqrt_int(u128, x));
},
TypeId.Int => return sqrt_int(T, x),
else => @compileError("sqrt not implemented for " ++ @typeName(T)),
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index ded5aa4b1a..903c3a12b3 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -341,7 +341,7 @@ test "std.meta.TagType" {
///Returns the active tag of a tagged union
pub fn activeTag(u: var) @TagType(@typeOf(u)) {
const T = @typeOf(u);
- return @TagType(T)(u);
+ return @as(@TagType(T), u);
}
test "std.meta.activeTag" {
diff --git a/lib/std/net.zig b/lib/std/net.zig
index fcb64d029a..d1db147866 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -117,7 +117,7 @@ pub const IpAddress = extern union {
ip_slice[10] = 0xff;
ip_slice[11] = 0xff;
- const ptr = @sliceToBytes((*const [1]u32)(&addr)[0..]);
+ const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]);
ip_slice[12] = ptr[0];
ip_slice[13] = ptr[1];
@@ -161,7 +161,7 @@ pub const IpAddress = extern union {
.addr = undefined,
},
};
- const out_ptr = @sliceToBytes((*[1]u32)(&result.in.addr)[0..]);
+ const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]);
var x: u8 = 0;
var index: u8 = 0;
@@ -271,7 +271,7 @@ pub const IpAddress = extern union {
},
os.AF_INET6 => {
const port = mem.bigToNative(u16, self.in6.port);
- if (mem.eql(u8, self.in6.addr[0..12], [_]u8{0,0,0,0,0,0,0,0,0,0,0xff,0xff})) {
+ if (mem.eql(u8, self.in6.addr[0..12], [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
try std.fmt.format(
context,
Errors,
@@ -1133,7 +1133,7 @@ fn resMSendRc(
}
// Wait for a response, or until time to retry
- const clamped_timeout = std.math.min(u31(std.math.maxInt(u31)), t1 + retry_interval - t2);
+ const clamped_timeout = std.math.min(@as(u31, std.math.maxInt(u31)), t1 + retry_interval - t2);
const nevents = os.poll(&pfd, clamped_timeout) catch 0;
if (nevents == 0) continue;
diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig
index e089a02445..bccb7beb1e 100644
--- a/lib/std/os/linux/test.zig
+++ b/lib/std/os/linux/test.zig
@@ -72,7 +72,7 @@ test "statx" {
expect(stat_buf.mode == statx_buf.mode);
expect(@bitCast(u32, stat_buf.uid) == statx_buf.uid);
expect(@bitCast(u32, stat_buf.gid) == statx_buf.gid);
- expect(@bitCast(u64, i64(stat_buf.size)) == statx_buf.size);
- expect(@bitCast(u64, i64(stat_buf.blksize)) == statx_buf.blksize);
- expect(@bitCast(u64, i64(stat_buf.blocks)) == statx_buf.blocks);
+ expect(@bitCast(u64, @as(i64, stat_buf.size)) == statx_buf.size);
+ expect(@bitCast(u64, @as(i64, stat_buf.blksize)) == statx_buf.blksize);
+ expect(@bitCast(u64, @as(i64, stat_buf.blocks)) == statx_buf.blocks);
}
diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig
index c22d701bf2..d8c77db59b 100644
--- a/lib/std/packed_int_array.zig
+++ b/lib/std/packed_int_array.zig
@@ -193,7 +193,7 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian,
///Initialize a packed array using an unpacked array
/// or, more likely, an array literal.
pub fn init(ints: [int_count]Int) Self {
- var self = Self(undefined);
+ var self = @as(Self, undefined);
for (ints) |int, i| self.set(i, int);
return self;
}
@@ -328,11 +328,11 @@ test "PackedIntArray" {
const expected_bytes = ((bits * int_count) + 7) / 8;
testing.expect(@sizeOf(PackedArray) == expected_bytes);
- var data = PackedArray(undefined);
+ var data = @as(PackedArray, undefined);
//write values, counting up
var i = @as(usize, 0);
- var count = I(0);
+ var count = @as(I, 0);
while (i < data.len()) : (i += 1) {
data.set(i, count);
if (bits > 0) count +%= 1;
@@ -376,7 +376,7 @@ test "PackedIntSlice" {
//write values, counting up
var i = @as(usize, 0);
- var count = I(0);
+ var count = @as(I, 0);
while (i < data.len()) : (i += 1) {
data.set(i, count);
if (bits > 0) count +%= 1;
@@ -402,7 +402,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
const Int = @IntType(false, bits);
const PackedArray = PackedIntArray(Int, int_count);
- var packed_array = PackedArray(undefined);
+ var packed_array = @as(PackedArray, undefined);
const limit = (1 << bits);
@@ -463,7 +463,7 @@ test "PackedIntSlice accumulating bit offsets" {
// anything
{
const PackedArray = PackedIntArray(u3, 16);
- var packed_array = PackedArray(undefined);
+ var packed_array = @as(PackedArray, undefined);
var packed_slice = packed_array.slice(0, packed_array.len());
var i = @as(usize, 0);
@@ -473,7 +473,7 @@ test "PackedIntSlice accumulating bit offsets" {
}
{
const PackedArray = PackedIntArray(u11, 88);
- var packed_array = PackedArray(undefined);
+ var packed_array = @as(PackedArray, undefined);
var packed_slice = packed_array.slice(0, packed_array.len());
var i = @as(usize, 0);
@@ -518,8 +518,8 @@ test "PackedInt(Array/Slice) sliceCast" {
i = 0;
while (i < packed_slice_cast_3.len()) : (i += 1) {
const val = switch (builtin.endian) {
- .Big => if (i % 2 == 0) u3(0b111) else u3(0b000),
- .Little => if (i % 2 == 0) u3(0b111) else u3(0b000),
+ .Big => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),
+ .Little => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),
};
testing.expect(packed_slice_cast_3.get(i) == val);
}
diff --git a/lib/std/rand.zig b/lib/std/rand.zig
index 2cd1583f63..1fea0526ed 100644
--- a/lib/std/rand.zig
+++ b/lib/std/rand.zig
@@ -93,13 +93,13 @@ pub const Random = struct {
// http://www.pcg-random.org/posts/bounded-rands.html
// "Lemire's (with an extra tweak from me)"
var x: Small = r.int(Small);
- var m: Large = Large(x) * Large(less_than);
+ var m: Large = @as(Large, x) * @as(Large, less_than);
var l: Small = @truncate(Small, m);
if (l < less_than) {
// TODO: workaround for https://github.com/ziglang/zig/issues/1770
// should be:
// var t: Small = -%less_than;
- var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), Small(less_than)));
+ var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), @as(Small, less_than)));
if (t >= less_than) {
t -= less_than;
@@ -109,7 +109,7 @@ pub const Random = struct {
}
while (l < t) {
x = r.int(Small);
- m = Large(x) * Large(less_than);
+ m = @as(Large, x) * @as(Large, less_than);
l = @truncate(Small, m);
}
}
@@ -286,7 +286,7 @@ pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
// adapted from:
// http://www.pcg-random.org/posts/bounded-rands.html
// "Integer Multiplication (Biased)"
- var m: T2 = T2(random_int) * T2(less_than);
+ var m: T2 = @as(T2, random_int) * @as(T2, less_than);
return @intCast(T, m >> T.bit_count);
}
diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig
index 5509f5f9dd..726b84f125 100644
--- a/lib/std/unicode.zig
+++ b/lib/std/unicode.zig
@@ -7,10 +7,10 @@ const mem = std.mem;
/// Returns how many bytes the UTF-8 representation would require
/// for the given codepoint.
pub fn utf8CodepointSequenceLength(c: u32) !u3 {
- if (c < 0x80) return u3(1);
- if (c < 0x800) return u3(2);
- if (c < 0x10000) return u3(3);
- if (c < 0x110000) return u3(4);
+ if (c < 0x80) return @as(u3, 1);
+ if (c < 0x800) return @as(u3, 2);
+ if (c < 0x10000) return @as(u3, 3);
+ if (c < 0x110000) return @as(u3, 4);
return error.CodepointTooLarge;
}
@@ -18,10 +18,10 @@ pub fn utf8CodepointSequenceLength(c: u32) !u3 {
/// returns a number 1-4 indicating the total length of the codepoint in bytes.
/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {
- if (first_byte < 0b10000000) return u3(1);
- if (first_byte & 0b11100000 == 0b11000000) return u3(2);
- if (first_byte & 0b11110000 == 0b11100000) return u3(3);
- if (first_byte & 0b11111000 == 0b11110000) return u3(4);
+ if (first_byte < 0b10000000) return @as(u3, 1);
+ if (first_byte & 0b11100000 == 0b11000000) return @as(u3, 2);
+ if (first_byte & 0b11110000 == 0b11100000) return @as(u3, 3);
+ if (first_byte & 0b11111000 == 0b11110000) return @as(u3, 4);
return error.Utf8InvalidStartByte;
}
diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig
index 3524c4f5b5..e84f7b0ac1 100644
--- a/src-self-hosted/stage1.zig
+++ b/src-self-hosted/stage1.zig
@@ -224,7 +224,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
}
if (flags.present("check")) {
const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
- const code = if (anything_changed) u8(1) else u8(0);
+ const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
process.exit(code);
}
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index b4f69753b1..0d3a99a683 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -123,7 +123,7 @@ const Context = struct {
fn locStr(c: *Context, loc: ZigClangSourceLocation) ![]u8 {
const spelling_loc = ZigClangSourceManager_getSpellingLoc(c.source_manager, loc);
const filename_c = ZigClangSourceManager_getFilename(c.source_manager, spelling_loc);
- const filename = if (filename_c) |s| try c.str(s) else ([]const u8)("(no file)");
+ const filename = if (filename_c) |s| try c.str(s) else @as([]const u8, "(no file)");
const line = ZigClangSourceManager_getSpellingLineNumber(c.source_manager, spelling_loc);
const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index c7f286ce3f..e3d80e4b63 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1332,7 +1332,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@bitCast with different sizes inside an expression",
\\export fn entry() void {
- \\ var foo = (@bitCast(u8, f32(1.0)) == 0xf);
+ \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);
\\}
,
"tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",
@@ -2120,13 +2120,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@floatToInt comptime safety",
\\comptime {
- \\ _ = @floatToInt(i8, f32(-129.1));
+ \\ _ = @floatToInt(i8, @as(f32, -129.1));
\\}
\\comptime {
- \\ _ = @floatToInt(u8, f32(-1.1));
+ \\ _ = @floatToInt(u8, @as(f32, -1.1));
\\}
\\comptime {
- \\ _ = @floatToInt(u8, f32(256.1));
+ \\ _ = @floatToInt(u8, @as(f32, 256.1));
\\}
,
"tmp.zig:2:9: error: integer value '-129' cannot be stored in type 'i8'",
@@ -3888,7 +3888,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\const lit_int_x = 1 / 0;
\\const lit_float_x = 1.0 / 0.0;
\\const int_x = @as(u32, 1) / @as(u32, 0);
- \\const float_x = f32(1.0) / f32(0.0);
+ \\const float_x = @as(f32, 1.0) / @as(f32, 0.0);
\\
\\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }
\\export fn entry2() usize { return @sizeOf(@typeOf(lit_float_x)); }
From aef04aff0c60a82ab5c2336ca999a918b1905c68 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Nov 2019 19:05:52 -0500
Subject: [PATCH 039/129] initial docs for `@as`
---
doc/langref.html.in | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 3eb30c3058..a4000f1b47 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6445,6 +6445,14 @@ comptime {
{#header_close#}
+ {#header_open|@as#}
+ {#syntax#}@as(comptime T: type, expression) T{#endsyntax#}
+
+ Performs {#link|Type Coercion#}. This cast is allowed when the conversion is unambiguous and safe,
+ and is the preferred way to convert between types, whenever possible.
+
+ {#header_close#}
+
{#header_open|@asyncCall#}
{#syntax#}@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: ...) anyframe->T{#endsyntax#}
From 3834d3dac0d901e8319aa515b64ade8604fe1ecf Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Nov 2019 01:15:19 -0500
Subject: [PATCH 040/129] passing std lib tests
---
src/ir.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 148be3b507..bf558cb8a2 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15719,7 +15719,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
return result_loc->resolved_loc;
}
case ResultLocIdCast: {
- if (!non_null_comptime && value != nullptr && value->value.special != ConstValSpecialRuntime)
+ if (value != nullptr && value->value.special != ConstValSpecialRuntime)
return nullptr;
ResultLocCast *result_cast = reinterpret_cast(result_loc);
ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
From 3cf5c2c62b12aa0615633a150a1ea8c279e53004 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Nov 2019 15:56:21 -0500
Subject: [PATCH 041/129] fix regressed tests and update docs to use "type
coercion"
---
build.zig | 2 +-
doc/docgen.zig | 4 +-
doc/langref.html.in | 140 ++++++++++++++++----------------
lib/std/event/loop.zig | 22 ++---
lib/std/fs.zig | 2 +-
lib/std/os.zig | 4 +-
lib/std/os/windows.zig | 2 +-
lib/std/os/windows/bits.zig | 24 +++---
src-self-hosted/translate_c.zig | 16 ++--
src/ir.cpp | 15 ++--
src/translate_c.cpp | 29 +++----
test/compare_output.zig | 18 ++--
test/compile_errors.zig | 72 ++++++++--------
test/translate_c.zig | 52 ++++++------
14 files changed, 203 insertions(+), 199 deletions(-)
diff --git a/build.zig b/build.zig
index 7cd6d1b7bb..cd25001eef 100644
--- a/build.zig
+++ b/build.zig
@@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
) catch unreachable;
for (dep.system_libs.toSliceConst()) |lib| {
const static_bare_name = if (mem.eql(u8, lib, "curses"))
- @as([]const u8,"libncurses.a")
+ @as([]const u8, "libncurses.a")
else
b.fmt("lib{}.a", lib);
const static_lib_name = fs.path.join(
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 07a7f23968..b25a903501 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -10,8 +10,8 @@ const testing = std.testing;
const max_doc_file_size = 10 * 1024 * 1024;
-const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
-const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
+const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt();
+const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt();
const tmp_dir_name = "docgen_tmp";
const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;
diff --git a/doc/langref.html.in b/doc/langref.html.in
index a4000f1b47..627709ec84 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -712,7 +712,7 @@ test "init with undefined" {
}
{#code_end#}
- {#syntax#}undefined{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to any type.
+ {#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type.
Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}.
{#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense
according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful
@@ -920,7 +920,7 @@ fn divide(a: i32, b: i32) i32 {
{#syntax#}f128{#endsyntax#}.
- Float literals {#link|implicitly cast|Implicit Casts#} to any floating point type,
+ Float literals {#link|coerce|Type Coercion#} to any floating point type,
and to any {#link|integer|Integers#} type when there is no fractional component.
{#code_begin|syntax#}
@@ -950,7 +950,7 @@ const nan = std.math.nan(f128);
{#code_begin|obj|foo#}
{#code_release_fast#}
const builtin = @import("builtin");
-const big = f64(1 << 40);
+const big = @as(f64, 1 << 40);
export fn foo_strict(x: f64) f64 {
return x + big - big;
@@ -1652,7 +1652,7 @@ test "iterate over an array" {
for (message) |byte| {
sum += byte;
}
- assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o'));
+ assert(sum == 'h' + 'e' + 'l' * 2 + 'o');
}
// modifiable array
@@ -2003,7 +2003,7 @@ test "variable alignment" {
}
}
{#code_end#}
- In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to a
+
In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a
{#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly
cast to a pointer with a smaller alignment, but not vice versa.
@@ -2019,7 +2019,7 @@ var foo: u8 align(4) = 100;
test "global variable alignment" {
assert(@typeOf(&foo).alignment == 4);
assert(@typeOf(&foo) == *align(4) u8);
- const slice = (*[1]u8)(&foo)[0..];
+ const slice = @as(*[1]u8, &foo)[0..];
assert(@typeOf(slice) == []align(4) u8);
}
@@ -2114,7 +2114,7 @@ const fmt = @import("std").fmt;
test "using slices for strings" {
// Zig has no concept of strings. String literals are arrays of u8, and
// in general the string type is []u8 (slice of u8).
- // Here we implicitly cast [5]u8 to []const u8
+ // Here we coerce [5]u8 to []const u8
const hello: []const u8 = "hello";
const world: []const u8 = "世界";
@@ -2778,7 +2778,7 @@ test "simple union" {
This turns the union into a tagged union, which makes it eligible
to use with {#link|switch#} expressions. One can use {#link|@TagType#} to
obtain the enum type from the union type.
- Tagged unions implicitly cast to their enum {#link|Implicit Cast: unions and enums#}
+ Tagged unions coerce to their enum {#link|Type Coercion: unions and enums#}
{#code_begin|test#}
const std = @import("std");
@@ -2795,7 +2795,7 @@ const ComplexType = union(ComplexTypeTag) {
test "switch on tagged union" {
const c = ComplexType{ .Ok = 42 };
- assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
+ assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
switch (c) {
ComplexTypeTag.Ok => |value| assert(value == 42),
@@ -2807,7 +2807,7 @@ test "@TagType" {
assert(@TagType(ComplexType) == ComplexTypeTag);
}
-test "implicit cast to enum" {
+test "coerce to enum" {
const c1 = ComplexType{ .Ok = 42 };
const c2 = ComplexType.NotOk;
@@ -2833,7 +2833,7 @@ const ComplexType = union(ComplexTypeTag) {
test "modify tagged union in switch" {
var c = ComplexType{ .Ok = 42 };
- assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
+ assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
switch (c) {
ComplexTypeTag.Ok => |*value| value.* += 1,
@@ -3943,7 +3943,7 @@ test "fn reflection" {
However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See #768.
- You can {#link|implicitly cast|Implicit Casts#} an error from a subset to a superset:
+ You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
{#code_begin|test#}
const std = @import("std");
@@ -3958,7 +3958,7 @@ const AllocationError = error {
OutOfMemory,
};
-test "implicit cast subset to superset" {
+test "coerce subset to superset" {
const err = foo(AllocationError.OutOfMemory);
std.debug.assert(err == FileOpenError.OutOfMemory);
}
@@ -3968,7 +3968,7 @@ fn foo(err: AllocationError) FileOpenError {
}
{#code_end#}
- But you cannot implicitly cast an error from a superset to a subset:
+ But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset:
{#code_begin|test_err|not a member of destination error set#}
const FileOpenError = error {
@@ -3981,7 +3981,7 @@ const AllocationError = error {
OutOfMemory,
};
-test "implicit cast superset to subset" {
+test "coerce superset to subset" {
foo(FileOpenError.OutOfMemory) catch {};
}
@@ -4008,7 +4008,7 @@ const err = (error {FileNotFound}).FileNotFound;
It is a superset of all other error sets and a subset of none of them.
- You can implicitly cast any error set to the global one, and you can explicitly
+ You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly
cast an error of the global error set to a non-global one. This inserts a language-level
assert to make sure the error value is in fact in the destination error set.
@@ -4079,7 +4079,7 @@ test "parse u64" {
Within the function definition, you can see some return statements that return
an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}.
- Both types {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyerror!u64{#endsyntax#}.
+ Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}.
What it looks like to use this function varies depending on what you're
@@ -4218,10 +4218,10 @@ const assert = @import("std").debug.assert;
test "error union" {
var foo: anyerror!i32 = undefined;
- // Implicitly cast from child type of an error union:
+ // Coerce from child type of an error union:
foo = 1234;
- // Implicitly cast from an error set:
+ // Coerce from an error set:
foo = error.SomeError;
// Use compile-time reflection to access the payload type of an error union:
@@ -4598,10 +4598,10 @@ fn doAThing(optional_foo: ?*Foo) void {
const assert = @import("std").debug.assert;
test "optional type" {
- // Declare an optional and implicitly cast from null:
+ // Declare an optional and coerce from null:
var foo: ?i32 = null;
- // Implicitly cast from child type of an optional
+ // Coerce from child type of an optional
foo = 1234;
// Use compile-time reflection to access the child type of the optional:
@@ -4644,38 +4644,38 @@ test "optional pointers" {
{#header_open|Casting#}
A type cast converts a value of one type to another.
- Zig has {#link|Implicit Casts#} for conversions that are known to be completely safe and unambiguous,
+ Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous,
and {#link|Explicit Casts#} for conversions that one would not want to happen on accident.
There is also a third kind of type conversion called {#link|Peer Type Resolution#} for
the case when a result type must be decided given multiple operand types.
- {#header_open|Implicit Casts#}
+ {#header_open|Type Coercion#}
- An implicit cast occurs when one type is expected, but different type is provided:
+ Type coercion occurs when one type is expected, but different type is provided:
{#code_begin|test#}
-test "implicit cast - variable declaration" {
+test "type coercion - variable declaration" {
var a: u8 = 1;
var b: u16 = a;
}
-test "implicit cast - function call" {
+test "type coercion - function call" {
var a: u8 = 1;
foo(a);
}
fn foo(b: u16) void {}
-test "implicit cast - invoke a type as a function" {
+test "type coercion - @as builtin" {
var a: u8 = 1;
- var b = u16(a);
+ var b = @as(u16, a);
}
{#code_end#}
- Implicit casts are only allowed when it is completely unambiguous how to get from one type to another,
+ Type coercions are only allowed when it is completely unambiguous how to get from one type to another,
and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.
- {#header_open|Implicit Cast: Stricter Qualification#}
+ {#header_open|Type Coercion: Stricter Qualification#}
Values which have the same representation at runtime can be cast to increase the strictness
of the qualifiers, no matter how nested the qualifiers are:
@@ -4690,7 +4690,7 @@ test "implicit cast - invoke a type as a function" {
These casts are no-ops at runtime since the value representation does not change.
{#code_begin|test#}
-test "implicit cast - const qualification" {
+test "type coercion - const qualification" {
var a: i32 = 1;
var b: *i32 = &a;
foo(b);
@@ -4699,7 +4699,7 @@ test "implicit cast - const qualification" {
fn foo(a: *const i32) void {}
{#code_end#}
- In addition, pointers implicitly cast to const optional pointers:
+ In addition, pointers coerce to const optional pointers:
{#code_begin|test#}
const std = @import("std");
@@ -4713,10 +4713,10 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: Integer and Float Widening#}
+ {#header_open|Type Coercion: Integer and Float Widening#}
- {#link|Integers#} implicitly cast to integer types which can represent every value of the old type, and likewise
- {#link|Floats#} implicitly cast to float types which can represent every value of the old type.
+ {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
+ {#link|Floats#} coerce to float types which can represent every value of the old type.
{#code_begin|test#}
const std = @import("std");
@@ -4748,7 +4748,7 @@ test "float widening" {
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: Arrays and Pointers#}
+ {#header_open|Type Coercion: Arrays and Pointers#}
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
@@ -4797,7 +4797,7 @@ test "*[N]T to []T" {
assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 }));
}
-// Single-item pointers to arrays can be implicitly casted to
+// Single-item pointers to arrays can be coerced to
// unknown length pointers.
test "*[N]T to [*]T" {
var buf: [5]u8 = "hello";
@@ -4823,15 +4823,15 @@ test "*T to *[1]T" {
{#code_end#}
{#see_also|C Pointers#}
{#header_close#}
- {#header_open|Implicit Cast: Optionals#}
+ {#header_open|Type Coercion: Optionals#}
- The payload type of {#link|Optionals#}, as well as {#link|null#}, implicitly cast to the optional type.
+ The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
-test "implicit casting to optionals" {
+test "coerce to optionals" {
const x: ?i32 = 1234;
const y: ?i32 = null;
@@ -4844,7 +4844,7 @@ test "implicit casting to optionals" {
const std = @import("std");
const assert = std.debug.assert;
-test "implicit casting to optionals wrapped in error union" {
+test "coerce to optionals wrapped in error union" {
const x: anyerror!?i32 = 1234;
const y: anyerror!?i32 = null;
@@ -4853,15 +4853,15 @@ test "implicit casting to optionals wrapped in error union" {
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: Error Unions#}
+ {#header_open|Type Coercion: Error Unions#}
The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
- implicitly cast to the error union type:
+ coerce to the error union type:
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
-test "implicit casting to error unions" {
+test "coercion to error unions" {
const x: anyerror!i32 = 1234;
const y: anyerror!i32 = error.Failure;
@@ -4870,23 +4870,23 @@ test "implicit casting to error unions" {
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: Compile-Time Known Numbers#}
+ {#header_open|Type Coercion: Compile-Time Known Numbers#}
When a number is {#link|comptime#}-known to be representable in the destination type,
- it may be implicitly casted:
+ it may be coerced:
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
-test "implicit casting large integer type to smaller one when value is comptime known to fit" {
+test "coercing large integer type to smaller one when value is comptime known to fit" {
const x: u64 = 255;
const y: u8 = x;
assert(y == 255);
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: unions and enums#}
- Tagged unions can be implicitly cast to enums, and enums can be implicitly casted to tagged unions
+ {#header_open|Type Coercion: unions and enums#}
+
Tagged unions can be coerced to enums, and enums can be coerced to tagged unions
when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
{#link|void#}:
@@ -4906,7 +4906,7 @@ const U = union(E) {
Three,
};
-test "implicit casting between unions and enums" {
+test "coercion between unions and enums" {
var u = U{ .Two = 12.34 };
var e: E = u;
assert(e == E.Two);
@@ -4918,20 +4918,20 @@ test "implicit casting between unions and enums" {
{#code_end#}
{#see_also|union|enum#}
{#header_close#}
- {#header_open|Implicit Cast: Zero Bit Types#}
- {#link|Zero Bit Types#} may be implicitly casted to single-item {#link|Pointers#},
+ {#header_open|Type Coercion: Zero Bit Types#}
+
{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#},
regardless of const.
TODO document the reasoning for this
TODO document whether vice versa should work and why
{#code_begin|test#}
-test "implicit casting of zero bit types" {
+test "coercion of zero bit types" {
var x: void = {};
var y: *void = x;
//var z: void = y; // TODO
}
{#code_end#}
{#header_close#}
- {#header_open|Implicit Cast: undefined#}
+ {#header_open|Type Coercion: undefined#}
{#link|undefined#} can be cast to any type.
{#header_close#}
{#header_close#}
@@ -4976,7 +4976,7 @@ test "implicit casting of zero bit types" {
Some {#link|binary operations|Table of Operators#}
- This kind of type resolution chooses a type that all peer types can implicitly cast into. Here are
+ This kind of type resolution chooses a type that all peer types can coerce into. Here are
some examples:
{#code_begin|test#}
@@ -5007,8 +5007,8 @@ test "peer resolve array and const slice" {
comptime testPeerResolveArrayConstSlice(true);
}
fn testPeerResolveArrayConstSlice(b: bool) void {
- const value1 = if (b) "aoeu" else ([]const u8)("zz");
- const value2 = if (b) ([]const u8)("zz") else "aoeu";
+ const value1 = if (b) "aoeu" else @as([]const u8, "zz");
+ const value2 = if (b) @as([]const u8, "zz") else "aoeu";
assert(mem.eql(u8, value1, "aoeu"));
assert(mem.eql(u8, value2, "zz"));
}
@@ -5023,10 +5023,10 @@ test "peer type resolution: ?T and T" {
}
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
if (c) {
- return if (b) null else usize(0);
+ return if (b) null else @as(usize, 0);
}
- return usize(3);
+ return @as(usize, 3);
}
test "peer type resolution: [0]u8 and []const u8" {
@@ -5815,7 +5815,7 @@ test "printf too many arguments" {
Zig doesn't care whether the format argument is a string literal,
- only that it is a compile-time known value that is implicitly castable to a {#syntax#}[]const u8{#endsyntax#}:
+ only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}:
{#code_begin|exe|printf#}
const warn = @import("std").debug.warn;
@@ -6185,7 +6185,7 @@ fn func() void {
{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
- implicitly casts to {#syntax#}anyframe->T{#endsyntax#}.
+ coerces to {#syntax#}anyframe->T{#endsyntax#}.
There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.
@@ -7116,7 +7116,7 @@ test "field access by string" {
{#syntax#}@frame() *@Frame(func){#endsyntax#}
This function returns a pointer to the frame for a given function. This type
- can be {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyframe->T{#endsyntax#} and
+ can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and
to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type
of the function in scope.
@@ -7835,7 +7835,7 @@ test "vector @splat" {
const scalar: u32 = 5;
const result = @splat(4, scalar);
comptime assert(@typeOf(result) == @Vector(4, u32));
- assert(std.mem.eql(u32, ([4]u32)(result), [_]u32{ 5, 5, 5, 5 }));
+ assert(std.mem.eql(u32, @as([4]u32, result), [_]u32{ 5, 5, 5, 5 }));
}
{#code_end#}
@@ -8033,7 +8033,7 @@ test "integer truncation" {
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
- then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.
+ then this is semantically equivalent to {#link|Type Coercion#}.
{#header_close#}
@@ -8537,7 +8537,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Cast Truncates Data#}
At compile-time:
- {#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#}
+ {#code_begin|test_err|integer value 300 cannot be coerced to type 'u8'#}
comptime {
const spartan_count: u16 = 300;
const byte = @intCast(u8, spartan_count);
@@ -8673,7 +8673,7 @@ test "wraparound addition and subtraction" {
At compile-time:
{#code_begin|test_err|operation caused overflow#}
comptime {
- const x = @shlExact(u8(0b01010101), 2);
+ const x = @shlExact(@as(u8, 0b01010101), 2);
}
{#code_end#}
At runtime:
@@ -8691,7 +8691,7 @@ pub fn main() void {
At compile-time:
{#code_begin|test_err|exact shift shifted out 1 bits#}
comptime {
- const x = @shrExact(u8(0b10101010), 2);
+ const x = @shrExact(@as(u8, 0b10101010), 2);
}
{#code_end#}
At runtime:
@@ -9543,8 +9543,8 @@ const c = @cImport({
{#syntax#}[*c]T{#endsyntax#} - C pointer.
- Supports all the syntax of the other two pointer types.
- - Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}.
- When a C pointer is implicitly casted to a non-optional pointer, safety-checked
+
- Coerces to other pointer types, as well as {#link|Optional Pointers#}.
+ When a C pointer is coerced to a non-optional pointer, safety-checked
{#link|Undefined Behavior#} occurs if the address is 0.
- Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
@@ -9552,7 +9552,7 @@ const c = @cImport({
null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
is unnecessary as one can use normal {#link|Optional Pointers#}.
- - Supports {#link|implicit casting|Implicit Casts#} to and from integers.
+ - Supports {#link|Type Coercion#} to and from integers.
- Supports comparison with integers.
- Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}
please!
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index d5d73dabbc..543863c71e 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -266,7 +266,7 @@ pub const Loop = struct {
},
};
- const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
+ const empty_kevs = &[0]os.Kevent{};
for (self.eventfd_resume_nodes) |*eventfd_node, i| {
eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{
@@ -289,7 +289,7 @@ pub const Loop = struct {
.next = undefined,
};
self.available_eventfd_resume_nodes.push(eventfd_node);
- const kevent_array = (*const [1]os.Kevent)(&eventfd_node.data.kevent);
+ const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);
_ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);
eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE;
eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER;
@@ -305,7 +305,7 @@ pub const Loop = struct {
.data = 0,
.udata = @ptrToInt(&self.final_resume_node),
};
- const final_kev_arr = (*const [1]os.Kevent)(&self.os_data.final_kevent);
+ const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
_ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);
self.os_data.final_kevent.flags = os.EV_ENABLE;
self.os_data.final_kevent.fflags = os.NOTE_TRIGGER;
@@ -572,8 +572,8 @@ pub const Loop = struct {
eventfd_node.base.handle = next_tick_node.data;
switch (builtin.os) {
.macosx, .freebsd, .netbsd, .dragonfly => {
- const kevent_array = (*const [1]os.Kevent)(&eventfd_node.kevent);
- const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
+ const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
+ const empty_kevs = &[0]os.Kevent{};
_ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
self.next_tick_queue.unget(next_tick_node);
self.available_eventfd_resume_nodes.push(resume_stack_node);
@@ -695,8 +695,8 @@ pub const Loop = struct {
},
.macosx, .freebsd, .netbsd, .dragonfly => {
self.posixFsRequest(&self.os_data.fs_end_request);
- const final_kevent = (*const [1]os.Kevent)(&self.os_data.final_kevent);
- const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
+ const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
+ const empty_kevs = &[0]os.Kevent{};
// cannot fail because we already added it and this just enables it
_ = os.kevent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable;
return;
@@ -753,7 +753,7 @@ pub const Loop = struct {
},
.macosx, .freebsd, .netbsd, .dragonfly => {
var eventlist: [1]os.Kevent = undefined;
- const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
+ const empty_kevs = &[0]os.Kevent{};
const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
for (eventlist[0..count]) |ev| {
const resume_node = @intToPtr(*ResumeNode, ev.udata);
@@ -815,8 +815,8 @@ pub const Loop = struct {
self.os_data.fs_queue.put(request_node);
switch (builtin.os) {
.macosx, .freebsd, .netbsd, .dragonfly => {
- const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wake);
- const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
+ const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake);
+ const empty_kevs = &[0]os.Kevent{};
_ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
},
.linux => {
@@ -890,7 +890,7 @@ pub const Loop = struct {
}
},
.macosx, .freebsd, .netbsd, .dragonfly => {
- const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wait);
+ const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wait);
var out_kevs: [1]os.Kevent = undefined;
_ = os.kevent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
},
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 2a96fd3fbc..3f20c66102 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -584,7 +584,7 @@ pub const Dir = struct {
.FileBothDirectoryInformation,
w.FALSE,
null,
- if (self.first) w.BOOLEAN(w.TRUE) else w.BOOLEAN(w.FALSE),
+ if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
);
self.first = false;
if (io.Information == 0) return null;
diff --git a/lib/std/os.zig b/lib/std/os.zig
index c0f02c9a0b..68a3a6e9f6 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -1126,9 +1126,9 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;
const create_options_flags = if (want_rmdir_behavior)
- w.ULONG(w.FILE_DELETE_ON_CLOSE)
+ @as(w.ULONG, w.FILE_DELETE_ON_CLOSE)
else
- w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);
+ @as(w.ULONG, w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);
const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2);
var nt_name = w.UNICODE_STRING{
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 4342512941..9cdf8e9317 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -262,7 +262,7 @@ pub const ReadFileError = error{Unexpected};
pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize {
var index: usize = 0;
while (index < buffer.len) {
- const want_read_count = @intCast(DWORD, math.min(DWORD(maxInt(DWORD)), buffer.len - index));
+ const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index));
var amt_read: DWORD = undefined;
if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) {
switch (kernel32.GetLastError()) {
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index 214f75186f..951edf2d67 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -69,7 +69,7 @@ pub const FALSE = 0;
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
-pub const INVALID_FILE_ATTRIBUTES = DWORD(maxInt(DWORD));
+pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
pub const FILE_ALL_INFORMATION = extern struct {
BasicInformation: FILE_BASIC_INFORMATION,
@@ -571,16 +571,16 @@ pub const KF_FLAG_SIMPLE_IDLIST = 256;
pub const KF_FLAG_ALIAS_ONLY = -2147483648;
pub const S_OK = 0;
-pub const E_NOTIMPL = @bitCast(c_long, c_ulong(0x80004001));
-pub const E_NOINTERFACE = @bitCast(c_long, c_ulong(0x80004002));
-pub const E_POINTER = @bitCast(c_long, c_ulong(0x80004003));
-pub const E_ABORT = @bitCast(c_long, c_ulong(0x80004004));
-pub const E_FAIL = @bitCast(c_long, c_ulong(0x80004005));
-pub const E_UNEXPECTED = @bitCast(c_long, c_ulong(0x8000FFFF));
-pub const E_ACCESSDENIED = @bitCast(c_long, c_ulong(0x80070005));
-pub const E_HANDLE = @bitCast(c_long, c_ulong(0x80070006));
-pub const E_OUTOFMEMORY = @bitCast(c_long, c_ulong(0x8007000E));
-pub const E_INVALIDARG = @bitCast(c_long, c_ulong(0x80070057));
+pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001));
+pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002));
+pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003));
+pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004));
+pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005));
+pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF));
+pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005));
+pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006));
+pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E));
+pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057));
pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
@@ -873,4 +873,4 @@ pub const CURDIR = extern struct {
Handle: HANDLE,
};
-pub const DUPLICATE_SAME_ACCESS = 2;
\ No newline at end of file
+pub const DUPLICATE_SAME_ACCESS = 2;
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 0d3a99a683..f8d3a12343 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -774,12 +774,14 @@ fn transCCast(
if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
return transCPtrCast(rp, loc, dst_type, src_type, expr);
if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {
- const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
+ const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ _ = try appendToken(rp.c, .Comma, ",");
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
try builtin_node.params.push(expr);
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.op.Call.params.push(&builtin_node.base);
- cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
+ try cast_node.params.push(&builtin_node.base);
+ cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {
@@ -793,9 +795,11 @@ fn transCCast(
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
- const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
- try cast_node.op.Call.params.push(expr);
- cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
+ const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ _ = try appendToken(rp.c, .Comma, ",");
+ try cast_node.params.push(expr);
+ cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
diff --git a/src/ir.cpp b/src/ir.cpp
index bf558cb8a2..9225968ce9 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -6339,7 +6339,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
return irb->codegen->invalid_instruction;
if (result_loc_cast != nullptr) {
- IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast);
+ IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node,
+ init_value, result_loc_cast);
ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
}
@@ -9610,7 +9611,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
}
ir_add_error(ira, instruction,
- buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",
+ buf_sprintf("%s value %s cannot be coerced to type '%s'",
num_lit_str,
buf_ptr(val_buf),
buf_ptr(&other_type->name)));
@@ -13065,8 +13066,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ira->codegen->invalid_instruction;
}
-static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,
- ResultLoc *result_loc)
+static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *value, ZigType *expected_type, ResultLoc *result_loc)
{
assert(value);
assert(value != ira->codegen->invalid_instruction);
@@ -13080,11 +13081,11 @@ static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction
if (value->value.type->id == ZigTypeIdUnreachable)
return value;
- return ir_analyze_cast(ira, value, expected_type, value, result_loc);
+ return ir_analyze_cast(ira, source_instr, expected_type, value, result_loc);
}
static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
- return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
+ return ir_implicit_cast_with_result(ira, value, value, expected_type, nullptr);
}
static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
@@ -26068,7 +26069,7 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);
if (type_is_invalid(dest_type))
return ira->codegen->invalid_instruction;
- return ir_implicit_cast(ira, operand, dest_type);
+ return ir_implicit_cast_with_result(ira, &instruction->base, operand, dest_type, nullptr);
}
static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 6765bf45fb..2214dc7d54 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -221,6 +221,15 @@ static AstNode *trans_create_node_opaque(Context *c) {
return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
}
+static AstNode *trans_create_node_cast(Context *c, AstNode *dest_type, AstNode *operand) {
+ AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
+ node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, buf_create_from_str("as"));
+ node->data.fn_call_expr.modifier = CallModifierBuiltin;
+ node->data.fn_call_expr.params.append(dest_type);
+ node->data.fn_call_expr.params.append(operand);
+ return node;
+}
+
static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
@@ -337,14 +346,6 @@ static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
return trans_create_node_unsigned_negative(c, x, false);
}
-static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
- AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
- node->data.fn_call_expr.fn_ref_expr = dest;
- node->data.fn_call_expr.params.resize(1);
- node->data.fn_call_expr.params.items[0] = src;
- return node;
-}
-
static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
const char *type_name)
{
@@ -701,7 +702,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
addr_node->data.fn_call_expr.params.append(expr);
- return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);
+ return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), addr_node);
}
if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
@@ -712,7 +713,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
- return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
+ return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), expr);
}
static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
@@ -1527,7 +1528,7 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQua
AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
+ AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
}
@@ -1702,7 +1703,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
+ AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);
} else {
@@ -1733,7 +1734,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
+ AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
// operation_type(*_ref)
AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
@@ -2684,7 +2685,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)
// @TagType(Enum)(0)
AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
- AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero);
+ AstNode *casted_zero = trans_create_node_cast(c, tag_type, zero);
// @bitCast(Enum, @TagType(Enum)(0))
AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");
diff --git a/test/compare_output.zig b/test/compare_output.zig
index 4c0cc23632..4e55b374b6 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -145,23 +145,23 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ _ = c._setmode(1, c._O_BINARY);
\\ }
\\ _ = c.printf(c"0: %llu\n",
- \\ u64(0));
+ \\ @as(u64, 0));
\\ _ = c.printf(c"320402575052271: %llu\n",
- \\ u64(320402575052271));
+ \\ @as(u64, 320402575052271));
\\ _ = c.printf(c"0x01236789abcdef: %llu\n",
- \\ u64(0x01236789abcdef));
+ \\ @as(u64, 0x01236789abcdef));
\\ _ = c.printf(c"0xffffffffffffffff: %llu\n",
- \\ u64(0xffffffffffffffff));
+ \\ @as(u64, 0xffffffffffffffff));
\\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n",
- \\ u64(0x000000ffffffffffffffff));
+ \\ @as(u64, 0x000000ffffffffffffffff));
\\ _ = c.printf(c"0o1777777777777777777777: %llu\n",
- \\ u64(0o1777777777777777777777));
+ \\ @as(u64, 0o1777777777777777777777));
\\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n",
- \\ u64(0o0000001777777777777777777777));
+ \\ @as(u64, 0o0000001777777777777777777777));
\\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
- \\ u64(0b1111111111111111111111111111111111111111111111111111111111111111));
+ \\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
\\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
- \\ u64(0b0000001111111111111111111111111111111111111111111111111111111111111111));
+ \\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
\\
\\ _ = c.printf(c"\n");
\\
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index e3d80e4b63..0917c3dbb4 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -189,7 +189,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = 1 << &@as(u8, 10);
\\}
,
- "tmp.zig:2:23: error: shift amount has to be an integer type, but found '*u8'",
+ "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*u8'",
"tmp.zig:2:17: note: referenced here",
);
@@ -199,8 +199,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = &@as(u8, 1) << 10;
\\}
,
- "tmp.zig:2:18: error: bit shifting operation expected integer type, found '*u8'",
- "tmp.zig:2:22: note: referenced here",
+ "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*u8'",
+ "tmp.zig:2:27: note: referenced here",
);
cases.add(
@@ -245,7 +245,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
,
"tmp.zig:2:20: error: expected type 'u29', found 'bool'",
- "tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
+ "tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
);
cases.addCase(x: {
@@ -1243,7 +1243,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var ptr: [*c]u8 = x;
\\}
,
- "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be implicitly casted to type 'usize'",
+ "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'",
"tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",
);
@@ -1300,14 +1300,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var z = @truncate(u8, @as(u16, undefined));
\\}
,
- "tmp.zig:2:30: error: use of undefined value here causes undefined behavior",
+ "tmp.zig:2:27: error: use of undefined value here causes undefined behavior",
);
cases.addTest(
"return invalid type from test",
\\test "example" { return 1; }
,
- "tmp.zig:1:25: error: integer value 1 cannot be implicitly casted to type 'void'",
+ "tmp.zig:1:25: error: integer value 1 cannot be coerced to type 'void'",
);
cases.add(
@@ -1464,8 +1464,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var byte: u8 = spartan_count;
\\}
,
- "tmp.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'",
- "tmp.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'",
+ "tmp.zig:3:31: error: integer value 300 cannot be coerced to type 'u8'",
+ "tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'",
"tmp.zig:11:20: error: expected type 'u8', found 'u16'",
);
@@ -1498,7 +1498,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var x: i65536 = 1;
\\}
,
- "tmp.zig:2:31: error: integer value 65536 cannot be implicitly casted to type 'u16'",
+ "tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'",
"tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
);
@@ -1689,7 +1689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @floatToInt(i32, @as(i32, 54));
\\}
,
- "tmp.zig:2:35: error: expected float type, found 'i32'",
+ "tmp.zig:2:32: error: expected float type, found 'i32'",
);
cases.add(
@@ -1698,7 +1698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @floatToInt(i8, 200);
\\}
,
- "tmp.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'",
+ "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",
);
cases.add(
@@ -2207,7 +2207,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var rule_set = try Foo.init();
\\}
,
- "tmp.zig:2:13: error: expected type 'i32', found 'type'",
+ "tmp.zig:2:10: error: expected type 'i32', found 'type'",
);
cases.add(
@@ -2357,10 +2357,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"comptime slice of undefined pointer non-zero len",
\\export fn entry() void {
- \\ const slice = ([*]i32)(undefined)[0..1];
+ \\ const slice = @as([*]i32, undefined)[0..1];
\\}
,
- "tmp.zig:2:38: error: non-zero length slice of undefined pointer",
+ "tmp.zig:2:41: error: non-zero length slice of undefined pointer",
);
cases.add(
@@ -2660,7 +2660,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @as(usize, -10);
\\}
,
- "tmp.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",
+ "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",
);
cases.add(
@@ -3388,7 +3388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\export fn entry() void { f(true); g(true); }
,
- "tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
+ "tmp.zig:2:21: error: expected type 'i32', found 'void'",
"tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
);
@@ -3524,7 +3524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\export fn entry() void { _ = f(); }
,
- "tmp.zig:2:15: error: unreachable code",
+ "tmp.zig:2:12: error: unreachable code",
);
cases.add(
@@ -3765,7 +3765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\const x : u8 = 300;
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
,
- "tmp.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",
+ "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",
);
cases.add(
@@ -3897,8 +3897,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
"tmp.zig:1:21: error: division by zero",
"tmp.zig:2:25: error: division by zero",
- "tmp.zig:3:22: error: division by zero",
- "tmp.zig:4:26: error: division by zero",
+ "tmp.zig:3:27: error: division by zero",
+ "tmp.zig:4:31: error: division by zero",
);
cases.add(
@@ -4908,7 +4908,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var vga_mem: u16 = 0xB8000;
\\}
,
- "tmp.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'",
+ "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",
);
cases.add(
@@ -5080,7 +5080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"pass const ptr to mutable ptr fn",
\\fn foo() bool {
- \\ const a = ([]const u8)("a",);
+ \\ const a = @as([]const u8, "a",);
\\ const b = &a;
\\ return ptrEql(b, b);
\\}
@@ -5584,7 +5584,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ return @as(i32, 12.34);
\\}
,
- "tmp.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
+ "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
);
cases.add(
@@ -5671,16 +5671,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ var foo = Foo { .a = 1, .b = 10 };
\\ foo.b += 1;
- \\ bar((*[1]u32)(&foo.b)[0..]);
+ \\ bar(@as(*[1]u32, &foo.b)[0..]);
\\}
\\
\\fn bar(x: []u32) void {
\\ x[0] += 1;
\\}
,
- "tmp.zig:9:18: error: cast increases pointer alignment",
- "tmp.zig:9:23: note: '*align(1) u32' has alignment 1",
- "tmp.zig:9:18: note: '*[1]u32' has alignment 4",
+ "tmp.zig:9:9: error: cast increases pointer alignment",
+ "tmp.zig:9:26: note: '*align(1) u32' has alignment 1",
+ "tmp.zig:9:9: note: '*[1]u32' has alignment 4",
);
cases.add(
@@ -5702,7 +5702,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ @alignCast(4, @as(u32, 3));
\\}
,
- "tmp.zig:2:22: error: expected pointer or slice, found 'u32'",
+ "tmp.zig:2:19: error: expected pointer or slice, found 'u32'",
);
cases.add(
@@ -5740,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
);
cases.add(
- "wrong pointer implicitly casted to pointer to @OpaqueType()",
+ "wrong pointer coerced to pointer to @OpaqueType()",
\\const Derp = @OpaqueType();
\\extern fn bar(d: *Derp) void;
\\export fn foo() void {
@@ -5793,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
"tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
"tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
- "tmp.zig:26:4: error: unreachable code",
+ "tmp.zig:26:22: error: unreachable code",
);
cases.add(
@@ -5803,7 +5803,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
\\}
,
- "tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
+ "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
);
cases.add(
@@ -5813,7 +5813,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ @export("entry", entry, @as(u32, 1234));
\\}
,
- "tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
+ "tmp.zig:3:29: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
);
cases.add(
@@ -6185,7 +6185,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\};
\\
\\export fn entry() void {
- \\ var y = u3(3);
+ \\ var y = @as(u3, 3);
\\ var x = @intToEnum(Small, y);
\\}
,
@@ -6722,8 +6722,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:1:1: note: declared here",
);
- // fixed bug #2032
- cases.add(
+ cases.add( // fixed bug #2032
"compile diagnostic string for top level decl type",
\\export fn entry() void {
\\ var foo: u32 = @This(){};
@@ -6731,6 +6730,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
"tmp.zig:2:27: error: expected type 'u32', found '(root)'",
"tmp.zig:1:1: note: (root) declared here",
- "tmp.zig:2:5: note: referenced here",
);
}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 54e4131155..17b089d1db 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -144,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn foo() void;
\\pub fn bar() void {
\\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
- \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr)));
+ \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
\\}
);
@@ -567,37 +567,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("l integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_long(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_long, 32);
);
cases.add("ul integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_ulong(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
);
cases.add("lu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_ulong(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
);
cases.add("ll integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_longlong(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
);
cases.add("ull integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
);
cases.add("llu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
- \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
+ \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
);
cases.add("zig keywords in C code",
@@ -677,7 +677,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = _arg_a;
\\ var i: c_int = 0;
\\ while (a > @as(c_uint, 0)) {
- \\ a >>= @import("std").math.Log2Int(c_uint)(1);
+ \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
\\ }
\\ return i;
\\}
@@ -849,7 +849,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = _arg_a;
\\ var i: c_int = 0;
\\ while (a > @as(c_uint, 0)) {
- \\ a >>= u5(1);
+ \\ a >>= @as(u5, 1);
\\ }
\\ return i;
\\}
@@ -1027,7 +1027,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub export fn foo() c_int {
- \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
+ \\ return (1 << @as(@import("std").math.Log2Int(c_int), 2)) >> @as(@import("std").math.Log2Int(c_int), 1);
\\}
);
@@ -1076,14 +1076,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ _ref.* = (_ref.* ^ 1);
\\ break :x _ref.*;
\\ });
- \\ a >>= @import("std").math.Log2Int(c_int)((x: {
+ \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));
+ \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
\\ break :x _ref.*;
\\ }));
- \\ a <<= @import("std").math.Log2Int(c_int)((x: {
+ \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));
+ \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
\\ break :x _ref.*;
\\ }));
\\}
@@ -1134,14 +1134,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ _ref.* = (_ref.* ^ @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
- \\ a >>= @import("std").math.Log2Int(c_uint)((x: {
+ \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));
+ \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
\\ break :x _ref.*;
\\ }));
- \\ a <<= @import("std").math.Log2Int(c_uint)((x: {
+ \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
\\ const _ref = &a;
- \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));
+ \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
\\ break :x _ref.*;
\\ }));
\\}
@@ -1539,7 +1539,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("macro pointer cast",
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
,
- \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*c]NRF_GPIO_Type)(NRF_GPIO_BASE);
+ \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
);
cases.add("if on non-bool",
@@ -1564,7 +1564,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != null) return 2;
- \\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;
+ \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
\\ return 4;
\\}
);
@@ -1652,37 +1652,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.addC(
"l integer suffix after 0 (zero) in macro definition",
"#define ZERO 0L",
- "pub const ZERO = c_long(0);",
+ "pub const ZERO = @as(c_long, 0);",
);
cases.addC(
"ul integer suffix after 0 (zero) in macro definition",
"#define ZERO 0UL",
- "pub const ZERO = c_ulong(0);",
+ "pub const ZERO = @as(c_ulong, 0);",
);
cases.addC(
"lu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LU",
- "pub const ZERO = c_ulong(0);",
+ "pub const ZERO = @as(c_ulong, 0);",
);
cases.addC(
"ll integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LL",
- "pub const ZERO = c_longlong(0);",
+ "pub const ZERO = @as(c_longlong, 0);",
);
cases.addC(
"ull integer suffix after 0 (zero) in macro definition",
"#define ZERO 0ULL",
- "pub const ZERO = c_ulonglong(0);",
+ "pub const ZERO = @as(c_ulonglong, 0);",
);
cases.addC(
"llu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LLU",
- "pub const ZERO = c_ulonglong(0);",
+ "pub const ZERO = @as(c_ulonglong, 0);",
);
cases.addC(
From f7b1e02158550a8df3c189299da88568b381f5b1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Nov 2019 17:05:20 -0500
Subject: [PATCH 042/129] fix type cast in windows child process code
---
lib/std/child_process.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig
index e6d81aeb4f..e6e284db18 100644
--- a/lib/std/child_process.zig
+++ b/lib/std/child_process.zig
@@ -219,7 +219,7 @@ pub const ChildProcess = struct {
fn waitUnwrappedWindows(self: *ChildProcess) !void {
const result = windows.WaitForSingleObject(self.handle, windows.INFINITE);
- self.term = (SpawnError!Term)(x: {
+ self.term = @as(SpawnError!Term, x: {
var exit_code: windows.DWORD = undefined;
if (windows.kernel32.GetExitCodeProcess(self.handle, &exit_code) == 0) {
break :x Term{ .Unknown = 0 };
From 5d05cfcfe6144a7f49f57cb376863edd0059d9ca Mon Sep 17 00:00:00 2001
From: Luna
Date: Fri, 8 Nov 2019 19:35:04 -0300
Subject: [PATCH 043/129] rename IpAddress to Address, add Address.unix
---
lib/std/net.zig | 85 ++++++++++++++++++++++----------------------
lib/std/net/test.zig | 30 ++++++++--------
2 files changed, 58 insertions(+), 57 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 95036707b6..d805aeb238 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -10,15 +10,16 @@ test "" {
_ = @import("net/test.zig");
}
-pub const IpAddress = extern union {
+pub const Address = extern union {
any: os.sockaddr,
in: os.sockaddr_in,
in6: os.sockaddr_in6,
+ unix: os.sockaddr_un,
// TODO this crashed the compiler
//pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
- pub fn parse(name: []const u8, port: u16) !IpAddress {
+ pub fn parseIp(name: []const u8, port: u16) !Address {
if (parseIp4(name, port)) |ip4| return ip4 else |err| switch (err) {
error.Overflow,
error.InvalidEnd,
@@ -39,7 +40,7 @@ pub const IpAddress = extern union {
return error.InvalidIPAddressFormat;
}
- pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !IpAddress {
+ pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
switch (family) {
os.AF_INET => return parseIp4(name, port),
os.AF_INET6 => return parseIp6(name, port),
@@ -48,8 +49,8 @@ pub const IpAddress = extern union {
}
}
- pub fn parseIp6(buf: []const u8, port: u16) !IpAddress {
- var result = IpAddress{
+ pub fn parseIp6(buf: []const u8, port: u16) !Address {
+ var result = Address{
.in6 = os.sockaddr_in6{
.scope_id = 0,
.port = mem.nativeToBig(u16, port),
@@ -154,8 +155,8 @@ pub const IpAddress = extern union {
}
}
- pub fn parseIp4(buf: []const u8, port: u16) !IpAddress {
- var result = IpAddress{
+ pub fn parseIp4(buf: []const u8, port: u16) !Address {
+ var result = Address{
.in = os.sockaddr_in{
.port = mem.nativeToBig(u16, port),
.addr = undefined,
@@ -194,8 +195,8 @@ pub const IpAddress = extern union {
return error.Incomplete;
}
- pub fn initIp4(addr: [4]u8, port: u16) IpAddress {
- return IpAddress{
+ pub fn initIp4(addr: [4]u8, port: u16) Address {
+ return Address{
.in = os.sockaddr_in{
.port = mem.nativeToBig(u16, port),
.addr = @ptrCast(*align(1) const u32, &addr).*,
@@ -203,8 +204,8 @@ pub const IpAddress = extern union {
};
}
- pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) IpAddress {
- return IpAddress{
+ pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
+ return Address{
.in6 = os.sockaddr_in6{
.addr = addr,
.port = mem.nativeToBig(u16, port),
@@ -215,7 +216,7 @@ pub const IpAddress = extern union {
}
/// Returns the port in native endian.
- pub fn getPort(self: IpAddress) u16 {
+ pub fn getPort(self: Address) u16 {
const big_endian_port = switch (self.any.family) {
os.AF_INET => self.in.port,
os.AF_INET6 => self.in6.port,
@@ -225,7 +226,7 @@ pub const IpAddress = extern union {
}
/// `port` is native-endian.
- pub fn setPort(self: *IpAddress, port: u16) void {
+ pub fn setPort(self: *Address, port: u16) void {
const ptr = switch (self.any.family) {
os.AF_INET => &self.in.port,
os.AF_INET6 => &self.in6.port,
@@ -237,16 +238,16 @@ pub const IpAddress = extern union {
/// Asserts that `addr` is an IP address.
/// This function will read past the end of the pointer, with a size depending
/// on the address family.
- pub fn initPosix(addr: *align(4) const os.sockaddr) IpAddress {
+ pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
switch (addr.family) {
- os.AF_INET => return IpAddress{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
- os.AF_INET6 => return IpAddress{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
+ os.AF_INET => return Address{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
+ os.AF_INET6 => return Address{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
else => unreachable,
}
}
pub fn format(
- self: IpAddress,
+ self: Address,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
context: var,
@@ -271,7 +272,7 @@ pub const IpAddress = extern union {
},
os.AF_INET6 => {
const port = mem.bigToNative(u16, self.in6.port);
- if (mem.eql(u8, self.in6.addr[0..12], [_]u8{0,0,0,0,0,0,0,0,0,0,0xff,0xff})) {
+ if (mem.eql(u8, self.in6.addr[0..12], [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
try std.fmt.format(
context,
Errors,
@@ -318,13 +319,13 @@ pub const IpAddress = extern union {
}
}
- pub fn eql(a: IpAddress, b: IpAddress) bool {
+ pub fn eql(a: Address, b: Address) bool {
const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];
const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];
return mem.eql(u8, a_bytes, b_bytes);
}
- fn getOsSockLen(self: IpAddress) os.socklen_t {
+ fn getOsSockLen(self: Address) os.socklen_t {
switch (self.any.family) {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
@@ -358,7 +359,7 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
pub const AddressList = struct {
arena: std.heap.ArenaAllocator,
- addrs: []IpAddress,
+ addrs: []Address,
canon_name: ?[]u8,
fn deinit(self: *AddressList) void {
@@ -381,7 +382,7 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)
return tcpConnectToAddress(addrs[0], port);
}
-pub fn tcpConnectToAddress(address: IpAddress) !fs.File {
+pub fn tcpConnectToAddress(address: Address) !fs.File {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
@@ -456,13 +457,13 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
}
break :blk count;
};
- result.addrs = try arena.alloc(IpAddress, addr_count);
+ result.addrs = try arena.alloc(Address, addr_count);
var it: ?*os.addrinfo = res;
var i: usize = 0;
while (it) |info| : (it = info.next) {
const addr = info.addr orelse continue;
- result.addrs[i] = IpAddress.initPosix(@alignCast(4, addr));
+ result.addrs[i] = Address.initPosix(@alignCast(4, addr));
if (info.canonname) |n| {
if (result.canon_name == null) {
@@ -485,7 +486,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
- result.addrs = try arena.alloc(IpAddress, lookup_addrs.len);
+ result.addrs = try arena.alloc(Address, lookup_addrs.len);
if (!canon.isNull()) {
result.canon_name = canon.toOwnedSlice();
}
@@ -501,7 +502,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
}
const LookupAddr = struct {
- addr: IpAddress,
+ addr: Address,
sortkey: i32 = 0,
};
@@ -524,7 +525,7 @@ fn linuxLookupName(
if (opt_name) |name| {
// reject empty name and check len so it fits into temp bufs
try canon.replaceContents(name);
- if (IpAddress.parseExpectingFamily(name, family, port)) |addr| {
+ if (Address.parseExpectingFamily(name, family, port)) |addr| {
try addrs.append(LookupAddr{ .addr = addr });
} else |name_err| if ((flags & std.c.AI_NUMERICHOST) != 0) {
return name_err;
@@ -751,23 +752,23 @@ fn linuxLookupNameFromNull(
if ((flags & std.c.AI_PASSIVE) != 0) {
if (family != os.AF_INET6) {
(try addrs.addOne()).* = LookupAddr{
- .addr = IpAddress.initIp4([1]u8{0} ** 4, port),
+ .addr = Address.initIp4([1]u8{0} ** 4, port),
};
}
if (family != os.AF_INET) {
(try addrs.addOne()).* = LookupAddr{
- .addr = IpAddress.initIp6([1]u8{0} ** 16, port, 0, 0),
+ .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),
};
}
} else {
if (family != os.AF_INET6) {
(try addrs.addOne()).* = LookupAddr{
- .addr = IpAddress.initIp4([4]u8{ 127, 0, 0, 1 }, port),
+ .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),
};
}
if (family != os.AF_INET) {
(try addrs.addOne()).* = LookupAddr{
- .addr = IpAddress.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
+ .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
};
}
}
@@ -812,7 +813,7 @@ fn linuxLookupNameFromHosts(
}
} else continue;
- const addr = IpAddress.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {
+ const addr = Address.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {
error.Overflow,
error.InvalidEnd,
error.InvalidCharacter,
@@ -1033,7 +1034,7 @@ fn linuxLookupNameFromNumericUnspec(
name: []const u8,
port: u16,
) !void {
- const addr = try IpAddress.parse(name, port);
+ const addr = try Address.parse(name, port);
(try addrs.addOne()).* = LookupAddr{ .addr = addr };
}
@@ -1049,7 +1050,7 @@ fn resMSendRc(
var sl: os.socklen_t = @sizeOf(os.sockaddr_in);
var family: os.sa_family_t = os.AF_INET;
- var ns_list = std.ArrayList(IpAddress).init(rc.ns.allocator);
+ var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
defer ns_list.deinit();
try ns_list.resize(rc.ns.len);
@@ -1065,8 +1066,8 @@ fn resMSendRc(
}
// Get local address and open/bind a socket
- var sa: IpAddress = undefined;
- @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(IpAddress));
+ var sa: Address = undefined;
+ @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
sa.any.family = family;
const flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK;
const fd = os.socket(family, flags, 0) catch |err| switch (err) {
@@ -1224,7 +1225,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
const new_addr = try ctx.addrs.addOne();
new_addr.* = LookupAddr{
// TODO slice [0..4] to make this *[4]u8 without @ptrCast
- .addr = IpAddress.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),
+ .addr = Address.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),
};
},
os.RR_AAAA => {
@@ -1232,7 +1233,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
const new_addr = try ctx.addrs.addOne();
new_addr.* = LookupAddr{
// TODO slice [0..16] to make this *[16]u8 without @ptrCast
- .addr = IpAddress.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),
+ .addr = Address.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),
};
},
os.RR_CNAME => {
@@ -1253,7 +1254,7 @@ pub const TcpServer = struct {
kernel_backlog: u32,
/// `undefined` until `listen` returns successfully.
- listen_address: IpAddress,
+ listen_address: Address,
sockfd: ?os.fd_t,
@@ -1280,7 +1281,7 @@ pub const TcpServer = struct {
self.* = undefined;
}
- pub fn listen(self: *TcpServer, address: IpAddress) !void {
+ pub fn listen(self: *TcpServer, address: Address) !void {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
@@ -1330,8 +1331,8 @@ pub const TcpServer = struct {
pub fn accept(self: *TcpServer) AcceptError!fs.File {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const accept_flags = nonblock | os.SOCK_CLOEXEC;
- var accepted_addr: IpAddress = undefined;
- var adr_len: os.socklen_t = @sizeOf(IpAddress);
+ var accepted_addr: Address = undefined;
+ var adr_len: os.socklen_t = @sizeOf(Address);
if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {
return fs.File.openHandle(fd);
} else |err| switch (err) {
diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig
index 90986049da..8ea3218e01 100644
--- a/lib/std/net/test.zig
+++ b/lib/std/net/test.zig
@@ -28,17 +28,17 @@ test "parse and render IPv6 addresses" {
"::ffff:123.5.123.5",
};
for (ips) |ip, i| {
- var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;
+ var addr = net.Address.parseIp6(ip, 0) catch unreachable;
var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
std.testing.expect(std.mem.eql(u8, printed[i], newIp[1 .. newIp.len - 3]));
}
- testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6(":::", 0));
- testing.expectError(error.Overflow, net.IpAddress.parseIp6("FF001::FB", 0));
- testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));
- testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
- testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));
- testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0));
+ testing.expectError(error.InvalidCharacter, net.Address.parseIp6(":::", 0));
+ testing.expectError(error.Overflow, net.Address.parseIp6("FF001::FB", 0));
+ testing.expectError(error.InvalidCharacter, net.Address.parseIp6("FF01::Fb:zig", 0));
+ testing.expectError(error.InvalidEnd, net.Address.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
+ testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
+ testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
}
test "parse and render IPv4 addresses" {
@@ -50,16 +50,16 @@ test "parse and render IPv4 addresses" {
"123.255.0.91",
"127.0.0.1",
}) |ip| {
- var addr = net.IpAddress.parseIp4(ip, 0) catch unreachable;
+ var addr = net.Address.parseIp4(ip, 0) catch unreachable;
var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));
}
- testing.expectError(error.Overflow, net.IpAddress.parseIp4("256.0.0.1", 0));
- testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("x.0.0.1", 0));
- testing.expectError(error.InvalidEnd, net.IpAddress.parseIp4("127.0.0.1.1", 0));
- testing.expectError(error.Incomplete, net.IpAddress.parseIp4("127.0.0.", 0));
- testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("100..0.1", 0));
+ testing.expectError(error.Overflow, net.Address.parseIp4("256.0.0.1", 0));
+ testing.expectError(error.InvalidCharacter, net.Address.parseIp4("x.0.0.1", 0));
+ testing.expectError(error.InvalidEnd, net.Address.parseIp4("127.0.0.1.1", 0));
+ testing.expectError(error.Incomplete, net.Address.parseIp4("127.0.0.", 0));
+ testing.expectError(error.InvalidCharacter, net.Address.parseIp4("100..0.1", 0));
}
test "resolve DNS" {
@@ -91,7 +91,7 @@ test "listen on a port, send bytes, receive bytes" {
}
// TODO doing this at comptime crashed the compiler
- const localhost = net.IpAddress.parse("127.0.0.1", 0);
+ const localhost = net.Address.parse("127.0.0.1", 0);
var server = net.TcpServer.init(net.TcpServer.Options{});
defer server.deinit();
@@ -104,7 +104,7 @@ test "listen on a port, send bytes, receive bytes" {
try await client_frame;
}
-fn testClient(addr: net.IpAddress) anyerror!void {
+fn testClient(addr: net.Address) anyerror!void {
const socket_file = try net.tcpConnectToAddress(addr);
defer socket_file.close();
From 9458620e18cb89b71cd0ad2755b9a7ae4f63e846 Mon Sep 17 00:00:00 2001
From: Luna
Date: Fri, 8 Nov 2019 19:59:30 -0300
Subject: [PATCH 044/129] replace Address.parse Address.parseIp
---
lib/std/net.zig | 4 ++--
lib/std/net/test.zig | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index d805aeb238..215c0ed6fa 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -44,7 +44,7 @@ pub const Address = extern union {
switch (family) {
os.AF_INET => return parseIp4(name, port),
os.AF_INET6 => return parseIp6(name, port),
- os.AF_UNSPEC => return parse(name, port),
+ os.AF_UNSPEC => return parseIp(name, port),
else => unreachable,
}
}
@@ -1034,7 +1034,7 @@ fn linuxLookupNameFromNumericUnspec(
name: []const u8,
port: u16,
) !void {
- const addr = try Address.parse(name, port);
+ const addr = try Address.parseIp(name, port);
(try addrs.addOne()).* = LookupAddr{ .addr = addr };
}
diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig
index 8ea3218e01..1bdd209837 100644
--- a/lib/std/net/test.zig
+++ b/lib/std/net/test.zig
@@ -91,7 +91,7 @@ test "listen on a port, send bytes, receive bytes" {
}
// TODO doing this at comptime crashed the compiler
- const localhost = net.Address.parse("127.0.0.1", 0);
+ const localhost = net.Address.parseIp("127.0.0.1", 0);
var server = net.TcpServer.init(net.TcpServer.Options{});
defer server.deinit();
From 8c8078513e60df7e017f91193524384e4e9640ca Mon Sep 17 00:00:00 2001
From: dimenus
Date: Fri, 8 Nov 2019 18:16:03 -0600
Subject: [PATCH 045/129] missed cast in std/target.zig
---
lib/std/target.zig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/std/target.zig b/lib/std/target.zig
index d84ef47347..4d600d4d38 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -319,7 +319,7 @@ pub const Target = union(enum) {
inline for (info.Union.fields) |field| {
if (mem.eql(u8, text, field.name)) {
if (field.field_type == void) {
- return (Arch)(@field(Arch, field.name));
+ return @as(Arch, @field(Arch, field.name));
} else {
const sub_info = @typeInfo(field.field_type);
inline for (sub_info.Enum.fields) |sub_field| {
@@ -581,7 +581,7 @@ pub const Target = union(enum) {
};
pub fn getExternalExecutor(self: Target) Executor {
- if (@as(@TagType(Target),self) == .Native) return .native;
+ if (@as(@TagType(Target), self) == .Native) return .native;
// If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
if (self.getOs() == builtin.os) {
From c2325053a86f4350e20ea3b476c7efeb942d8438 Mon Sep 17 00:00:00 2001
From: Luna
Date: Fri, 8 Nov 2019 21:44:17 -0300
Subject: [PATCH 046/129] add Address.parseUnix and Address.format support for
AF_UNIX
---
lib/std/net.zig | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 215c0ed6fa..af3ac5475d 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -14,7 +14,7 @@ pub const Address = extern union {
any: os.sockaddr,
in: os.sockaddr_in,
in6: os.sockaddr_in6,
- unix: os.sockaddr_un,
+ un: os.sockaddr_un,
// TODO this crashed the compiler
//pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
@@ -40,6 +40,18 @@ pub const Address = extern union {
return error.InvalidIPAddressFormat;
}
+ pub fn parseUnix(path: []const u8) !Address {
+ var sock_addr = os.sockaddr_un{
+ .family = os.AF_UNIX,
+ .path = undefined,
+ };
+
+ if (path.len > sock_addr.path.len) return error.NameTooLong;
+ mem.copy(u8, &sock_addr.path, path);
+
+ return Address{ .un = sock_addr };
+ }
+
pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
switch (family) {
os.AF_INET => return parseIp4(name, port),
@@ -315,6 +327,9 @@ pub const Address = extern union {
}
try std.fmt.format(context, Errors, output, "]:{}", port);
},
+ os.AF_UNIX => {
+ try std.fmt.format(context, Errors, output, "{}", self.un.path);
+ },
else => unreachable,
}
}
From def5462d053d744a9f4c2c6874355a23d3371b3d Mon Sep 17 00:00:00 2001
From: Sahnvour
Date: Thu, 10 Oct 2019 21:58:47 +0200
Subject: [PATCH 047/129] build: initial support for using vcpkg libraries
---
lib/std/build.zig | 82 +++++++++++++++++++++++++++++++++++++++++++++-
lib/std/target.zig | 34 +++++++++++++++++++
2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 899e74105b..3388e35128 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -53,7 +53,7 @@ pub const Builder = struct {
release_mode: ?builtin.Mode,
is_release: bool,
override_lib_dir: ?[]const u8,
-
+ vcpkg_root: VcpkgRoot,
pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
const PkgConfigError = error{
@@ -159,6 +159,7 @@ pub const Builder = struct {
.is_release = false,
.override_lib_dir = null,
.install_path = undefined,
+ .vcpkg_root = VcpkgRoot{ .Unattempted = {} },
};
try self.top_level_steps.append(&self.install_tls);
try self.top_level_steps.append(&self.uninstall_tls);
@@ -1046,6 +1047,7 @@ pub const LibExeObjStep = struct {
output_dir: ?[]const u8,
need_system_paths: bool,
is_linking_libc: bool = false,
+ vcpkg_bin_path: ?[]const u8 = null,
installed_path: ?[]const u8,
install_step: ?*InstallArtifactStep,
@@ -1264,6 +1266,11 @@ pub const LibExeObjStep = struct {
// option is supplied.
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
run_step.addArtifactArg(exe);
+
+ if (exe.vcpkg_bin_path) |path| {
+ run_step.addPathDir(path);
+ }
+
return run_step;
}
@@ -1569,6 +1576,43 @@ pub const LibExeObjStep = struct {
}) catch unreachable;
}
+ /// If Vcpkg was found on the system, it will be added to include and lib
+ /// paths for the specified target.
+ pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void {
+ // Ideally in the Unattempted case we would call the function recursively
+ // after findVcpkgRoot and have only one switch statement, but the compiler
+ // cannot resolve the error set.
+ switch (self.builder.vcpkg_root) {
+ .Unattempted => {
+ self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root|
+ VcpkgRoot{ .Found = root }
+ else
+ .NotFound;
+ },
+ .NotFound => return error.VcpkgNotFound,
+ .Found => {},
+ }
+
+ switch (self.builder.vcpkg_root) {
+ .Unattempted => unreachable,
+ .NotFound => return error.VcpkgNotFound,
+ .Found => |root| {
+ const allocator = self.builder.allocator;
+ const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
+ defer self.builder.allocator.free(triplet);
+
+ const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" });
+ errdefer allocator.free(include_path);
+ try self.include_dirs.append(IncludeDir{ .RawPath = include_path });
+
+ const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" });
+ try self.lib_paths.append(lib_path);
+
+ self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" });
+ },
+ }
+ }
+
pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
assert(self.kind == Kind.Test);
self.exec_cmd_args = args;
@@ -2341,6 +2385,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
};
}
+/// Returned slice must be freed by the caller.
+fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {
+ const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
+ defer allocator.free(appdata_path);
+
+ const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" });
+ defer allocator.free(path_file);
+
+ const file = fs.File.openRead(path_file) catch return null;
+ defer file.close();
+
+ const size = @intCast(usize, try file.getEndPos());
+ const vcpkg_path = try allocator.alloc(u8, size);
+ const size_read = try file.read(vcpkg_path);
+ std.debug.assert(size == size_read);
+
+ return vcpkg_path;
+}
+
+const VcpkgRoot = union(VcpkgRootStatus) {
+ Unattempted: void,
+ NotFound: void,
+ Found: []const u8,
+};
+
+const VcpkgRootStatus = enum {
+ Unattempted,
+ NotFound,
+ Found,
+};
+
+pub const VcpkgLinkage = enum {
+ Static,
+ Dynamic,
+};
+
pub const InstallDir = enum {
Prefix,
Lib,
diff --git a/lib/std/target.zig b/lib/std/target.zig
index 4d600d4d38..5c0ac3d905 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -218,6 +218,40 @@ pub const Target = union(enum) {
);
}
+ /// Returned slice must be freed by the caller.
+ pub fn vcpkgTriplet(allocator: *mem.Allocator, target: Target, linkage: std.build.VcpkgLinkage) ![]const u8 {
+ const arch = switch (target.getArch()) {
+ .i386 => "x86",
+ .x86_64 => "x64",
+
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ .aarch64_32,
+ => "arm",
+
+ .aarch64,
+ .aarch64_be,
+ => "arm64",
+
+ else => return error.VcpkgNoSuchArchitecture,
+ };
+
+ const os = switch (target.getOs()) {
+ .windows => "windows",
+ .linux => "linux",
+ .macosx => "macos",
+ else => return error.VcpkgNoSuchOs,
+ };
+
+ if (linkage == .Static) {
+ return try mem.join(allocator, "-", [_][]const u8{ arch, os, "static" });
+ } else {
+ return try mem.join(allocator, "-", [_][]const u8{ arch, os });
+ }
+ }
+
pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {
// TODO is there anything else worthy of the description that is not
// already captured in the triple?
From f4d8dc278b312fc3eccf33a37cfe89c7c012d6fd Mon Sep 17 00:00:00 2001
From: Luna
Date: Sat, 9 Nov 2019 12:40:56 -0300
Subject: [PATCH 048/129] rename TcpServer -> StreamServer
- add AF_UNIX support to getOsSockLen
---
lib/std/net.zig | 23 +++++++++++++++--------
lib/std/net/test.zig | 4 ++--
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index af3ac5475d..0f7c76438f 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -46,6 +46,9 @@ pub const Address = extern union {
.path = undefined,
};
+ // this enables us to have the proper length of the socket in getOsSockLen
+ mem.zero(&sock_addr.path);
+
if (path.len > sock_addr.path.len) return error.NameTooLong;
mem.copy(u8, &sock_addr.path, path);
@@ -344,6 +347,10 @@ pub const Address = extern union {
switch (self.any.family) {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
+ os.AF_UNIX => blk: {
+ const path_len = std.mem.len(self.un.path.len);
+ break :blk @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
+ },
else => unreachable,
}
}
@@ -1264,7 +1271,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
}
}
-pub const TcpServer = struct {
+pub const StreamServer = struct {
/// Copied from `Options` on `init`.
kernel_backlog: u32,
@@ -1282,21 +1289,21 @@ pub const TcpServer = struct {
/// After this call succeeds, resources have been acquired and must
/// be released with `deinit`.
- pub fn init(options: Options) TcpServer {
- return TcpServer{
+ pub fn init(options: Options) StreamServer {
+ return StreamServer{
.sockfd = null,
.kernel_backlog = options.kernel_backlog,
.listen_address = undefined,
};
}
- /// Release all resources. The `TcpServer` memory becomes `undefined`.
- pub fn deinit(self: *TcpServer) void {
+ /// Release all resources. The `StreamServer` memory becomes `undefined`.
+ pub fn deinit(self: *StreamServer) void {
self.close();
self.* = undefined;
}
- pub fn listen(self: *TcpServer, address: Address) !void {
+ pub fn listen(self: *StreamServer, address: Address) !void {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
@@ -1315,7 +1322,7 @@ pub const TcpServer = struct {
/// Stop listening. It is still necessary to call `deinit` after stopping listening.
/// Calling `deinit` will automatically call `close`. It is safe to call `close` when
/// not listening.
- pub fn close(self: *TcpServer) void {
+ pub fn close(self: *StreamServer) void {
if (self.sockfd) |fd| {
os.close(fd);
self.sockfd = null;
@@ -1343,7 +1350,7 @@ pub const TcpServer = struct {
} || os.UnexpectedError;
/// If this function succeeds, the returned `fs.File` is a caller-managed resource.
- pub fn accept(self: *TcpServer) AcceptError!fs.File {
+ pub fn accept(self: *StreamServer) AcceptError!fs.File {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const accept_flags = nonblock | os.SOCK_CLOEXEC;
var accepted_addr: Address = undefined;
diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig
index 1bdd209837..49dbdbb218 100644
--- a/lib/std/net/test.zig
+++ b/lib/std/net/test.zig
@@ -93,7 +93,7 @@ test "listen on a port, send bytes, receive bytes" {
// TODO doing this at comptime crashed the compiler
const localhost = net.Address.parseIp("127.0.0.1", 0);
- var server = net.TcpServer.init(net.TcpServer.Options{});
+ var server = net.StreamServer.init(net.StreamServer.Options{});
defer server.deinit();
try server.listen(localhost);
@@ -114,7 +114,7 @@ fn testClient(addr: net.Address) anyerror!void {
testing.expect(mem.eql(u8, msg, "hello from server\n"));
}
-fn testServer(server: *net.TcpServer) anyerror!void {
+fn testServer(server: *net.StreamServer) anyerror!void {
var client_file = try server.accept();
const stream = &client_file.outStream().stream;
From 05ae21b78ed58e621fd2c10456a3f100a8107e3a Mon Sep 17 00:00:00 2001
From: Luna
Date: Sat, 9 Nov 2019 12:51:33 -0300
Subject: [PATCH 049/129] make StreamServer.listen family-agnostic
- rename Address.parseUnix to Address.initUnix
---
lib/std/net.zig | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 0f7c76438f..1f680cd3ec 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -40,21 +40,6 @@ pub const Address = extern union {
return error.InvalidIPAddressFormat;
}
- pub fn parseUnix(path: []const u8) !Address {
- var sock_addr = os.sockaddr_un{
- .family = os.AF_UNIX,
- .path = undefined,
- };
-
- // this enables us to have the proper length of the socket in getOsSockLen
- mem.zero(&sock_addr.path);
-
- if (path.len > sock_addr.path.len) return error.NameTooLong;
- mem.copy(u8, &sock_addr.path, path);
-
- return Address{ .un = sock_addr };
- }
-
pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
switch (family) {
os.AF_INET => return parseIp4(name, port),
@@ -230,6 +215,21 @@ pub const Address = extern union {
};
}
+ pub fn initUnix(path: []const u8) !Address {
+ var sock_addr = os.sockaddr_un{
+ .family = os.AF_UNIX,
+ .path = undefined,
+ };
+
+ // this enables us to have the proper length of the socket in getOsSockLen
+ mem.zero(&sock_addr.path);
+
+ if (path.len > sock_addr.path.len) return error.NameTooLong;
+ mem.copy(u8, &sock_addr.path, path);
+
+ return Address{ .un = sock_addr };
+ }
+
/// Returns the port in native endian.
pub fn getPort(self: Address) u16 {
const big_endian_port = switch (self.any.family) {
@@ -1306,7 +1306,7 @@ pub const StreamServer = struct {
pub fn listen(self: *StreamServer, address: Address) !void {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
- const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
+ const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
self.sockfd = sockfd;
errdefer {
os.close(sockfd);
From d18b5f8b53d24d5a27ebde5711d0d142a953adc0 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Fri, 8 Nov 2019 23:17:26 +0100
Subject: [PATCH 050/129] Fix initialization of union references
Fixes #3532
---
src/ir.cpp | 4 ++--
src/ir_print.cpp | 15 +++++++++++++++
src/ir_print.hpp | 1 +
test/stage1/behavior/union.zig | 14 ++++++++++++++
4 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 9225968ce9..507b3e4459 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -18263,7 +18263,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
if (!ptr_val)
return ira->codegen->invalid_instruction;
- if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
+ if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
+ ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
if (union_val == nullptr)
return ira->codegen->invalid_instruction;
@@ -18295,7 +18296,6 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
ConstExprValue *payload_val = union_val->data.x_union.payload;
-
IrInstruction *result;
if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 85b58faefc..89cfab22c2 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -2549,3 +2549,18 @@ void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction,
ir_print_instruction(irp, instruction, false);
}
+
+void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass) {
+ IrPrint ir_print = {};
+ IrPrint *irp = &ir_print;
+ irp->pass = pass;
+ irp->codegen = codegen;
+ irp->f = f;
+ irp->indent = indent_size;
+ irp->indent_size = indent_size;
+ irp->printed = {};
+ irp->printed.init(4);
+ irp->pending = {};
+
+ ir_print_const_value(irp, value);
+}
diff --git a/src/ir_print.hpp b/src/ir_print.hpp
index e3947077c8..64af959f53 100644
--- a/src/ir_print.hpp
+++ b/src/ir_print.hpp
@@ -14,6 +14,7 @@
void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);
void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);
+void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass);
const char* ir_instruction_type_str(IrInstructionId id);
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index 40af5c4fd4..497aa7e574 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -535,3 +535,17 @@ test "global union with single field is correctly initialized" {
};
expect(glbl.f.x == 123);
}
+
+pub const FooUnion = union(enum) {
+ U0: usize,
+ U1: u8,
+};
+
+var glbl_array: [2]FooUnion = undefined;
+
+test "initialize global array of union" {
+ glbl_array[1] = FooUnion{ .U1 = 2 };
+ glbl_array[0] = FooUnion{ .U0 = 1 };
+ expect(glbl_array[0].U0 == 1);
+ expect(glbl_array[1].U1 == 2);
+}
From 348c0232a5612eb9bdb445e80e6e201d24911dcc Mon Sep 17 00:00:00 2001
From: Luna
Date: Sat, 9 Nov 2019 14:53:48 -0300
Subject: [PATCH 051/129] miscellaneous fixes
- make connextUnixSocket use std.net.Address
- fix StreamServer.listen giving wrong protocol for unix sockets
---
lib/std/net.zig | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 1f680cd3ec..24d312e3f6 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -222,7 +222,7 @@ pub const Address = extern union {
};
// this enables us to have the proper length of the socket in getOsSockLen
- mem.zero(&sock_addr.path);
+ mem.set(u8, &sock_addr.path, 0);
if (path.len > sock_addr.path.len) return error.NameTooLong;
mem.copy(u8, &sock_addr.path, path);
@@ -347,9 +347,9 @@ pub const Address = extern union {
switch (self.any.family) {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
- os.AF_UNIX => blk: {
- const path_len = std.mem.len(self.un.path.len);
- break :blk @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
+ os.AF_UNIX => {
+ const path_len = std.mem.len(u8, &self.un.path);
+ return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
},
else => unreachable,
}
@@ -365,16 +365,13 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
);
errdefer os.close(sockfd);
- var sock_addr = os.sockaddr_un{
- .family = os.AF_UNIX,
- .path = undefined,
- };
+ var addr = try std.net.Address.initUnix(path);
- if (path.len > sock_addr.path.len) return error.NameTooLong;
- mem.copy(u8, &sock_addr.path, path);
-
- const size = @intCast(u32, @sizeOf(os.sockaddr_un) - sock_addr.path.len + path.len);
- try os.connect(sockfd, &sock_addr, size);
+ try os.connect(
+ sockfd,
+ &addr.any,
+ addr.getOsSockLen(),
+ );
return fs.File.openHandle(sockfd);
}
@@ -1306,7 +1303,8 @@ pub const StreamServer = struct {
pub fn listen(self: *StreamServer, address: Address) !void {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
- const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
+ const proto = if (address.any.family == os.AF_UNIX) u32(0) else os.IPPROTO_TCP;
+ const sockfd = try os.socket(address.any.family, sock_flags, proto);
self.sockfd = sockfd;
errdefer {
os.close(sockfd);
From e4704f68f850021543ceab86c253806fdded7733 Mon Sep 17 00:00:00 2001
From: Luna
Date: Sat, 9 Nov 2019 15:10:39 -0300
Subject: [PATCH 052/129] use at-as
---
lib/std/net.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index d6dba254e5..98400f23cb 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -1303,7 +1303,7 @@ pub const StreamServer = struct {
pub fn listen(self: *StreamServer, address: Address) !void {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
- const proto = if (address.any.family == os.AF_UNIX) u32(0) else os.IPPROTO_TCP;
+ const proto = if (address.any.family == os.AF_UNIX) @as(u32, 0) else os.IPPROTO_TCP;
const sockfd = try os.socket(address.any.family, sock_flags, proto);
self.sockfd = sockfd;
errdefer {
From 25423eb453e1c0cece457f4012106dbcd97f29f3 Mon Sep 17 00:00:00 2001
From: Luna
Date: Sun, 10 Nov 2019 10:50:22 -0300
Subject: [PATCH 053/129] add errors/panics for unsupported OSes
---
lib/std/net.zig | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 98400f23cb..bbfa47f407 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -14,7 +14,10 @@ pub const Address = extern union {
any: os.sockaddr,
in: os.sockaddr_in,
in6: os.sockaddr_in6,
- un: os.sockaddr_un,
+ un: switch (builtin.os) {
+ .linux, .macosx, .freebsd, .netbsd => os.sockaddr_un,
+ else => void,
+ },
// TODO this crashed the compiler
//pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
@@ -216,6 +219,11 @@ pub const Address = extern union {
}
pub fn initUnix(path: []const u8) !Address {
+ switch (builtin.os) {
+ .linux, .macosx, .freebsd, .netbsd => {},
+ else => return error.UnsupportedOS,
+ }
+
var sock_addr = os.sockaddr_un{
.family = os.AF_UNIX,
.path = undefined,
@@ -331,6 +339,10 @@ pub const Address = extern union {
try std.fmt.format(context, Errors, output, "]:{}", port);
},
os.AF_UNIX => {
+ if (@typeOf(self.un) == void) {
+ @panic("unsupported OS");
+ }
+
try std.fmt.format(context, Errors, output, "{}", self.un.path);
},
else => unreachable,
@@ -348,6 +360,10 @@ pub const Address = extern union {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
os.AF_UNIX => {
+ if (@typeOf(self.un) == void) {
+ @panic("unsupported OS");
+ }
+
const path_len = std.mem.len(u8, &self.un.path);
return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
},
@@ -1304,6 +1320,13 @@ pub const StreamServer = struct {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
const proto = if (address.any.family == os.AF_UNIX) @as(u32, 0) else os.IPPROTO_TCP;
+ if (address.any.family == os.AF_UNIX and @typeOf(address.un) == void) {
+ return error{
+ /// When the OS does not have support for AF_UNIX sockets.
+ UnsupportedOS,
+ }.UnsupportedOS;
+ }
+
const sockfd = try os.socket(address.any.family, sock_flags, proto);
self.sockfd = sockfd;
errdefer {
From 98e37537d1fc290e3df35b03b41b036490ffdaee Mon Sep 17 00:00:00 2001
From: dimenus
Date: Sat, 9 Nov 2019 15:08:53 -0600
Subject: [PATCH 054/129] minor fix due to recent directory handling API
changes
---
lib/std/fs.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 3f20c66102..0d9de44f79 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -1100,7 +1100,7 @@ pub const Walker = struct {
}
pub fn deinit(self: *Walker) void {
- while (self.stack.popOrNull()) |*item| item.dir_it.close();
+ while (self.stack.popOrNull()) |*item| item.dir_it.dir.close();
self.stack.deinit();
self.name_buffer.deinit();
}
From 2d02920a905e20b7f43991657cdc028e444b9df7 Mon Sep 17 00:00:00 2001
From: Luna
Date: Sun, 10 Nov 2019 14:04:52 -0300
Subject: [PATCH 055/129] use hasDecl instead of switch on builtin.os
---
lib/std/net.zig | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index bbfa47f407..7ee8b9a756 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -10,14 +10,13 @@ test "" {
_ = @import("net/test.zig");
}
+const has_unix_sockets = @hasDecl(os, "sockaddr_un");
+
pub const Address = extern union {
any: os.sockaddr,
in: os.sockaddr_in,
in6: os.sockaddr_in6,
- un: switch (builtin.os) {
- .linux, .macosx, .freebsd, .netbsd => os.sockaddr_un,
- else => void,
- },
+ un: if (has_unix_sockets) os.sockaddr_un else void,
// TODO this crashed the compiler
//pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
@@ -239,6 +238,7 @@ pub const Address = extern union {
}
/// Returns the port in native endian.
+ /// Asserts that the address is ip4 or ip6.
pub fn getPort(self: Address) u16 {
const big_endian_port = switch (self.any.family) {
os.AF_INET => self.in.port,
@@ -249,6 +249,7 @@ pub const Address = extern union {
}
/// `port` is native-endian.
+ /// Asserts that the address is ip4 or ip6.
pub fn setPort(self: *Address, port: u16) void {
const ptr = switch (self.any.family) {
os.AF_INET => &self.in.port,
From d99ecef9433d677b4f834d466d7057b0f35e4dbf Mon Sep 17 00:00:00 2001
From: Luna
Date: Sun, 10 Nov 2019 14:17:39 -0300
Subject: [PATCH 056/129] replace panic to unreachable
- remove error.UnsupportedOS from StreamServer.listen
---
lib/std/net.zig | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 7ee8b9a756..af79f22757 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -340,8 +340,8 @@ pub const Address = extern union {
try std.fmt.format(context, Errors, output, "]:{}", port);
},
os.AF_UNIX => {
- if (@typeOf(self.un) == void) {
- @panic("unsupported OS");
+ if (!has_unix_sockets) {
+ unreachable;
}
try std.fmt.format(context, Errors, output, "{}", self.un.path);
@@ -361,8 +361,8 @@ pub const Address = extern union {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
os.AF_UNIX => {
- if (@typeOf(self.un) == void) {
- @panic("unsupported OS");
+ if (!has_unix_sockets) {
+ unreachable;
}
const path_len = std.mem.len(u8, &self.un.path);
@@ -1321,12 +1321,6 @@ pub const StreamServer = struct {
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
const proto = if (address.any.family == os.AF_UNIX) @as(u32, 0) else os.IPPROTO_TCP;
- if (address.any.family == os.AF_UNIX and @typeOf(address.un) == void) {
- return error{
- /// When the OS does not have support for AF_UNIX sockets.
- UnsupportedOS,
- }.UnsupportedOS;
- }
const sockfd = try os.socket(address.any.family, sock_flags, proto);
self.sockfd = sockfd;
From d1eabe81a99c3fe6c0e551e9bab90a3bbae509fe Mon Sep 17 00:00:00 2001
From: Luna
Date: Sun, 10 Nov 2019 14:38:33 -0300
Subject: [PATCH 057/129] add sockaddr_un to os/bits/windows
---
lib/std/os/bits/windows.zig | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig
index 178811bb1e..b5b8a9c2d4 100644
--- a/lib/std/os/bits/windows.zig
+++ b/lib/std/os/bits/windows.zig
@@ -186,6 +186,11 @@ pub const sockaddr_in6 = extern struct {
pub const in6_addr = [16]u8;
pub const in_addr = u32;
+pub const sockaddr_un = extern struct {
+ family: sa_family_t = AF_UNIX,
+ path: [108]u8,
+};
+
pub const AF_UNSPEC = 0;
pub const AF_UNIX = 1;
pub const AF_INET = 2;
From c8a8da28049d2e9aece857359725b2a8f6d3732b Mon Sep 17 00:00:00 2001
From: Luna
Date: Sun, 10 Nov 2019 16:44:18 -0300
Subject: [PATCH 058/129] remove builtin.os check in Address.initUnix
---
lib/std/net.zig | 5 -----
1 file changed, 5 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index af79f22757..531b8ce797 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -218,11 +218,6 @@ pub const Address = extern union {
}
pub fn initUnix(path: []const u8) !Address {
- switch (builtin.os) {
- .linux, .macosx, .freebsd, .netbsd => {},
- else => return error.UnsupportedOS,
- }
-
var sock_addr = os.sockaddr_un{
.family = os.AF_UNIX,
.path = undefined,
From d44a69689eb2579ceb290cd19b91f824b30e6acc Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Nov 2019 14:58:24 -0500
Subject: [PATCH 059/129] std.ChildProcess.spawn has a consistent error set
across targets. Also fix detection of pkg-config not
installed on Windows when using zig build.
---
lib/std/build.zig | 1 +
lib/std/child_process.zig | 95 +++++++++++++++++++++++++++++++--------
2 files changed, 78 insertions(+), 18 deletions(-)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 899e74105b..ade3dabea3 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -957,6 +957,7 @@ pub const Builder = struct {
error.ProcessTerminated => error.PkgConfigCrashed,
error.ExitCodeFailure => error.PkgConfigFailed,
error.FileNotFound => error.PkgConfigNotInstalled,
+ error.InvalidName => error.PkgConfigNotInstalled,
error.PkgConfigInvalidOutput => error.PkgConfigInvalidOutput,
else => return err,
};
diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig
index e6e284db18..d329855c03 100644
--- a/lib/std/child_process.zig
+++ b/lib/std/child_process.zig
@@ -50,8 +50,20 @@ pub const ChildProcess = struct {
err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,
- pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError ||
- os.ChangeCurDirError || windows.CreateProcessError;
+ pub const SpawnError = error{
+ OutOfMemory,
+
+ /// POSIX-only. `StdIo.Ignore` was selected and opening `/dev/null` returned ENODEV.
+ NoDevice,
+
+ /// Windows-only. One of:
+ /// * `cwd` was provided and it could not be re-encoded into UTF16LE, or
+ /// * The `PATH` or `PATHEXT` environment variable contained invalid UTF-8.
+ InvalidUtf8,
+
+ /// Windows-only. `cwd` was provided, but the path did not exist when spawning the child process.
+ CurrentWorkingDirectoryUnlinked,
+ } || os.ExecveError || os.SetIdError || os.ChangeCurDirError || windows.CreateProcessError;
pub const Term = union(enum) {
Exited: u32,
@@ -102,7 +114,7 @@ pub const ChildProcess = struct {
}
/// On success must call `kill` or `wait`.
- pub fn spawn(self: *ChildProcess) !void {
+ pub fn spawn(self: *ChildProcess) SpawnError!void {
if (builtin.os == .windows) {
return self.spawnWindows();
} else {
@@ -110,7 +122,7 @@ pub const ChildProcess = struct {
}
}
- pub fn spawnAndWait(self: *ChildProcess) !Term {
+ pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term {
try self.spawn();
return self.wait();
}
@@ -162,7 +174,13 @@ pub const ChildProcess = struct {
/// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
/// If it succeeds, the caller owns result.stdout and result.stderr memory.
- pub fn exec(allocator: *mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, env_map: ?*const BufMap, max_output_size: usize) !ExecResult {
+ pub fn exec(
+ allocator: *mem.Allocator,
+ argv: []const []const u8,
+ cwd: ?[]const u8,
+ env_map: ?*const BufMap,
+ max_output_size: usize,
+ ) !ExecResult {
const child = try ChildProcess.init(argv, allocator);
defer child.deinit();
@@ -292,7 +310,7 @@ pub const ChildProcess = struct {
Term{ .Unknown = status };
}
- fn spawnPosix(self: *ChildProcess) !void {
+ fn spawnPosix(self: *ChildProcess) SpawnError!void {
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe() else undefined;
errdefer if (self.stdin_behavior == StdIo.Pipe) {
destroyPipe(stdin_pipe);
@@ -309,7 +327,16 @@ pub const ChildProcess = struct {
};
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
- const dev_null_fd = if (any_ignore) try os.openC(c"/dev/null", os.O_RDWR, 0) else undefined;
+ const dev_null_fd = if (any_ignore)
+ os.openC(c"/dev/null", os.O_RDWR, 0) catch |err| switch (err) {
+ error.PathAlreadyExists => unreachable,
+ error.NoSpaceLeft => unreachable,
+ error.FileTooBig => unreachable,
+ error.DeviceBusy => unreachable,
+ else => |e| return e,
+ }
+ else
+ undefined;
defer {
if (any_ignore) os.close(dev_null_fd);
}
@@ -403,7 +430,7 @@ pub const ChildProcess = struct {
}
}
- fn spawnWindows(self: *ChildProcess) !void {
+ fn spawnWindows(self: *ChildProcess) SpawnError!void {
const saAttr = windows.SECURITY_ATTRIBUTES{
.nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
.bInheritHandle = windows.TRUE,
@@ -412,11 +439,28 @@ pub const ChildProcess = struct {
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
- const nul_handle = if (any_ignore) blk: {
- break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null);
- } else blk: {
- break :blk undefined;
- };
+ const nul_handle = if (any_ignore)
+ windows.CreateFile(
+ "NUL",
+ windows.GENERIC_READ,
+ windows.FILE_SHARE_READ,
+ null,
+ windows.OPEN_EXISTING,
+ windows.FILE_ATTRIBUTE_NORMAL,
+ null,
+ ) catch |err| switch (err) {
+ error.SharingViolation => unreachable, // not possible for "NUL"
+ error.PathAlreadyExists => unreachable, // not possible for "NUL"
+ error.PipeBusy => unreachable, // not possible for "NUL"
+ error.InvalidUtf8 => unreachable, // not possible for "NUL"
+ error.BadPathName => unreachable, // not possible for "NUL"
+ error.FileNotFound => unreachable, // not possible for "NUL"
+ error.AccessDenied => unreachable, // not possible for "NUL"
+ error.NameTooLong => unreachable, // not possible for "NUL"
+ else => |e| return e,
+ }
+ else
+ undefined;
defer {
if (any_ignore) os.close(nul_handle);
}
@@ -542,10 +586,25 @@ pub const ChildProcess = struct {
windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
if (no_path_err != error.FileNotFound) return no_path_err;
- const PATH = try process.getEnvVarOwned(self.allocator, "PATH");
- defer self.allocator.free(PATH);
- const PATHEXT = try process.getEnvVarOwned(self.allocator, "PATHEXT");
- defer self.allocator.free(PATHEXT);
+ var free_path = true;
+ const PATH = process.getEnvVarOwned(self.allocator, "PATH") catch |err| switch (err) {
+ error.EnvironmentVariableNotFound => blk: {
+ free_path = false;
+ break :blk "";
+ },
+ else => |e| return e,
+ };
+ defer if (free_path) self.allocator.free(PATH);
+
+ var free_path_ext = true;
+ const PATHEXT = process.getEnvVarOwned(self.allocator, "PATHEXT") catch |err| switch (err) {
+ error.EnvironmentVariableNotFound => blk: {
+ free_path_ext = false;
+ break :blk "";
+ },
+ else => |e| return e,
+ };
+ defer if (free_path_ext) self.allocator.free(PATHEXT);
var it = mem.tokenize(PATH, ";");
retry: while (it.next()) |search_path| {
@@ -717,7 +776,7 @@ fn destroyPipe(pipe: [2]os.fd_t) void {
// Child of fork calls this to report an error to the fork parent.
// Then the child exits.
fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
- writeIntFd(fd, @as(ErrInt,@errorToInt(err))) catch {};
+ writeIntFd(fd, @as(ErrInt, @errorToInt(err))) catch {};
os.exit(1);
}
From cd5c9c8998f1669059cee3d915831ee539dea2b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20Quei=C3=9Fner?=
Date: Mon, 11 Nov 2019 00:08:24 +0100
Subject: [PATCH 060/129] Fix missing @as cast in std.fmt.formatInt (#3650)
---
lib/std/fmt.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index e901d8d3f7..743ca4d920 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -892,7 +892,7 @@ pub fn formatInt(
) Errors!void {
const int_value = if (@typeOf(value) == comptime_int) blk: {
const Int = math.IntFittingRange(value, value);
- break :blk Int(value);
+ break :blk @as(Int, value);
} else
value;
From ae0a219d1f5495acc4d82421fa24d84186c2a40d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 11:52:50 -0500
Subject: [PATCH 061/129] stop accepting deprecated `use` keyword
closes #2591
---
lib/std/zig/parser_test.zig | 10 ----------
lib/std/zig/render.zig | 4 +---
lib/std/zig/tokenizer.zig | 1 -
src/tokenizer.cpp | 1 -
test/compare_output.zig | 24 ++++++++++++------------
5 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 28497ad6f1..e9b4cd6455 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,13 +1,3 @@
-// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
-test "zig fmt: change use to usingnamespace" {
- try testTransform(
- \\use @import("std");
- ,
- \\usingnamespace @import("std");
- \\
- );
-}
-
test "zig fmt: async function" {
try testCanonical(
\\pub const Server = struct {
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 81ba8e941c..c6912087cf 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -226,9 +226,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
if (use_decl.visib_token) |visib_token| {
try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
}
- // TODO after depracating use, go back to this:
- //try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace
- try stream.write("usingnamespace ");
+ try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace
try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
},
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index b401b25ade..ae82cb7602 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -59,7 +59,6 @@ pub const Token = struct {
Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
Keyword{ .bytes = "union", .id = Id.Keyword_union },
Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },
- Keyword{ .bytes = "use", .id = Id.Keyword_usingnamespace },
Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace },
Keyword{ .bytes = "var", .id = Id.Keyword_var },
Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 674f0c2b96..8b301f85ac 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -153,7 +153,6 @@ static const struct ZigKeyword zig_keywords[] = {
{"undefined", TokenIdKeywordUndefined},
{"union", TokenIdKeywordUnion},
{"unreachable", TokenIdKeywordUnreachable},
- {"use", TokenIdKeywordUsingNamespace},
{"usingnamespace", TokenIdKeywordUsingNamespace},
{"var", TokenIdKeywordVar},
{"volatile", TokenIdKeywordVolatile},
diff --git a/test/compare_output.zig b/test/compare_output.zig
index 4e55b374b6..dfa33e26bd 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -14,8 +14,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addCase(x: {
var tc = cases.create("multiple files with private function",
- \\use @import("std").io;
- \\use @import("foo.zig");
+ \\usingnamespace @import("std").io;
+ \\usingnamespace @import("foo.zig");
\\
\\pub fn main() void {
\\ privateFunction();
@@ -29,7 +29,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
, "OK 1\nOK 2\n");
tc.addSourceFile("foo.zig",
- \\use @import("std").io;
+ \\usingnamespace @import("std").io;
\\
\\// purposefully conflicting function with main.zig
\\// but it's private so it should be OK
@@ -48,8 +48,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addCase(x: {
var tc = cases.create("import segregation",
- \\use @import("foo.zig");
- \\use @import("bar.zig");
+ \\usingnamespace @import("foo.zig");
+ \\usingnamespace @import("bar.zig");
\\
\\pub fn main() void {
\\ foo_function();
@@ -58,7 +58,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
, "OK\nOK\n");
tc.addSourceFile("foo.zig",
- \\use @import("std").io;
+ \\usingnamespace @import("std").io;
\\pub fn foo_function() void {
\\ const stdout = &(getStdOut() catch unreachable).outStream().stream;
\\ stdout.print("OK\n") catch unreachable;
@@ -66,8 +66,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
);
tc.addSourceFile("bar.zig",
- \\use @import("other.zig");
- \\use @import("std").io;
+ \\usingnamespace @import("other.zig");
+ \\usingnamespace @import("std").io;
\\
\\pub fn bar_function() void {
\\ if (foo_function()) {
@@ -88,8 +88,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
});
cases.addCase(x: {
- var tc = cases.create("two files use import each other",
- \\use @import("a.zig");
+ var tc = cases.create("two files usingnamespace import each other",
+ \\usingnamespace @import("a.zig");
\\
\\pub fn main() void {
\\ ok();
@@ -97,7 +97,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
, "OK\n");
tc.addSourceFile("a.zig",
- \\use @import("b.zig");
+ \\usingnamespace @import("b.zig");
\\const io = @import("std").io;
\\
\\pub const a_text = "OK\n";
@@ -109,7 +109,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
);
tc.addSourceFile("b.zig",
- \\use @import("a.zig");
+ \\usingnamespace @import("a.zig");
\\
\\pub const b_text = a_text;
);
From de30438ed2efb909538f3177cced441b57eb1a5d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Nov 2019 16:15:12 -0500
Subject: [PATCH 062/129] stage1 parser code for anon container lit
---
src/parser.cpp | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/parser.cpp b/src/parser.cpp
index a1ece3ed10..484e145cfa 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -81,7 +81,7 @@ static AstNode *ast_parse_for_type_expr(ParseContext *pc);
static AstNode *ast_parse_while_type_expr(ParseContext *pc);
static AstNode *ast_parse_switch_expr(ParseContext *pc);
static AstNode *ast_parse_asm_expr(ParseContext *pc);
-static AstNode *ast_parse_enum_lit(ParseContext *pc);
+static AstNode *ast_parse_anon_lit(ParseContext *pc);
static AstNode *ast_parse_asm_output(ParseContext *pc);
static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);
static AstNode *ast_parse_asm_input(ParseContext *pc);
@@ -1600,9 +1600,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
if (container_decl != nullptr)
return container_decl;
- AstNode *enum_lit = ast_parse_enum_lit(pc);
- if (enum_lit != nullptr)
- return enum_lit;
+ AstNode *anon_lit = ast_parse_anon_lit(pc);
+ if (anon_lit != nullptr)
+ return anon_lit;
AstNode *error_set_decl = ast_parse_error_set_decl(pc);
if (error_set_decl != nullptr)
@@ -1876,16 +1876,22 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {
return res;
}
-static AstNode *ast_parse_enum_lit(ParseContext *pc) {
+static AstNode *ast_parse_anon_lit(ParseContext *pc) {
Token *period = eat_token_if(pc, TokenIdDot);
if (period == nullptr)
return nullptr;
- Token *identifier = expect_token(pc, TokenIdSymbol);
- AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
- res->data.enum_literal.period = period;
- res->data.enum_literal.identifier = identifier;
- return res;
+ // anon enum literal
+ Token *identifier = eat_token_if(pc, TokenIdSymbol);
+ if (identifier != nullptr) {
+ AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
+ res->data.enum_literal.period = period;
+ res->data.enum_literal.identifier = identifier;
+ return res;
+ }
+
+ // anon container literal
+ return ast_parse_init_list(pc);
}
// AsmOutput <- COLON AsmOutputList AsmInput?
From 5b279434986b18d07ceec217c5c402a589ccc0b4 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Nov 2019 21:58:05 -0500
Subject: [PATCH 063/129] implement anon struct literal syntax
This implements stage1 parser support for anonymous struct literal
syntax (see #685), as well as semantic analysis support for anonymous
struct literals and anonymous list literals (see #208). The semantic
analysis works when there is a type coercion in the result location;
inferring the struct type based on the values in the literal is not
implemented yet. Also remaining to do is zig fmt support for this new
syntax and documentation updates.
---
lib/std/builtin.zig | 33 +----
src/all_types.hpp | 7 +-
src/analyze.cpp | 10 +-
src/ast_render.cpp | 4 +-
src/ir.cpp | 204 +++++++++++++++++++-----------
src/ir_print.cpp | 8 +-
test/compile_errors.zig | 4 +-
test/stage1/behavior/async_fn.zig | 4 +-
test/stage1/behavior/struct.zig | 20 +++
9 files changed, 174 insertions(+), 120 deletions(-)
diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig
index 8315cd84cf..8052f0b31a 100644
--- a/lib/std/builtin.zig
+++ b/lib/std/builtin.zig
@@ -90,40 +90,11 @@ pub const Mode = enum {
ReleaseSmall,
};
-/// This data structure is used by the Zig language code generation and
-/// therefore must be kept in sync with the compiler implementation.
-pub const TypeId = enum {
- Type,
- Void,
- Bool,
- NoReturn,
- Int,
- Float,
- Pointer,
- Array,
- Struct,
- ComptimeFloat,
- ComptimeInt,
- Undefined,
- Null,
- Optional,
- ErrorUnion,
- ErrorSet,
- Enum,
- Union,
- Fn,
- BoundFn,
- ArgTuple,
- Opaque,
- Frame,
- AnyFrame,
- Vector,
- EnumLiteral,
-};
+pub const TypeId = @TagType(TypeInfo);
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
-pub const TypeInfo = union(TypeId) {
+pub const TypeInfo = union(enum) {
Type: void,
Void: void,
Bool: void,
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 8ba2bfc503..4d751bae2c 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1237,6 +1237,7 @@ struct TypeStructField {
enum ResolveStatus {
ResolveStatusUnstarted,
ResolveStatusInvalid,
+ ResolveStatusBeingInferred,
ResolveStatusZeroBitsKnown,
ResolveStatusAlignmentKnown,
ResolveStatusSizeKnown,
@@ -1285,6 +1286,7 @@ struct ZigTypeStruct {
bool requires_comptime;
bool resolve_loop_flag_zero_bits;
bool resolve_loop_flag_other;
+ bool is_inferred;
};
struct ZigTypeOptional {
@@ -2812,7 +2814,7 @@ struct IrInstructionElemPtr {
IrInstruction *array_ptr;
IrInstruction *elem_index;
- IrInstruction *init_array_type;
+ AstNode *init_array_type_source_node;
PtrLen ptr_len;
bool safety_check_on;
};
@@ -2909,11 +2911,11 @@ struct IrInstructionResizeSlice {
struct IrInstructionContainerInitList {
IrInstruction base;
- IrInstruction *container_type;
IrInstruction *elem_type;
size_t item_count;
IrInstruction **elem_result_loc_list;
IrInstruction *result_loc;
+ AstNode *init_array_type_source_node;
};
struct IrInstructionContainerInitFieldsField {
@@ -2926,7 +2928,6 @@ struct IrInstructionContainerInitFieldsField {
struct IrInstructionContainerInitFields {
IrInstruction base;
- IrInstruction *container_type;
size_t field_count;
IrInstructionContainerInitFieldsField *fields;
IrInstruction *result_loc;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 66e1f8984b..ae5b626c29 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -140,7 +140,6 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope
static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
ZigType *import, Buf *bare_name)
{
- assert(node == nullptr || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
ScopeDecls *scope = allocate(1);
init_scope(g, &scope->base, ScopeIdDecls, node, parent);
scope->decl_table.init(4);
@@ -346,6 +345,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
switch (status) {
case ResolveStatusInvalid:
zig_unreachable();
+ case ResolveStatusBeingInferred:
+ zig_unreachable();
case ResolveStatusUnstarted:
case ResolveStatusZeroBitsKnown:
return true;
@@ -362,6 +363,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
switch (status) {
case ResolveStatusInvalid:
zig_unreachable();
+ case ResolveStatusBeingInferred:
+ zig_unreachable();
case ResolveStatusUnstarted:
return true;
case ResolveStatusZeroBitsKnown:
@@ -6132,6 +6135,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
continue;
if (instruction->ref_count == 0)
continue;
+ if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown)))
+ return ErrorSemanticAnalyzeFail;
if (!type_has_bits(instruction->value.type))
continue;
if (scope_needs_spill(instruction->scope)) {
@@ -6271,6 +6276,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
switch (status) {
case ResolveStatusUnstarted:
return ErrorNone;
+ case ResolveStatusBeingInferred:
+ zig_unreachable();
case ResolveStatusInvalid:
zig_unreachable();
case ResolveStatusZeroBitsKnown:
@@ -9038,4 +9045,3 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
*out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
return ErrorNone;
}
-
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index c016f629d1..34cbed245a 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -821,7 +821,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
break;
}
case NodeTypeContainerInitExpr:
- render_node_ungrouped(ar, node->data.container_init_expr.type);
+ if (node->data.container_init_expr.type != nullptr) {
+ render_node_ungrouped(ar, node->data.container_init_expr.type);
+ }
if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
fprintf(ar->f, "{\n");
ar->indent += ar->indent_size;
diff --git a/src/ir.cpp b/src/ir.cpp
index 507b3e4459..f1b31af582 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -1350,18 +1350,17 @@ static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_
static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len,
- IrInstruction *init_array_type)
+ AstNode *init_array_type_source_node)
{
IrInstructionElemPtr *instruction = ir_build_instruction(irb, scope, source_node);
instruction->array_ptr = array_ptr;
instruction->elem_index = elem_index;
instruction->safety_check_on = safety_check_on;
instruction->ptr_len = ptr_len;
- instruction->init_array_type = init_array_type;
+ instruction->init_array_type_source_node = init_array_type_source_node;
ir_ref_instruction(array_ptr, irb->current_basic_block);
ir_ref_instruction(elem_index, irb->current_basic_block);
- if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block);
return &instruction->base;
}
@@ -1575,17 +1574,16 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *sour
}
static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list,
- IrInstruction *result_loc)
+ size_t item_count, IrInstruction **elem_result_loc_list, IrInstruction *result_loc,
+ AstNode *init_array_type_source_node)
{
IrInstructionContainerInitList *container_init_list_instruction =
ir_build_instruction(irb, scope, source_node);
- container_init_list_instruction->container_type = container_type;
container_init_list_instruction->item_count = item_count;
container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
container_init_list_instruction->result_loc = result_loc;
+ container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
- ir_ref_instruction(container_type, irb->current_basic_block);
for (size_t i = 0; i < item_count; i += 1) {
ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
}
@@ -1595,17 +1593,14 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope,
}
static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields,
- IrInstruction *result_loc)
+ size_t field_count, IrInstructionContainerInitFieldsField *fields, IrInstruction *result_loc)
{
IrInstructionContainerInitFields *container_init_fields_instruction =
ir_build_instruction(irb, scope, source_node);
- container_init_fields_instruction->container_type = container_type;
container_init_fields_instruction->field_count = field_count;
container_init_fields_instruction->fields = fields;
container_init_fields_instruction->result_loc = result_loc;
- ir_ref_instruction(container_type, irb->current_basic_block);
for (size_t i = 0; i < field_count; i += 1) {
ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
}
@@ -3084,7 +3079,7 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN
instruction->result_loc = result_loc;
instruction->ty = ty;
- ir_ref_instruction(ty, irb->current_basic_block);
+ if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block);
return &instruction->base;
}
@@ -6127,28 +6122,42 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
ContainerInitKind kind = container_init_expr->kind;
- IrInstruction *container_type = nullptr;
- IrInstruction *elem_type = nullptr;
- if (container_init_expr->type->type == NodeTypeInferredArrayType) {
- elem_type = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.child_type, scope);
- if (elem_type == irb->codegen->invalid_instruction)
- return elem_type;
- } else {
- container_type = ir_gen_node(irb, container_init_expr->type, scope);
- if (container_type == irb->codegen->invalid_instruction)
- return container_type;
- }
-
- switch (kind) {
- case ContainerInitKindStruct: {
- if (elem_type != nullptr) {
+ ResultLocCast *result_loc_cast = nullptr;
+ ResultLoc *child_result_loc;
+ AstNode *init_array_type_source_node;
+ if (container_init_expr->type != nullptr) {
+ IrInstruction *container_type;
+ if (container_init_expr->type->type == NodeTypeInferredArrayType) {
+ if (kind == ContainerInitKindStruct) {
add_node_error(irb->codegen, container_init_expr->type,
buf_sprintf("initializing array with struct syntax"));
return irb->codegen->invalid_instruction;
}
+ IrInstruction *elem_type = ir_gen_node(irb,
+ container_init_expr->type->data.inferred_array_type.child_type, scope);
+ if (elem_type == irb->codegen->invalid_instruction)
+ return elem_type;
+ size_t item_count = container_init_expr->entries.length;
+ IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
+ container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
+ } else {
+ container_type = ir_gen_node(irb, container_init_expr->type, scope);
+ if (container_type == irb->codegen->invalid_instruction)
+ return container_type;
+ }
- IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
- container_type);
+ result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc);
+ child_result_loc = &result_loc_cast->base;
+ init_array_type_source_node = container_type->source_node;
+ } else {
+ child_result_loc = parent_result_loc;
+ init_array_type_source_node = parent_result_loc->source_instruction->source_node;
+ }
+
+ switch (kind) {
+ case ContainerInitKindStruct: {
+ IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
+ nullptr);
size_t field_count = container_init_expr->entries.length;
IrInstructionContainerInitFieldsField *fields = allocate(field_count);
@@ -6176,29 +6185,27 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
fields[i].source_node = entry_node;
fields[i].result_loc = field_ptr;
}
- IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type,
- field_count, fields, container_ptr);
+ IrInstruction *result = ir_build_container_init_fields(irb, scope, node, field_count,
+ fields, container_ptr);
- return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc);
+ if (result_loc_cast != nullptr) {
+ result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
+ }
+ return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
}
case ContainerInitKindArray: {
size_t item_count = container_init_expr->entries.length;
- if (container_type == nullptr) {
- IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
- container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
- }
-
- IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
- container_type);
+ IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
+ nullptr);
IrInstruction **result_locs = allocate(item_count);
for (size_t i = 0; i < item_count; i += 1) {
AstNode *expr_node = container_init_expr->entries.at(i);
IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
- IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index,
- false, PtrLenSingle, container_type);
+ IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr,
+ elem_index, false, PtrLenSingle, init_array_type_source_node);
ResultLocInstruction *result_loc_inst = allocate(1);
result_loc_inst->base.id = ResultLocIdInstruction;
result_loc_inst->base.source_instruction = elem_ptr;
@@ -6213,9 +6220,12 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
result_locs[i] = elem_ptr;
}
- IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type,
- item_count, result_locs, container_ptr);
- return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc);
+ IrInstruction *result = ir_build_container_init_list(irb, scope, node, item_count,
+ result_locs, container_ptr, init_array_type_source_node);
+ if (result_loc_cast != nullptr) {
+ result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
+ }
+ return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
}
}
zig_unreachable();
@@ -7935,14 +7945,14 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o
static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,
Scope *scope, AstNode *source_node, Buf *out_bare_name)
{
- if (exec->name) {
+ if (exec != nullptr && exec->name) {
ZigType *import = get_scope_import(scope);
Buf *namespace_name = buf_alloc();
append_namespace_qualification(codegen, namespace_name, import);
buf_append_buf(namespace_name, exec->name);
buf_init_from_buf(out_bare_name, exec->name);
return namespace_name;
- } else if (exec->name_fn != nullptr) {
+ } else if (exec != nullptr && exec->name_fn != nullptr) {
Buf *name = buf_alloc();
buf_append_buf(name, &exec->name_fn->symbol_name);
buf_appendf(name, "(");
@@ -15541,11 +15551,7 @@ static bool ir_result_has_type(ResultLoc *result_loc) {
static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr,
ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime)
{
- Error err;
-
IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
- if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))
- return ira->codegen->invalid_instruction;
alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
PtrLenSingle, 0, 0, 0, false);
set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
@@ -15750,6 +15756,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
return casted_value;
}
+ bool old_parent_result_loc_written = result_cast->parent->written;
IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent,
dest_type, casted_value, force_runtime, non_null_comptime, true);
if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
@@ -15775,6 +15782,22 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
+ {
+ // we also need to check that this cast is OK.
+ ConstCastOnly const_cast_result = types_match_const_cast_only(ira,
+ parent_result_loc->value.type, ptr_type,
+ result_cast->base.source_instruction->source_node, false);
+ if (const_cast_result.id == ConstCastResultIdInvalid)
+ return ira->codegen->invalid_instruction;
+ if (const_cast_result.id != ConstCastResultIdOk) {
+ // We will not be able to provide a result location for this value. Create
+ // a new result location.
+ result_cast->parent->written = old_parent_result_loc_written;
+ return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
+ force_runtime, non_null_comptime);
+ }
+ }
+
result_loc->written = true;
result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
ptr_type, result_cast->base.source_instruction, false);
@@ -15902,10 +15925,33 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
return result_loc;
}
-static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
- ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
- if (type_is_invalid(implicit_elem_type))
- return ira->codegen->invalid_instruction;
+static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
+ IrInstructionResolveResult *instruction)
+{
+ ZigType *implicit_elem_type;
+ if (instruction->ty == nullptr) {
+ if (instruction->result_loc->id == ResultLocIdCast) {
+ implicit_elem_type = ir_resolve_type(ira,
+ instruction->result_loc->source_instruction->child);
+ if (type_is_invalid(implicit_elem_type))
+ return ira->codegen->invalid_instruction;
+ } else {
+ Buf *bare_name = buf_alloc();
+ Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
+ instruction->base.scope, instruction->base.source_node, bare_name);
+
+ ZigType *inferred_struct_type = get_partial_container_type(ira->codegen,
+ instruction->base.scope, ContainerKindStruct, instruction->base.source_node,
+ buf_ptr(name), bare_name, ContainerLayoutAuto);
+ inferred_struct_type->data.structure.is_inferred = true;
+ inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred;
+ implicit_elem_type = inferred_struct_type;
+ }
+ } else {
+ implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
+ if (type_is_invalid(implicit_elem_type))
+ return ira->codegen->invalid_instruction;
+ }
IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
implicit_elem_type, nullptr, false, true, true);
if (result_loc != nullptr)
@@ -17837,7 +17883,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
if (array_ptr_val == nullptr)
return ira->codegen->invalid_instruction;
- if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) {
+ if (array_ptr_val->special == ConstValSpecialUndef &&
+ elem_ptr_instruction->init_array_type_source_node != nullptr)
+ {
if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) {
array_ptr_val->data.x_array.special = ConstArraySpecialNone;
array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);
@@ -17851,11 +17899,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
elem_val->parent.data.p_array.elem_index = i;
}
} else if (is_slice(array_type)) {
- ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child);
+ ir_assert(array_ptr->value.type->id == ZigTypeIdPointer, &elem_ptr_instruction->base);
+ ZigType *actual_array_type = array_ptr->value.type->data.pointer.child_type;
+
if (type_is_invalid(actual_array_type))
return ira->codegen->invalid_instruction;
if (actual_array_type->id != ZigTypeIdArray) {
- ir_add_error(ira, elem_ptr_instruction->init_array_type,
+ ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
buf_sprintf("expected array type or [_], found slice"));
return ira->codegen->invalid_instruction;
}
@@ -17879,7 +17929,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
false);
array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;
} else {
- ir_add_error(ira, elem_ptr_instruction->init_array_type,
+ ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
buf_sprintf("expected array type or [_], found '%s'",
buf_ptr(&array_type->name)));
return ira->codegen->invalid_instruction;
@@ -18012,7 +18062,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,
- false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
+ false, elem_ptr_instruction->ptr_len, nullptr);
result->value.type = return_type;
result->value.special = ConstValSpecialStatic;
} else {
@@ -18073,7 +18123,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,
- elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
+ elem_ptr_instruction->ptr_len, nullptr);
result->value.type = return_type;
return result;
}
@@ -18223,6 +18273,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
Error err;
ZigType *bare_type = container_ref_type(container_type);
+
if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
@@ -20124,14 +20175,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
IrInstructionContainerInitList *instruction)
{
- ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child);
- if (type_is_invalid(container_type))
- return ira->codegen->invalid_instruction;
+ ir_assert(instruction->result_loc != nullptr, &instruction->base);
+ IrInstruction *result_loc = instruction->result_loc->child;
+ if (type_is_invalid(result_loc->value.type))
+ return result_loc;
+ ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
+
+ ZigType *container_type = result_loc->value.type->data.pointer.child_type;
size_t elem_count = instruction->item_count;
if (is_slice(container_type)) {
- ir_add_error(ira, instruction->container_type,
+ ir_add_error_node(ira, instruction->init_array_type_source_node,
buf_sprintf("expected array type or [_], found slice"));
return ira->codegen->invalid_instruction;
}
@@ -20160,12 +20215,6 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
return ira->codegen->invalid_instruction;
}
- ir_assert(instruction->result_loc != nullptr, &instruction->base);
- IrInstruction *result_loc = instruction->result_loc->child;
- if (type_is_invalid(result_loc->value.type))
- return result_loc;
- ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
-
ZigType *child_type = container_type->data.array.child_type;
if (container_type->data.array.len != elem_count) {
ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
@@ -20262,16 +20311,14 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
IrInstructionContainerInitFields *instruction)
{
- IrInstruction *container_type_value = instruction->container_type->child;
- ZigType *container_type = ir_resolve_type(ira, container_type_value);
- if (type_is_invalid(container_type))
- return ira->codegen->invalid_instruction;
-
ir_assert(instruction->result_loc != nullptr, &instruction->base);
IrInstruction *result_loc = instruction->result_loc->child;
if (type_is_invalid(result_loc->value.type))
return result_loc;
+ ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
+ ZigType *container_type = result_loc->value.type->data.pointer.child_type;
+
return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
instruction->field_count, instruction->fields, result_loc);
}
@@ -24607,6 +24654,10 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
ZigType *src_type = ptr->value.type;
assert(!type_is_invalid(src_type));
+ if (src_type == dest_type) {
+ return ptr;
+ }
+
// We have a check for zero bits later so we use get_src_ptr_type to
// validate src_type and dest_type.
@@ -24656,6 +24707,9 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
IrInstruction *result;
if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
+
+ if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
} else {
result = ir_const(ira, source_instr, dest_type);
}
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 89cfab22c2..da7ae38e5f 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -731,7 +731,6 @@ static void ir_print_phi(IrPrint *irp, IrInstructionPhi *phi_instruction) {
}
static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerInitList *instruction) {
- ir_print_other_instruction(irp, instruction->container_type);
fprintf(irp->f, "{");
if (instruction->item_count > 50) {
fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
@@ -743,11 +742,11 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni
ir_print_other_instruction(irp, result_loc);
}
}
- fprintf(irp->f, "}");
+ fprintf(irp->f, "}result=");
+ ir_print_other_instruction(irp, instruction->result_loc);
}
static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerInitFields *instruction) {
- ir_print_other_instruction(irp, instruction->container_type);
fprintf(irp->f, "{");
for (size_t i = 0; i < instruction->field_count; i += 1) {
IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
@@ -755,7 +754,8 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
ir_print_other_instruction(irp, field->result_loc);
}
- fprintf(irp->f, "} // container init");
+ fprintf(irp->f, "}result=");
+ ir_print_other_instruction(irp, instruction->result_loc);
}
static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 0917c3dbb4..c64f5b38a5 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -216,9 +216,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const obj = AstObject{ .lhsExpr = lhsExpr };
\\}
,
- "tmp.zig:4:19: error: union 'AstObject' depends on itself",
- "tmp.zig:2:5: note: while checking this field",
+ "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
"tmp.zig:5:5: note: while checking this field",
+ "tmp.zig:2:5: note: while checking this field",
);
cases.add(
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 99efa0e7be..f44ca541eb 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -1214,7 +1214,7 @@ test "spill target expr in a for loop" {
}
const Foo = struct {
- slice: []i32,
+ slice: []const i32,
};
fn atest(foo: *Foo) i32 {
@@ -1245,7 +1245,7 @@ test "spill target expr in a for loop, with a var decl in the loop body" {
}
const Foo = struct {
- slice: []i32,
+ slice: []const i32,
};
fn atest(foo: *Foo) i32 {
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index 76ecad6b43..571343e281 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -709,3 +709,23 @@ test "packed struct field passed to generic function" {
var loaded = S.genericReadPackedField(&p.b);
expect(loaded == 29);
}
+
+test "anonymous struct literal syntax" {
+ const S = struct {
+ const Point = struct {
+ x: i32,
+ y: i32,
+ };
+
+ fn doTheTest() void {
+ var p: Point = .{
+ .x = 1,
+ .y = 2,
+ };
+ expect(p.x == 1);
+ expect(p.y == 2);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From b4ad3e71af77b2be4467d67b64c721adfe86ac17 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 11:14:45 -0500
Subject: [PATCH 064/129] add behavior test case for anon union literal
---
test/stage1/behavior/union.zig | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index 497aa7e574..de98a26d55 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -549,3 +549,21 @@ test "initialize global array of union" {
expect(glbl_array[0].U0 == 1);
expect(glbl_array[1].U1 == 2);
}
+
+test "anonymous union literal syntax" {
+ const S = struct {
+ const Number = union {
+ int: i32,
+ float: f64,
+ };
+
+ fn doTheTest() void {
+ var i: Number = .{.int = 42};
+ var f: Number = .{.float = 12.34};
+ expect(i.int == 42);
+ expect(f.float == 12.34);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From 725b6ee634f01355da4a6badc5675751b85f0bf0 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 11:41:17 -0500
Subject: [PATCH 065/129] add behavior test case for anonymous list literal
syntax
---
test/stage1/behavior/array.zig | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig
index f9ca1efdb9..0558a47fa4 100644
--- a/test/stage1/behavior/array.zig
+++ b/test/stage1/behavior/array.zig
@@ -298,3 +298,17 @@ test "implicit cast zero sized array ptr to slice" {
const c: []const u8 = &b;
expect(c.len == 0);
}
+
+test "anonymous list literal syntax" {
+ const S = struct {
+ fn doTheTest() void {
+ var array: [4]u8 = .{1, 2, 3, 4};
+ expect(array[0] == 1);
+ expect(array[1] == 2);
+ expect(array[2] == 3);
+ expect(array[3] == 4);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From d4e6a6d5e27df845d47b254aab9d14f44d68d620 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 13:10:06 -0500
Subject: [PATCH 066/129] zig fmt: support anon struct and anon list init
syntax
---
lib/std/zig/ast.zig | 21 +++++++++++---
lib/std/zig/parse.zig | 52 ++++++++++++++++++++-------------
lib/std/zig/parser_test.zig | 17 +++++++++++
lib/std/zig/render.zig | 57 +++++++++++++++++++++++++++----------
4 files changed, 108 insertions(+), 39 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 9f32c6e54b..e705aea477 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -1648,10 +1648,15 @@ pub const Node = struct {
pub const SuffixOp = struct {
base: Node,
- lhs: *Node,
+ lhs: Lhs,
op: Op,
rtoken: TokenIndex,
+ pub const Lhs = union(enum) {
+ node: *Node,
+ dot: TokenIndex,
+ };
+
pub const Op = union(enum) {
Call: Call,
ArrayAccess: *Node,
@@ -1679,8 +1684,13 @@ pub const Node = struct {
pub fn iterate(self: *SuffixOp, index: usize) ?*Node {
var i = index;
- if (i < 1) return self.lhs;
- i -= 1;
+ switch (self.lhs) {
+ .node => |node| {
+ if (i == 0) return node;
+ i -= 1;
+ },
+ .dot => {},
+ }
switch (self.op) {
.Call => |*call_info| {
@@ -1721,7 +1731,10 @@ pub const Node = struct {
.Call => |*call_info| if (call_info.async_token) |async_token| return async_token,
else => {},
}
- return self.lhs.firstToken();
+ switch (self.lhs) {
+ .node => |node| return node.firstToken(),
+ .dot => |dot| return dot,
+ }
}
pub fn lastToken(self: *const SuffixOp) TokenIndex {
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 4c6c461c01..6d5d4b5f2d 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -1026,16 +1026,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// CurlySuffixExpr <- TypeExpr InitList?
fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
- const init_list = (try parseInitList(arena, it, tree)) orelse return type_expr;
- init_list.cast(Node.SuffixOp).?.lhs = type_expr;
- return init_list;
+ const suffix_op = (try parseInitList(arena, it, tree)) orelse return type_expr;
+ suffix_op.lhs.node = type_expr;
+ return &suffix_op.base;
}
/// InitList
/// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
/// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
/// / LBRACE RBRACE
-fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.SuffixOp {
const lbrace = eatToken(it, .LBrace) orelse return null;
var init_list = Node.SuffixOp.Op.InitList.init(arena);
@@ -1064,11 +1064,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const node = try arena.create(Node.SuffixOp);
node.* = Node.SuffixOp{
.base = Node{ .id = .SuffixOp },
- .lhs = undefined, // set by caller
+ .lhs = .{.node = undefined}, // set by caller
.op = op,
.rtoken = try expectToken(it, tree, .RBrace),
};
- return &node.base;
+ return node;
}
/// TypeExpr <- PrefixTypeOp* ErrorUnionExpr
@@ -1117,7 +1117,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
while (try parseSuffixOp(arena, it, tree)) |node| {
switch (node.id) {
- .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
+ .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
.InfixOp => node.cast(Node.InfixOp).?.lhs = res,
else => unreachable,
}
@@ -1133,7 +1133,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const node = try arena.create(Node.SuffixOp);
node.* = Node.SuffixOp{
.base = Node{ .id = .SuffixOp },
- .lhs = res,
+ .lhs = .{.node = res},
.op = Node.SuffixOp.Op{
.Call = Node.SuffixOp.Op.Call{
.params = params.list,
@@ -1150,7 +1150,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
while (true) {
if (try parseSuffixOp(arena, it, tree)) |node| {
switch (node.id) {
- .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
+ .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
.InfixOp => node.cast(Node.InfixOp).?.lhs = res,
else => unreachable,
}
@@ -1161,7 +1161,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const call = try arena.create(Node.SuffixOp);
call.* = Node.SuffixOp{
.base = Node{ .id = .SuffixOp },
- .lhs = res,
+ .lhs = .{.node = res},
.op = Node.SuffixOp.Op{
.Call = Node.SuffixOp.Op.Call{
.params = params.list,
@@ -1215,7 +1215,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
return &node.base;
}
if (try parseContainerDecl(arena, it, tree)) |node| return node;
- if (try parseEnumLiteral(arena, it, tree)) |node| return node;
+ if (try parseAnonLiteral(arena, it, tree)) |node| return node;
if (try parseErrorSetDecl(arena, it, tree)) |node| return node;
if (try parseFloatLiteral(arena, it, tree)) |node| return node;
if (try parseFnProto(arena, it, tree)) |node| return node;
@@ -1494,16 +1494,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
}
/// DOT IDENTIFIER
-fn parseEnumLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const dot = eatToken(it, .Period) orelse return null;
- const name = try expectToken(it, tree, .Identifier);
- const node = try arena.create(Node.EnumLiteral);
- node.* = Node.EnumLiteral{
- .base = Node{ .id = .EnumLiteral },
- .dot = dot,
- .name = name,
- };
- return &node.base;
+
+ // anon enum literal
+ if (eatToken(it, .Identifier)) |name| {
+ const node = try arena.create(Node.EnumLiteral);
+ node.* = Node.EnumLiteral{
+ .base = Node{ .id = .EnumLiteral },
+ .dot = dot,
+ .name = name,
+ };
+ return &node.base;
+ }
+
+ // anon container literal
+ if (try parseInitList(arena, it, tree)) |node| {
+ node.lhs = .{.dot = dot};
+ return &node.base;
+ }
+
+ putBackToken(it, dot);
+ return null;
}
/// AsmOutput <- COLON AsmOutputList AsmInput?
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index e9b4cd6455..f61442adfc 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,3 +1,20 @@
+test "zig fmt: anon struct literal syntax" {
+ try testCanonical(
+ \\const x = .{
+ \\ .a = b,
+ \\ .c = d,
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: anon list literal syntax" {
+ try testCanonical(
+ \\const x = .{ a, b, c };
+ \\
+ );
+}
+
test "zig fmt: async function" {
try testCanonical(
\\pub const Server = struct {
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index c6912087cf..c824939296 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -538,9 +538,9 @@ fn renderExpression(
try renderToken(tree, stream, async_token, indent, start_col, Space.Space);
}
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
- const lparen = tree.nextToken(suffix_op.lhs.lastToken());
+ const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
if (call_info.params.len == 0) {
try renderToken(tree, stream, lparen, indent, start_col, Space.None);
@@ -598,7 +598,7 @@ fn renderExpression(
const lbracket = tree.prevToken(index_expr.firstToken());
const rbracket = tree.nextToken(index_expr.lastToken());
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment;
@@ -616,18 +616,18 @@ fn renderExpression(
},
ast.Node.SuffixOp.Op.Deref => {
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .*
},
ast.Node.SuffixOp.Op.UnwrapOptional => {
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ?
},
@TagType(ast.Node.SuffixOp.Op).Slice => |range| {
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
const lbracket = tree.prevToken(range.start.firstToken());
const dotdot = tree.nextToken(range.start.lastToken());
@@ -647,10 +647,16 @@ fn renderExpression(
},
ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
- const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
+ const lbrace = switch (suffix_op.lhs) {
+ .dot => |dot| tree.nextToken(dot),
+ .node => |node| tree.nextToken(node.lastToken()),
+ };
if (field_inits.len == 0) {
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None);
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
@@ -691,7 +697,10 @@ fn renderExpression(
break :blk;
}
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
@@ -699,7 +708,10 @@ fn renderExpression(
if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
// render all on one line, no trailing comma
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
var it = field_inits.iterator(0);
@@ -719,7 +731,10 @@ fn renderExpression(
const new_indent = indent + indent_delta;
- try renderExpression(allocator, stream, tree, new_indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, new_indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
var it = field_inits.iterator(0);
@@ -743,23 +758,35 @@ fn renderExpression(
},
ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
- const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
+ const lbrace = switch (suffix_op.lhs) {
+ .dot => |dot| tree.nextToken(dot),
+ .node => |node| tree.nextToken(node.lastToken()),
+ };
if (exprs.len == 0) {
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) {
const expr = exprs.at(0).*;
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
- try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ switch (suffix_op.lhs) {
+ .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
+ .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
+ }
// scan to find row size
const maybe_row_size: ?usize = blk: {
From 1bca8e693d42256d575c76fbab5c68d86c0c4bc3 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 13:18:16 -0500
Subject: [PATCH 067/129] fix anon literal used with return result loc
---
src/ir.cpp | 10 +++++++++-
test/stage1/behavior/union.zig | 6 +++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index f1b31af582..e278193785 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -6151,7 +6151,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
init_array_type_source_node = container_type->source_node;
} else {
child_result_loc = parent_result_loc;
- init_array_type_source_node = parent_result_loc->source_instruction->source_node;
+ if (parent_result_loc->source_instruction != nullptr) {
+ init_array_type_source_node = parent_result_loc->source_instruction->source_node;
+ } else {
+ init_array_type_source_node = node;
+ }
}
switch (kind) {
@@ -15935,6 +15939,10 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
instruction->result_loc->source_instruction->child);
if (type_is_invalid(implicit_elem_type))
return ira->codegen->invalid_instruction;
+ } else if (instruction->result_loc->id == ResultLocIdReturn) {
+ implicit_elem_type = ira->explicit_return_type;
+ if (type_is_invalid(implicit_elem_type))
+ return ira->codegen->invalid_instruction;
} else {
Buf *bare_name = buf_alloc();
Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index de98a26d55..caad1d474f 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -559,10 +559,14 @@ test "anonymous union literal syntax" {
fn doTheTest() void {
var i: Number = .{.int = 42};
- var f: Number = .{.float = 12.34};
+ var f = makeNumber();
expect(i.int == 42);
expect(f.float == 12.34);
}
+
+ fn makeNumber() Number {
+ return .{.float = 12.34};
+ }
};
S.doTheTest();
comptime S.doTheTest();
From ca2a788a240bbc3fa8060471bcda845e543dac70 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 17:50:41 -0500
Subject: [PATCH 068/129] fully anonymous struct literals
---
src/all_types.hpp | 13 +++
src/analyze.cpp | 133 ++++++++++++++++++--------
src/analyze.hpp | 3 +-
src/ir.cpp | 163 ++++++++++++++++++++++++++++----
test/stage1/behavior/struct.zig | 22 +++++
5 files changed, 271 insertions(+), 63 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 4d751bae2c..e38e857209 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1187,10 +1187,22 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;
static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;
+struct InferredStructField {
+ ZigType *inferred_struct_type;
+ Buf *field_name;
+};
+
struct ZigTypePointer {
ZigType *child_type;
ZigType *slice_parent;
+ // Anonymous struct literal syntax uses this when the result location has
+ // no type in it. This field is null if this pointer does not refer to
+ // a field of a currently-being-inferred struct type.
+ // When this is non-null, the pointer is pointing to the base of the inferred
+ // struct.
+ InferredStructField *inferred_struct_field;
+
PtrLen ptr_len;
uint32_t explicit_alignment; // 0 means use ABI alignment
@@ -1743,6 +1755,7 @@ struct TypeId {
union {
struct {
ZigType *child_type;
+ InferredStructField *inferred_struct_field;
PtrLen ptr_len;
uint32_t alignment;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ae5b626c29..d8ff4f2848 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -486,7 +486,7 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {
ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,
- uint32_t vector_index)
+ uint32_t vector_index, InferredStructField *inferred_struct_field)
{
assert(ptr_len != PtrLenC || allow_zero);
assert(!type_is_invalid(child_type));
@@ -509,7 +509,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
TypeId type_id = {};
ZigType **parent_pointer = nullptr;
if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
- allow_zero || vector_index != VECTOR_INDEX_NONE)
+ allow_zero || vector_index != VECTOR_INDEX_NONE || inferred_struct_field != nullptr)
{
type_id.id = ZigTypeIdPointer;
type_id.data.pointer.child_type = child_type;
@@ -521,6 +521,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
type_id.data.pointer.ptr_len = ptr_len;
type_id.data.pointer.allow_zero = allow_zero;
type_id.data.pointer.vector_index = vector_index;
+ type_id.data.pointer.inferred_struct_field = inferred_struct_field;
auto existing_entry = g->type_table.maybe_get(type_id);
if (existing_entry)
@@ -548,8 +549,15 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
}
buf_resize(&entry->name, 0);
if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {
- buf_appendf(&entry->name, "%s%s%s%s%s",
- star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
+ if (inferred_struct_field == nullptr) {
+ buf_appendf(&entry->name, "%s%s%s%s%s",
+ star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
+ } else {
+ buf_appendf(&entry->name, "(%s%s%s%s field '%s' of %s)",
+ star_str, const_str, volatile_str, allow_zero_str,
+ buf_ptr(inferred_struct_field->field_name),
+ buf_ptr(&inferred_struct_field->inferred_struct_type->name));
+ }
} else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {
buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
@@ -606,6 +614,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
entry->data.pointer.host_int_bytes = host_int_bytes;
entry->data.pointer.allow_zero = allow_zero;
entry->data.pointer.vector_index = vector_index;
+ entry->data.pointer.inferred_struct_field = inferred_struct_field;
if (parent_pointer) {
*parent_pointer = entry;
@@ -620,12 +629,12 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
{
return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,
- byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE);
+ byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE, nullptr);
}
ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,
- VECTOR_INDEX_NONE);
+ VECTOR_INDEX_NONE, nullptr);
}
ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
@@ -2082,7 +2091,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
}
assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
- assert(decl_node->type == NodeTypeContainerDecl);
+ assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
size_t field_count = struct_type->data.structure.src_field_count;
@@ -2670,7 +2679,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
return ErrorNone;
AstNode *decl_node = struct_type->data.structure.decl_node;
- assert(decl_node->type == NodeTypeContainerDecl);
if (struct_type->data.structure.resolve_loop_flag_zero_bits) {
if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
@@ -2681,29 +2689,46 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
}
return ErrorSemanticAnalyzeFail;
}
-
struct_type->data.structure.resolve_loop_flag_zero_bits = true;
- assert(!struct_type->data.structure.fields);
- size_t field_count = decl_node->data.container_decl.fields.length;
- struct_type->data.structure.src_field_count = (uint32_t)field_count;
- struct_type->data.structure.fields = allocate(field_count);
+ size_t field_count;
+ if (decl_node->type == NodeTypeContainerDecl) {
+ field_count = decl_node->data.container_decl.fields.length;
+ struct_type->data.structure.src_field_count = (uint32_t)field_count;
+
+ src_assert(struct_type->data.structure.fields == nullptr, decl_node);
+ struct_type->data.structure.fields = allocate(field_count);
+ } else if (decl_node->type == NodeTypeContainerInitExpr) {
+ src_assert(struct_type->data.structure.is_inferred, decl_node);
+ src_assert(struct_type->data.structure.fields != nullptr, decl_node);
+
+ field_count = struct_type->data.structure.src_field_count;
+ } else zig_unreachable();
+
struct_type->data.structure.fields_by_name.init(field_count);
Scope *scope = &struct_type->data.structure.decls_scope->base;
size_t gen_field_index = 0;
for (size_t i = 0; i < field_count; i += 1) {
- AstNode *field_node = decl_node->data.container_decl.fields.at(i);
TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
- type_struct_field->name = field_node->data.struct_field.name;
- type_struct_field->decl_node = field_node;
- if (field_node->data.struct_field.type == nullptr) {
- add_node_error(g, field_node, buf_sprintf("struct field missing type"));
- struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- return ErrorSemanticAnalyzeFail;
- }
+ AstNode *field_node;
+ if (decl_node->type == NodeTypeContainerDecl) {
+ field_node = decl_node->data.container_decl.fields.at(i);
+ type_struct_field->name = field_node->data.struct_field.name;
+ type_struct_field->decl_node = field_node;
+
+ if (field_node->data.struct_field.type == nullptr) {
+ add_node_error(g, field_node, buf_sprintf("struct field missing type"));
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ return ErrorSemanticAnalyzeFail;
+ }
+ } else if (decl_node->type == NodeTypeContainerInitExpr) {
+ field_node = type_struct_field->decl_node;
+
+ src_assert(type_struct_field->type_entry != nullptr, field_node);
+ } else zig_unreachable();
auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);
if (field_entry != nullptr) {
@@ -2714,16 +2739,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
return ErrorSemanticAnalyzeFail;
}
- ConstExprValue *field_type_val = analyze_const_value(g, scope,
- field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
- if (type_is_invalid(field_type_val->type)) {
- struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- return ErrorSemanticAnalyzeFail;
- }
- assert(field_type_val->special != ConstValSpecialRuntime);
- type_struct_field->type_val = field_type_val;
- if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
- return ErrorSemanticAnalyzeFail;
+ ConstExprValue *field_type_val;
+ if (decl_node->type == NodeTypeContainerDecl) {
+ field_type_val = analyze_const_value(g, scope,
+ field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
+ if (type_is_invalid(field_type_val->type)) {
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ return ErrorSemanticAnalyzeFail;
+ }
+ assert(field_type_val->special != ConstValSpecialRuntime);
+ type_struct_field->type_val = field_type_val;
+ if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
+ return ErrorSemanticAnalyzeFail;
+ } else if (decl_node->type == NodeTypeContainerInitExpr) {
+ field_type_val = type_struct_field->type_val;
+ } else zig_unreachable();
bool field_is_opaque_type;
if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
@@ -2807,7 +2837,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
}
struct_type->data.structure.resolve_loop_flag_other = true;
- assert(decl_node->type == NodeTypeContainerDecl);
+ assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
size_t field_count = struct_type->data.structure.src_field_count;
bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;
@@ -2817,7 +2847,8 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
if (field->gen_index == SIZE_MAX)
continue;
- AstNode *align_expr = field->decl_node->data.struct_field.align_expr;
+ AstNode *align_expr = (field->decl_node->type == NodeTypeStructField) ?
+ field->decl_node->data.struct_field.align_expr : nullptr;
if (align_expr != nullptr) {
if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,
&field->align))
@@ -5416,6 +5447,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
if (type_entry->one_possible_value != OnePossibleValueInvalid)
return type_entry->one_possible_value;
+ if (type_entry->id == ZigTypeIdStruct &&
+ type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
+ {
+ return OnePossibleValueNo;
+ }
+
Error err;
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
return OnePossibleValueInvalid;
@@ -5820,9 +5857,15 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
ConstExprValue *create_const_vals(size_t count) {
- ConstGlobalRefs *global_refs = allocate(count, "ConstGlobalRefs");
- ConstExprValue *vals = allocate(count, "ConstExprValue");
- for (size_t i = 0; i < count; i += 1) {
+ return realloc_const_vals(nullptr, 0, count);
+}
+
+ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count) {
+ ConstGlobalRefs *old_global_refs = (base == nullptr) ? nullptr : base->global_refs;
+ ConstGlobalRefs *global_refs = reallocate(old_global_refs, old_count,
+ new_count, "ConstGlobalRefs");
+ ConstExprValue *vals = reallocate(base, old_count, new_count, "ConstExprValue");
+ for (size_t i = old_count; i < new_count; i += 1) {
vals[i].global_refs = &global_refs[i];
}
return vals;
@@ -7002,7 +7045,16 @@ bool type_id_eql(TypeId a, TypeId b) {
a.data.pointer.alignment == b.data.pointer.alignment &&
a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
a.data.pointer.vector_index == b.data.pointer.vector_index &&
- a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;
+ a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes &&
+ (
+ a.data.pointer.inferred_struct_field == b.data.pointer.inferred_struct_field ||
+ (a.data.pointer.inferred_struct_field != nullptr &&
+ b.data.pointer.inferred_struct_field != nullptr &&
+ a.data.pointer.inferred_struct_field->inferred_struct_type ==
+ b.data.pointer.inferred_struct_field->inferred_struct_type &&
+ buf_eql_buf(a.data.pointer.inferred_struct_field->field_name,
+ b.data.pointer.inferred_struct_field->field_name))
+ );
case ZigTypeIdArray:
return a.data.array.child_type == b.data.array.child_type &&
a.data.array.size == b.data.array.size;
@@ -7815,7 +7867,6 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
ZigLLVMDIScope *di_scope;
unsigned line;
if (decl_node != nullptr) {
- assert(decl_node->type == NodeTypeContainerDecl);
Scope *scope = &struct_type->data.structure.decls_scope->base;
ZigType *import = get_scope_import(scope);
di_file = import->data.structure.root_struct->di_file;
@@ -8018,7 +8069,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
}
unsigned line;
if (decl_node != nullptr) {
- AstNode *field_node = decl_node->data.container_decl.fields.at(i);
+ AstNode *field_node = field->decl_node;
line = field_node->line + 1;
} else {
line = 0;
@@ -8314,12 +8365,12 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus
if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {
peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,
PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,
- VECTOR_INDEX_NONE);
+ VECTOR_INDEX_NONE, nullptr);
} else {
uint32_t host_vec_len = type->data.pointer.host_int_bytes;
ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);
peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,
- PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE);
+ PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr);
}
type->llvm_type = get_llvm_type(g, peer_type);
type->llvm_di_type = get_llvm_di_type(g, peer_type);
diff --git a/src/analyze.hpp b/src/analyze.hpp
index a6af371e25..7de51092e8 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -24,7 +24,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,
ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,
bool is_const, bool is_volatile, PtrLen ptr_len,
uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,
- bool allow_zero, uint32_t vector_index);
+ bool allow_zero, uint32_t vector_index, InferredStructField *inferred_struct_field);
uint64_t type_size(CodeGen *g, ZigType *type_entry);
uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
@@ -175,6 +175,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
ConstExprValue *create_const_vals(size_t count);
+ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count);
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
diff --git a/src/ir.cpp b/src/ir.cpp
index e278193785..fb2b0ed841 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -202,6 +202,8 @@ static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char
Scope *scope, AstNode *source_node, Buf *out_bare_name);
static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
ResultLoc *parent_result_loc);
+static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
+ TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -16321,13 +16323,81 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
return ir_const_void(ira, source_instr);
}
- ZigType *child_type = ptr->value.type->data.pointer.child_type;
+ InferredStructField *isf = ptr->value.type->data.pointer.inferred_struct_field;
+ if (allow_write_through_const && isf != nullptr) {
+ // Now it's time to add the field to the struct type.
+ uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
+ uint32_t new_field_count = old_field_count + 1;
+ isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
+ // This thing with max(x, 16) is a hack to allow this functionality to work without
+ // modifying the ConstExprValue layout of structs. That reworking needs to be
+ // done, but this hack lets us do it separately, in the future.
+ TypeStructField *prev_ptr = isf->inferred_struct_type->data.structure.fields;
+ isf->inferred_struct_type->data.structure.fields = reallocate(
+ isf->inferred_struct_type->data.structure.fields,
+ (old_field_count == 0) ? 0 : max(old_field_count, 16u),
+ max(new_field_count, 16u));
+ if (prev_ptr != nullptr && prev_ptr != isf->inferred_struct_type->data.structure.fields) {
+ zig_panic("TODO need to rework the layout of ZigTypeStruct. this realloc would have caused invalid pointer references");
+ }
+
+ // This reference can't live long, don't keep it around outside this block.
+ TypeStructField *field = &isf->inferred_struct_type->data.structure.fields[old_field_count];
+ field->name = isf->field_name;
+ field->type_entry = uncasted_value->value.type;
+ field->type_val = create_const_type(ira->codegen, field->type_entry);
+ field->src_index = old_field_count;
+ field->decl_node = uncasted_value->source_node;
+
+ ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
+ IrInstruction *casted_ptr;
+ if (instr_is_comptime(ptr)) {
+ casted_ptr = ir_const(ira, source_instr, struct_ptr_type);
+ copy_const_val(&casted_ptr->value, &ptr->value, false);
+ casted_ptr->value.type = struct_ptr_type;
+ } else {
+ casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, struct_ptr_type, ptr, CastOpNoop);
+ casted_ptr->value.type = struct_ptr_type;
+ }
+ if (instr_is_comptime(casted_ptr)) {
+ ConstExprValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
+ if (!ptr_val)
+ return ira->codegen->invalid_instruction;
+ if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
+ ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
+ source_instr->source_node);
+ struct_val->special = ConstValSpecialStatic;
+ ConstExprValue *prev_ptr = struct_val->data.x_struct.fields;
+ // This thing with max(x, 16) is a hack to allow this functionality to work without
+ // modifying the ConstExprValue layout of structs. That reworking needs to be
+ // done, but this hack lets us do it separately, in the future.
+ struct_val->data.x_struct.fields = realloc_const_vals(struct_val->data.x_struct.fields,
+ (old_field_count == 0) ? 0 : max(old_field_count, 16u),
+ max(new_field_count, 16u));
+ if (prev_ptr != nullptr && prev_ptr != struct_val->data.x_struct.fields) {
+ zig_panic("TODO need to rework the layout of ConstExprValue for structs. this realloc would have caused invalid pointer references");
+ }
+
+ ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];
+ field_val->special = ConstValSpecialUndef;
+ field_val->type = field->type_entry;
+ field_val->parent.id = ConstParentIdStruct;
+ field_val->parent.data.p_struct.struct_val = struct_val;
+ field_val->parent.data.p_struct.field_index = old_field_count;
+ }
+ }
+
+ ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, casted_ptr,
+ isf->inferred_struct_type, true);
+ }
if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {
ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
return ira->codegen->invalid_instruction;
}
+ ZigType *child_type = ptr->value.type->data.pointer.child_type;
IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);
if (value == ira->codegen->invalid_instruction)
return ira->codegen->invalid_instruction;
@@ -17853,7 +17923,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
elem_ptr_instruction->ptr_len,
- get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index);
+ get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index,
+ nullptr);
} else if (return_type->data.pointer.explicit_alignment != 0) {
// figure out the largest alignment possible
@@ -18094,7 +18165,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
elem_ptr_instruction->ptr_len,
- get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME);
+ get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME,
+ nullptr);
} else {
// runtime known element index
switch (type_requires_comptime(ira->codegen, return_type)) {
@@ -18210,31 +18282,34 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
case OnePossibleValueNo:
break;
}
- ResolveStatus needed_resolve_status =
- (struct_type->data.structure.layout == ContainerLayoutAuto) ?
- ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
- if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
- return ira->codegen->invalid_instruction;
- assert(struct_ptr->value.type->id == ZigTypeIdPointer);
- uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
- uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
- uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
- get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
bool is_const = struct_ptr->value.type->data.pointer.is_const;
bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
- ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
- is_const, is_volatile, PtrLenSingle, field->align,
- (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
- (uint32_t)host_int_bytes_for_result_type, false);
+ ZigType *ptr_type;
+ if (struct_type->data.structure.is_inferred) {
+ ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
+ is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
+ } else {
+ ResolveStatus needed_resolve_status =
+ (struct_type->data.structure.layout == ContainerLayoutAuto) ?
+ ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
+ if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
+ return ira->codegen->invalid_instruction;
+ assert(struct_ptr->value.type->id == ZigTypeIdPointer);
+ uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
+ uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
+ uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
+ get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
+ ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
+ is_const, is_volatile, PtrLenSingle, field->align,
+ (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
+ (uint32_t)host_int_bytes_for_result_type, false);
+ }
if (instr_is_comptime(struct_ptr)) {
ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
if (!ptr_val)
return ira->codegen->invalid_instruction;
if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
- if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusSizeKnown)))
- return ira->codegen->invalid_instruction;
-
ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
if (struct_val == nullptr)
return ira->codegen->invalid_instruction;
@@ -18246,7 +18321,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
field_val->special = ConstValSpecialUndef;
- field_val->type = struct_type->data.structure.fields[i].type_entry;
+ field_val->type = resolve_struct_field_type(ira->codegen,
+ &struct_type->data.structure.fields[i]);
field_val->parent.id = ConstParentIdStruct;
field_val->parent.data.p_struct.struct_val = struct_val;
field_val->parent.data.p_struct.field_index = i;
@@ -18275,6 +18351,40 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
return result;
}
+static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
+ IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type)
+{
+ // The type of the field is not available until a store using this pointer happens.
+ // So, here we create a special pointer type which has the inferred struct type and
+ // field name encoded in the type. Later, when there is a store via this pointer,
+ // the field type will then be available, and the field will be added to the inferred
+ // struct.
+
+ ZigType *container_ptr_type = container_ptr->value.type;
+ ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr);
+
+ InferredStructField *inferred_struct_field = allocate(1, "InferredStructField");
+ inferred_struct_field->inferred_struct_type = container_type;
+ inferred_struct_field->field_name = field_name;
+
+ ZigType *elem_type = ira->codegen->builtin_types.entry_c_void;
+ ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
+ container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile,
+ PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field);
+
+ if (instr_is_comptime(container_ptr)) {
+ IrInstruction *result = ir_const(ira, source_instr, field_ptr_type);
+ copy_const_val(&result->value, &container_ptr->value, false);
+ result->value.type = field_ptr_type;
+ return result;
+ }
+
+ IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, field_ptr_type, container_ptr, CastOpNoop);
+ result->value.type = field_ptr_type;
+ return result;
+}
+
static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)
{
@@ -18282,6 +18392,12 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
ZigType *bare_type = container_ref_type(container_type);
+ if (initializing && bare_type->id == ZigTypeIdStruct &&
+ bare_type->data.structure.resolve_status == ResolveStatusBeingInferred)
+ {
+ return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type);
+ }
+
if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
@@ -20056,6 +20172,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
return ira->codegen->invalid_instruction;
}
+ if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) {
+ // We're now done inferring the type.
+ container_type->data.structure.resolve_status = ResolveStatusUnstarted;
+ }
+
if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index 571343e281..6b9ddacabc 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -729,3 +729,25 @@ test "anonymous struct literal syntax" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "fully anonymous struct" {
+ const S = struct {
+ fn doTheTest() void {
+ dump(.{
+ .int = @as(u32, 1234),
+ .float = @as(f64, 12.34),
+ .b = true,
+ .s = "hi",
+ });
+ }
+ fn dump(args: var) void {
+ expect(args.int == 1234);
+ expect(args.float == 12.34);
+ expect(args.b);
+ expect(args.s[0] == 'h');
+ expect(args.s[1] == 'i');
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From a33b9aec724dfce68889f6255a2c78572b47c92f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 18:01:27 -0500
Subject: [PATCH 069/129] add test for missing const in slice with nested array
type
---
test/compile_errors.zig | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index c64f5b38a5..1adf3c3f8e 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,23 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "missing const in slice with nested array type",
+ \\const Geo3DTex2D = struct { vertices: [][2]f32 };
+ \\pub fn getGeo3DTex2D() Geo3DTex2D {
+ \\ return Geo3DTex2D{
+ \\ .vertices = [_][2]f32{
+ \\ [_]f32{ -0.5, -0.5},
+ \\ },
+ \\ };
+ \\}
+ \\export fn entry() void {
+ \\ var geo_data = getGeo3DTex2D();
+ \\}
+ ,
+ "tmp.zig:4:30: error: expected type '[][2]f32', found '[1][2]f32'",
+ );
+
cases.add(
"slicing of global undefined pointer",
\\var buf: *[1]u8 = undefined;
From b9482fc32d13886626692484e5a778355fa7934c Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 19:00:39 -0500
Subject: [PATCH 070/129] implement fully anonymous list literals
---
src/analyze.cpp | 12 ++---
src/analyze.hpp | 1 -
src/ir.cpp | 85 ++++++++++++++++++++-------------
test/stage1/behavior/struct.zig | 17 +++++++
4 files changed, 73 insertions(+), 42 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index d8ff4f2848..316fa52ac5 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -5857,15 +5857,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
ConstExprValue *create_const_vals(size_t count) {
- return realloc_const_vals(nullptr, 0, count);
-}
-
-ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count) {
- ConstGlobalRefs *old_global_refs = (base == nullptr) ? nullptr : base->global_refs;
- ConstGlobalRefs *global_refs = reallocate(old_global_refs, old_count,
- new_count, "ConstGlobalRefs");
- ConstExprValue *vals = reallocate(base, old_count, new_count, "ConstExprValue");
- for (size_t i = old_count; i < new_count; i += 1) {
+ ConstGlobalRefs *global_refs = allocate(count, "ConstGlobalRefs");
+ ConstExprValue *vals = allocate(count, "ConstExprValue");
+ for (size_t i = 0; i < count; i += 1) {
vals[i].global_refs = &global_refs[i];
}
return vals;
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 7de51092e8..06c8847eda 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -175,7 +175,6 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
ConstExprValue *create_const_vals(size_t count);
-ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count);
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
diff --git a/src/ir.cpp b/src/ir.cpp
index fb2b0ed841..9d15e341da 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -204,6 +204,8 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de
ResultLoc *parent_result_loc);
static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
+static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
+ IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -16329,16 +16331,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
uint32_t new_field_count = old_field_count + 1;
isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
- // This thing with max(x, 16) is a hack to allow this functionality to work without
- // modifying the ConstExprValue layout of structs. That reworking needs to be
- // done, but this hack lets us do it separately, in the future.
- TypeStructField *prev_ptr = isf->inferred_struct_type->data.structure.fields;
- isf->inferred_struct_type->data.structure.fields = reallocate(
- isf->inferred_struct_type->data.structure.fields,
- (old_field_count == 0) ? 0 : max(old_field_count, 16u),
- max(new_field_count, 16u));
- if (prev_ptr != nullptr && prev_ptr != isf->inferred_struct_type->data.structure.fields) {
- zig_panic("TODO need to rework the layout of ZigTypeStruct. this realloc would have caused invalid pointer references");
+ if (new_field_count > 16) {
+ // This thing with 16 is a hack to allow this functionality to work without
+ // modifying the ConstExprValue layout of structs. That reworking needs to be
+ // done, but this hack lets us do it separately, in the future.
+ zig_panic("TODO need to rework the layout of ZigTypeStruct. This realloc would have caused invalid pointer references");
+ }
+ if (isf->inferred_struct_type->data.structure.fields == nullptr) {
+ isf->inferred_struct_type->data.structure.fields = allocate(16);
}
// This reference can't live long, don't keep it around outside this block.
@@ -16368,15 +16368,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
source_instr->source_node);
struct_val->special = ConstValSpecialStatic;
- ConstExprValue *prev_ptr = struct_val->data.x_struct.fields;
- // This thing with max(x, 16) is a hack to allow this functionality to work without
- // modifying the ConstExprValue layout of structs. That reworking needs to be
- // done, but this hack lets us do it separately, in the future.
- struct_val->data.x_struct.fields = realloc_const_vals(struct_val->data.x_struct.fields,
- (old_field_count == 0) ? 0 : max(old_field_count, 16u),
- max(new_field_count, 16u));
- if (prev_ptr != nullptr && prev_ptr != struct_val->data.x_struct.fields) {
- zig_panic("TODO need to rework the layout of ConstExprValue for structs. this realloc would have caused invalid pointer references");
+ if (new_field_count > 16) {
+ // This thing with 16 is a hack to allow this functionality to work without
+ // modifying the ConstExprValue layout of structs. That reworking needs to be
+ // done, but this hack lets us do it separately, in the future.
+ zig_panic("TODO need to rework the layout of ConstExprValue for structs. This realloc would have caused invalid pointer references");
+ }
+ if (struct_val->data.x_struct.fields == nullptr) {
+ struct_val->data.x_struct.fields = create_const_vals(16);
}
ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];
@@ -17893,6 +17892,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
} else if (array_type->id == ZigTypeIdVector) {
// This depends on whether the element index is comptime, so it is computed later.
return_type = nullptr;
+ } else if (elem_ptr_instruction->init_array_type_source_node != nullptr &&
+ array_type->id == ZigTypeIdStruct &&
+ array_type->data.structure.resolve_status == ResolveStatusBeingInferred)
+ {
+ ZigType *usize = ira->codegen->builtin_types.entry_usize;
+ IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize);
+ if (casted_elem_index == ira->codegen->invalid_instruction)
+ return ira->codegen->invalid_instruction;
+ ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base);
+ Buf *field_name = buf_alloc();
+ bigint_append_buf(field_name, &casted_elem_index->value.data.x_bigint, 10);
+ return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base,
+ array_ptr, array_type);
} else {
ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));
@@ -20246,8 +20258,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
TypeStructField *field = &container_type->data.structure.fields[i];
if (field->init_val == nullptr) {
// it's not memoized. time to go analyze it
- assert(field->decl_node->type == NodeTypeStructField);
- AstNode *init_node = field->decl_node->data.struct_field.value;
+ AstNode *init_node;
+ if (field->decl_node->type == NodeTypeStructField) {
+ init_node = field->decl_node->data.struct_field.value;
+ } else {
+ init_node = nullptr;
+ }
if (init_node == nullptr) {
ir_add_error_node(ira, instruction->source_node,
buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
@@ -20337,23 +20353,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);
}
- if (container_type->id != ZigTypeIdArray) {
+ if (container_type->id == ZigTypeIdArray) {
+ ZigType *child_type = container_type->data.array.child_type;
+ if (container_type->data.array.len != elem_count) {
+ ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
+
+ ir_add_error(ira, &instruction->base,
+ buf_sprintf("expected %s literal, found %s literal",
+ buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+ } else if (container_type->id == ZigTypeIdStruct &&
+ container_type->data.structure.resolve_status == ResolveStatusBeingInferred)
+ {
+ // We're now done inferring the type.
+ container_type->data.structure.resolve_status = ResolveStatusUnstarted;
+ } else {
ir_add_error_node(ira, instruction->base.source_node,
buf_sprintf("type '%s' does not support array initialization",
buf_ptr(&container_type->name)));
return ira->codegen->invalid_instruction;
}
- ZigType *child_type = container_type->data.array.child_type;
- if (container_type->data.array.len != elem_count) {
- ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
-
- ir_add_error(ira, &instruction->base,
- buf_sprintf("expected %s literal, found %s literal",
- buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
- return ira->codegen->invalid_instruction;
- }
-
switch (type_has_one_possible_value(ira->codegen, container_type)) {
case OnePossibleValueInvalid:
return ira->codegen->invalid_instruction;
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index 6b9ddacabc..a42c261e3b 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -751,3 +751,20 @@ test "fully anonymous struct" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "fully anonymous list literal" {
+ const S = struct {
+ fn doTheTest() void {
+ dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
+ }
+ fn dump(args: var) void {
+ expect(args.@"0" == 1234);
+ expect(args.@"1" == 12.34);
+ expect(args.@"2");
+ expect(args.@"3"[0] == 'h');
+ expect(args.@"3"[1] == 'i');
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From 0c315e7f7613b085a203e9c94d222e846b5b9e46 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 19:57:57 -0500
Subject: [PATCH 071/129] update docs for anonymous struct/list literals
---
doc/langref.html.in | 113 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 112 insertions(+), 1 deletion(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 627709ec84..b0003a714b 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -1734,6 +1734,43 @@ test "array initialization with function calls" {
{#code_end#}
{#see_also|for|Slices#}
+ {#header_open|Anonymous List Literals#}
+ Similar to {#link|Enum Literals#} and {#link|Anonymous Struct Literals#}
+ the type can be omitted from array literals:
+ {#code_begin|test|anon_list#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "anonymous list literal syntax" {
+ var array: [4]u8 = .{11, 22, 33, 44};
+ assert(array[0] == 11);
+ assert(array[1] == 22);
+ assert(array[2] == 33);
+ assert(array[3] == 44);
+}
+ {#code_end#}
+
+ If there is no type in the result location then an anonymous list literal actually
+ turns into a {#link|struct#} with numbered field names:
+
+ {#code_begin|test|infer_list_literal#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "fully anonymous list literal" {
+ dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
+}
+
+fn dump(args: var) void {
+ assert(args.@"0" == 1234);
+ assert(args.@"1" == 12.34);
+ assert(args.@"2");
+ assert(args.@"3"[0] == 'h');
+ assert(args.@"3"[1] == 'i');
+}
+ {#code_end#}
+ {#header_close#}
+
{#header_open|Multidimensional Arrays#}
Mutlidimensional arrays can be created by nesting arrays:
@@ -2526,7 +2563,8 @@ test "overaligned pointer to packed struct" {
Don't worry, there will be a good solution for this use case in zig.
{#header_close#}
- {#header_open|struct Naming#}
+
+ {#header_open|Struct Naming#}
Since all structs are anonymous, Zig infers the type name based on a few rules.
- If the struct is in the initialization expression of a variable, it gets named after
@@ -2552,6 +2590,53 @@ fn List(comptime T: type) type {
}
{#code_end#}
{#header_close#}
+
+ {#header_open|Anonymous Struct Literals#}
+
+ Zig allows omitting the struct type of a literal. When the result is {#link|coerced|Type Coercion#},
+ the struct literal will directly instantiate the result location, with no copy:
+
+ {#code_begin|test|struct_result#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+const Point = struct {x: i32, y: i32};
+
+test "anonymous struct literal" {
+ var pt: Point = .{
+ .x = 13,
+ .y = 67,
+ };
+ assert(pt.x == 13);
+ assert(pt.y == 67);
+}
+ {#code_end#}
+
+ The struct type can be inferred. Here the result location does not include a type, and
+ so Zig infers the type:
+
+ {#code_begin|test|struct_anon#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "fully anonymous struct" {
+ dump(.{
+ .int = @as(u32, 1234),
+ .float = @as(f64, 12.34),
+ .b = true,
+ .s = "hi",
+ });
+}
+
+fn dump(args: var) void {
+ assert(args.int == 1234);
+ assert(args.float == 12.34);
+ assert(args.b);
+ assert(args.s[0] == 'h');
+ assert(args.s[1] == 'i');
+}
+ {#code_end#}
+ {#header_close#}
{#see_also|comptime|@fieldParentPtr#}
{#header_close#}
{#header_open|enum#}
@@ -2906,6 +2991,32 @@ test "@tagName" {
A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
to be in a {#link|packed struct#}.
{#header_close#}
+
+ {#header_open|Anonymous Union Literals#}
+
{#link|Anonymous Struct Literals#} syntax can be used to initialize unions without specifying
+ the type:
+ {#code_begin|test|anon_union#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+const Number = union {
+ int: i32,
+ float: f64,
+};
+
+test "anonymous union literal syntax" {
+ var i: Number = .{.int = 42};
+ var f = makeNumber();
+ assert(i.int == 42);
+ assert(f.float == 12.34);
+}
+
+fn makeNumber() Number {
+ return .{.float = 12.34};
+}
+ {#code_end#}
+ {#header_close#}
+
{#header_close#}
{#header_open|blocks#}
From bf8870a60bb35062b2b25867a0f9a95f6f5397ce Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 22:09:53 -0500
Subject: [PATCH 072/129] fix unresolved type making it to codegen
found this trying to build oxid
---
src/codegen.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 4861def16c..a2fc0c0687 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1699,6 +1699,10 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
}
static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
+ Error err;
+ if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown))) {
+ codegen_report_errors_and_exit(g);
+ }
if (!type_has_bits(instruction->value.type))
return nullptr;
if (!instruction->llvm_value) {
From 45d2fd9b9d86c4a5751612f62aa324d635976bf8 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Nov 2019 22:10:24 -0500
Subject: [PATCH 073/129] fix assertion failure in init_const_undefined
found this from building my tetris game
---
src/analyze.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 316fa52ac5..4c63c566e9 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -7138,7 +7138,7 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
const_val->data.x_struct.fields = create_const_vals(field_count);
for (size_t i = 0; i < field_count; i += 1) {
ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
- field_val->type = wanted_type->data.structure.fields[i].type_entry;
+ field_val->type = resolve_struct_field_type(g, &wanted_type->data.structure.fields[i]);
assert(field_val->type);
init_const_undefined(g, field_val);
field_val->parent.id = ConstParentIdStruct;
From 7e5b234b8b3a7e675a7b11eebcdaf504f2686749 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Tue, 12 Nov 2019 17:13:33 +0200
Subject: [PATCH 074/129] support atomic operations with enums
---
src/ir.cpp | 22 +++++++++++++++++++++-
test/stage1/behavior/atomics.zig | 16 ++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 9d15e341da..1e08598eca 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25618,9 +25618,29 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));
return ira->codegen->builtin_types.entry_invalid;
}
+ } else if (operand_type->id == ZigTypeIdEnum) {
+ ZigType *int_type = operand_type->data.enumeration.tag_int_type;
+ if (int_type->data.integral.bit_count < 8) {
+ ir_add_error(ira, op,
+ buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type",
+ int_type->data.integral.bit_count));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
+ uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
+ if (int_type->data.integral.bit_count > max_atomic_bits) {
+ ir_add_error(ira, op,
+ buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type",
+ max_atomic_bits, int_type->data.integral.bit_count));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
+ if (!is_power_of_2(int_type->data.integral.bit_count)) {
+ ir_add_error(ira, op,
+ buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
} else if (get_codegen_ptr_type(operand_type) == nullptr) {
ir_add_error(ira, op,
- buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name)));
+ buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name)));
return ira->codegen->builtin_types.entry_invalid;
}
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index d49589bdcc..c6344b17ca 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -107,3 +107,19 @@ test "cmpxchg on a global variable" {
_ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
expectEqual(@as(u32, 42), a_global_variable);
}
+
+test "atomic load and rmw with enum" {
+ const Value = enum(u8) {
+ a,
+ b,
+ c,
+ };
+ var x = Value.a;
+
+ expect(@atomicLoad(Value, &x, .SeqCst) != .b);
+
+ _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
+ expect(@atomicLoad(Value, &x, .SeqCst) == .c);
+ expect(@atomicLoad(Value, &x, .SeqCst) != .a);
+ expect(@atomicLoad(Value, &x, .SeqCst) != .b);
+}
From 5194fc57d1c206d71654b4f3e43bfcb300bf43c5 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Tue, 12 Nov 2019 17:40:21 +0200
Subject: [PATCH 075/129] use enum with atomics in std lib
---
lib/std/event/future.zig | 21 ++++++++++----------
lib/std/event/rwlock.zig | 32 +++++++++++++++---------------
lib/std/lazy_init.zig | 24 ++++++++++++-----------
lib/std/mutex.zig | 42 +++++++++++++++++++++-------------------
4 files changed, 62 insertions(+), 57 deletions(-)
diff --git a/lib/std/event/future.zig b/lib/std/event/future.zig
index 356d9cac79..43593b348a 100644
--- a/lib/std/event/future.zig
+++ b/lib/std/event/future.zig
@@ -12,12 +12,13 @@ pub fn Future(comptime T: type) type {
return struct {
lock: Lock,
data: T,
+ available: Available,
- /// TODO make this an enum
- /// 0 - not started
- /// 1 - started
- /// 2 - finished
- available: u8,
+ const Available = enum(u8) {
+ NotStarted,
+ Started,
+ Finished,
+ };
const Self = @This();
const Queue = std.atomic.Queue(anyframe);
@@ -34,7 +35,7 @@ pub fn Future(comptime T: type) type {
/// available.
/// Thread-safe.
pub async fn get(self: *Self) *T {
- if (@atomicLoad(u8, &self.available, .SeqCst) == 2) {
+ if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
return &self.data;
}
const held = self.lock.acquire();
@@ -46,7 +47,7 @@ pub fn Future(comptime T: type) type {
/// Gets the data without waiting for it. If it's available, a pointer is
/// returned. Otherwise, null is returned.
pub fn getOrNull(self: *Self) ?*T {
- if (@atomicLoad(u8, &self.available, .SeqCst) == 2) {
+ if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
return &self.data;
} else {
return null;
@@ -59,7 +60,7 @@ pub fn Future(comptime T: type) type {
/// It's not required to call start() before resolve() but it can be useful since
/// this method is thread-safe.
pub async fn start(self: *Self) ?*T {
- const state = @cmpxchgStrong(u8, &self.available, 0, 1, .SeqCst, .SeqCst) orelse return null;
+ const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
switch (state) {
1 => {
const held = self.lock.acquire();
@@ -74,8 +75,8 @@ pub fn Future(comptime T: type) type {
/// Make the data become available. May be called only once.
/// Before calling this, modify the `data` property.
pub fn resolve(self: *Self) void {
- const prev = @atomicRmw(u8, &self.available, .Xchg, 2, .SeqCst);
- assert(prev == 0 or prev == 1); // resolve() called twice
+ const prev = @atomicRmw(Available, &self.available, .Xchg, .Finished, .SeqCst);
+ assert(prev != .Finished); // resolve() called twice
Lock.Held.release(Lock.Held{ .lock = &self.lock });
}
};
diff --git a/lib/std/event/rwlock.zig b/lib/std/event/rwlock.zig
index c05e740b09..3a64b9df8c 100644
--- a/lib/std/event/rwlock.zig
+++ b/lib/std/event/rwlock.zig
@@ -13,17 +13,17 @@ const Loop = std.event.Loop;
/// When a write lock is held, it will not be released until the writer queue is empty.
/// TODO: make this API also work in blocking I/O mode
pub const RwLock = struct {
- shared_state: u8, // TODO make this an enum
+ shared_state: State,
writer_queue: Queue,
reader_queue: Queue,
writer_queue_empty_bit: u8, // TODO make this a bool
reader_queue_empty_bit: u8, // TODO make this a bool
reader_lock_count: usize,
- const State = struct {
- const Unlocked = 0;
- const WriteLock = 1;
- const ReadLock = 2;
+ const State = enum(u8) {
+ Unlocked,
+ WriteLock,
+ ReadLock,
};
const Queue = std.atomic.Queue(anyframe);
@@ -41,7 +41,7 @@ pub const RwLock = struct {
}
_ = @atomicRmw(u8, &self.lock.reader_queue_empty_bit, .Xchg, 1, .SeqCst);
- if (@cmpxchgStrong(u8, &self.lock.shared_state, State.ReadLock, State.Unlocked, .SeqCst, .SeqCst) != null) {
+ if (@cmpxchgStrong(State, &self.lock.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
// Didn't unlock. Someone else's problem.
return;
}
@@ -64,7 +64,7 @@ pub const RwLock = struct {
// We need to release the write lock. Check if any readers are waiting to grab the lock.
if (@atomicLoad(u8, &self.lock.reader_queue_empty_bit, .SeqCst) == 0) {
// Switch to a read lock.
- _ = @atomicRmw(u8, &self.lock.shared_state, .Xchg, State.ReadLock, .SeqCst);
+ _ = @atomicRmw(State, &self.lock.shared_state, .Xchg, .ReadLock, .SeqCst);
while (self.lock.reader_queue.get()) |node| {
global_event_loop.onNextTick(node);
}
@@ -72,7 +72,7 @@ pub const RwLock = struct {
}
_ = @atomicRmw(u8, &self.lock.writer_queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(u8, &self.lock.shared_state, .Xchg, State.Unlocked, .SeqCst);
+ _ = @atomicRmw(State, &self.lock.shared_state, .Xchg, State.Unlocked, .SeqCst);
self.lock.commonPostUnlock();
}
@@ -80,7 +80,7 @@ pub const RwLock = struct {
pub fn init() RwLock {
return RwLock{
- .shared_state = State.Unlocked,
+ .shared_state = .Unlocked,
.writer_queue = Queue.init(),
.writer_queue_empty_bit = 1,
.reader_queue = Queue.init(),
@@ -92,7 +92,7 @@ pub const RwLock = struct {
/// Must be called when not locked. Not thread safe.
/// All calls to acquire() and release() must complete before calling deinit().
pub fn deinit(self: *RwLock) void {
- assert(self.shared_state == State.Unlocked);
+ assert(self.shared_state == .Unlocked);
while (self.writer_queue.get()) |node| resume node.data;
while (self.reader_queue.get()) |node| resume node.data;
}
@@ -116,7 +116,7 @@ pub const RwLock = struct {
_ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 0, .SeqCst);
// Here we don't care if we are the one to do the locking or if it was already locked for reading.
- const have_read_lock = if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.ReadLock, .SeqCst, .SeqCst)) |old_state| old_state == State.ReadLock else true;
+ const have_read_lock = if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .ReadLock, .SeqCst, .SeqCst)) |old_state| old_state == .ReadLock else true;
if (have_read_lock) {
// Give out all the read locks.
if (self.reader_queue.get()) |first_node| {
@@ -147,7 +147,7 @@ pub const RwLock = struct {
_ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 0, .SeqCst);
// Here we must be the one to acquire the write lock. It cannot already be locked.
- if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.WriteLock, .SeqCst, .SeqCst) == null) {
+ if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .WriteLock, .SeqCst, .SeqCst) == null) {
// We now have a write lock.
if (self.writer_queue.get()) |node| {
// Whether this node is us or someone else, we tail resume it.
@@ -166,7 +166,7 @@ pub const RwLock = struct {
// But if there's a writer_queue item or a reader_queue item,
// we are the actor which must loop and attempt to grab the lock again.
if (@atomicLoad(u8, &self.writer_queue_empty_bit, .SeqCst) == 0) {
- if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.WriteLock, .SeqCst, .SeqCst) != null) {
+ if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .WriteLock, .SeqCst, .SeqCst) != null) {
// We did not obtain the lock. Great, the queues are someone else's problem.
return;
}
@@ -177,12 +177,12 @@ pub const RwLock = struct {
}
// Release the lock again.
_ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(u8, &self.shared_state, .Xchg, State.Unlocked, .SeqCst);
+ _ = @atomicRmw(State, &self.shared_state, .Xchg, .Unlocked, .SeqCst);
continue;
}
if (@atomicLoad(u8, &self.reader_queue_empty_bit, .SeqCst) == 0) {
- if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.ReadLock, .SeqCst, .SeqCst) != null) {
+ if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .ReadLock, .SeqCst, .SeqCst) != null) {
// We did not obtain the lock. Great, the queues are someone else's problem.
return;
}
@@ -196,7 +196,7 @@ pub const RwLock = struct {
}
// Release the lock again.
_ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 1, .SeqCst);
- if (@cmpxchgStrong(u8, &self.shared_state, State.ReadLock, State.Unlocked, .SeqCst, .SeqCst) != null) {
+ if (@cmpxchgStrong(State, &self.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
// Didn't unlock. Someone else's problem.
return;
}
diff --git a/lib/std/lazy_init.zig b/lib/std/lazy_init.zig
index add40a372d..dc792b398c 100644
--- a/lib/std/lazy_init.zig
+++ b/lib/std/lazy_init.zig
@@ -1,24 +1,26 @@
const std = @import("std.zig");
-const builtin = @import("builtin");
const assert = std.debug.assert;
const testing = std.testing;
-const AtomicRmwOp = builtin.AtomicRmwOp;
-const AtomicOrder = builtin.AtomicOrder;
/// Thread-safe initialization of global data.
/// TODO use a mutex instead of a spinlock
pub fn lazyInit(comptime T: type) LazyInit(T) {
return LazyInit(T){
.data = undefined,
- .state = 0,
};
}
fn LazyInit(comptime T: type) type {
return struct {
- state: u8, // TODO make this an enum
+ state: State = .NotResolved,
data: Data,
+ const State = enum(u8) {
+ NotResolved,
+ Resolving,
+ Resolved,
+ };
+
const Self = @This();
// TODO this isn't working for void, investigate and then remove this special case
@@ -30,14 +32,14 @@ fn LazyInit(comptime T: type) type {
/// perform the initialization and then call resolve().
pub fn get(self: *Self) ?Ptr {
while (true) {
- var state = @cmpxchgWeak(u8, &self.state, 0, 1, AtomicOrder.SeqCst, AtomicOrder.SeqCst) orelse return null;
+ var state = @cmpxchgWeak(State, &self.state, .NotResolved, .Resolving, .SeqCst, .SeqCst) orelse return null;
switch (state) {
- 0 => continue,
- 1 => {
+ .NotResolved => continue,
+ .Resolving => {
// TODO mutex instead of a spinlock
continue;
},
- 2 => {
+ .Resolved => {
if (@sizeOf(T) == 0) {
return @as(T, undefined);
} else {
@@ -50,8 +52,8 @@ fn LazyInit(comptime T: type) type {
}
pub fn resolve(self: *Self) void {
- const prev = @atomicRmw(u8, &self.state, AtomicRmwOp.Xchg, 2, AtomicOrder.SeqCst);
- assert(prev == 1); // resolve() called twice
+ const prev = @atomicRmw(State, &self.state, .Xchg, .Resolved, .SeqCst);
+ assert(prev != .Resolved); // resolve() called twice
}
};
}
diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig
index 9b44e2edc3..706c699a87 100644
--- a/lib/std/mutex.zig
+++ b/lib/std/mutex.zig
@@ -39,12 +39,14 @@ pub const Mutex = if (builtin.single_threaded)
}
else
struct {
- state: u32, // TODO: make this an enum
+ state: State, // TODO: make this an enum
parker: ThreadParker,
- const Unlocked = 0;
- const Sleeping = 1;
- const Locked = 2;
+ const State = enum(u32) {
+ Unlocked,
+ Sleeping,
+ Locked,
+ };
/// number of iterations to spin yielding the cpu
const SPIN_CPU = 4;
@@ -57,7 +59,7 @@ else
pub fn init() Mutex {
return Mutex{
- .state = Unlocked,
+ .state = .Unlocked,
.parker = ThreadParker.init(),
};
}
@@ -70,10 +72,10 @@ else
mutex: *Mutex,
pub fn release(self: Held) void {
- switch (@atomicRmw(u32, &self.mutex.state, .Xchg, Unlocked, .Release)) {
- Locked => {},
- Sleeping => self.mutex.parker.unpark(&self.mutex.state),
- Unlocked => unreachable, // unlocking an unlocked mutex
+ switch (@atomicRmw(State, &self.mutex.state, .Xchg, .Unlocked, .Release)) {
+ .Locked => {},
+ .Sleeping => self.mutex.parker.unpark(@ptrCast(*const u32, &self.mutex.state)),
+ .Unlocked => unreachable, // unlocking an unlocked mutex
else => unreachable, // should never be anything else
}
}
@@ -83,34 +85,34 @@ else
// Try and speculatively grab the lock.
// If it fails, the state is either Locked or Sleeping
// depending on if theres a thread stuck sleeping below.
- var state = @atomicRmw(u32, &self.state, .Xchg, Locked, .Acquire);
- if (state == Unlocked)
+ var state = @atomicRmw(State, &self.state, .Xchg, .Locked, .Acquire);
+ if (state == .Unlocked)
return Held{ .mutex = self };
while (true) {
// try and acquire the lock using cpu spinning on failure
var spin: usize = 0;
while (spin < SPIN_CPU) : (spin += 1) {
- var value = @atomicLoad(u32, &self.state, .Monotonic);
- while (value == Unlocked)
- value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ var value = @atomicLoad(State, &self.state, .Monotonic);
+ while (value == .Unlocked)
+ value = @cmpxchgWeak(State, &self.state, .Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
SpinLock.yield(SPIN_CPU_COUNT);
}
// try and acquire the lock using thread rescheduling on failure
spin = 0;
while (spin < SPIN_THREAD) : (spin += 1) {
- var value = @atomicLoad(u32, &self.state, .Monotonic);
- while (value == Unlocked)
- value = @cmpxchgWeak(u32, &self.state, Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
+ var value = @atomicLoad(State, &self.state, .Monotonic);
+ while (value == .Unlocked)
+ value = @cmpxchgWeak(State, &self.state, .Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
std.os.sched_yield() catch std.time.sleep(1);
}
// failed to acquire the lock, go to sleep until woken up by `Held.release()`
- if (@atomicRmw(u32, &self.state, .Xchg, Sleeping, .Acquire) == Unlocked)
+ if (@atomicRmw(State, &self.state, .Xchg, .Sleeping, .Acquire) == .Unlocked)
return Held{ .mutex = self };
- state = Sleeping;
- self.parker.park(&self.state, Sleeping);
+ state = .Sleeping;
+ self.parker.park(@ptrCast(*const u32, &self.state), @enumToInt(State.Sleeping));
}
}
};
From 710ccacfa3307fc642f4bac71f894e3d8a18764a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Nov 2019 12:21:20 -0500
Subject: [PATCH 076/129] fix assertion failure in ptrToInt
found by building pluto
---
src/ir.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index 9d15e341da..f193f5d0b9 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25394,6 +25394,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
}
static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {
+ Error err;
IrInstruction *target = instruction->target->child;
if (type_is_invalid(target->value.type))
return ira->codegen->invalid_instruction;
@@ -25407,6 +25408,8 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
}
+ if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
if (!type_has_bits(target->value.type)) {
ir_add_error(ira, target,
buf_sprintf("pointer to size 0 type has no address"));
From 110ef2e52825656fc048cba020f0fc36a1e58d13 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Wed, 13 Nov 2019 00:25:44 +0200
Subject: [PATCH 077/129] add @atomicStore builtin
---
doc/langref.html.in | 25 +++++++-
src/all_types.hpp | 12 ++++
src/codegen.cpp | 14 +++++
src/ir.cpp | 103 +++++++++++++++++++++++++++++++
src/ir_print.cpp | 26 ++++++++
test/stage1/behavior/atomics.zig | 8 +++
6 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index b0003a714b..f5fbb4e3a3 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6612,14 +6612,14 @@ async fn func(y: *i32) void {
This builtin function atomically dereferences a pointer and returns the value.
- {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#},
- or an integer whose bit count meets these requirements:
+ {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}
+ an integer whose bit count meets these requirements:
- At least 8
- At most the same as usize
- Power of 2
-
+
or an enum with a valid integer tag type.
TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
we can remove this restriction
@@ -6660,6 +6660,25 @@ async fn func(y: *i32) void {
- {#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.
{#header_close#}
+ {#header_open|@atomicStore#}
+ {#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void{#endsyntax#}
+
+ This builtin function atomically stores a value.
+
+
+ {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}
+ an integer whose bit count meets these requirements:
+
+
+ - At least 8
+ - At most the same as usize
+ - Power of 2
+
or an enum with a valid integer tag type.
+
+ TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
+ we can remove this restriction
+
+ {#header_close#}
{#header_open|@bitCast#}
{#syntax#}@bitCast(comptime DestType: type, value: var) DestType{#endsyntax#}
diff --git a/src/all_types.hpp b/src/all_types.hpp
index e38e857209..1acd855b96 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1700,6 +1700,7 @@ enum BuiltinFnId {
BuiltinFnIdErrorReturnTrace,
BuiltinFnIdAtomicRmw,
BuiltinFnIdAtomicLoad,
+ BuiltinFnIdAtomicStore,
BuiltinFnIdHasDecl,
BuiltinFnIdUnionInit,
BuiltinFnIdFrameAddress,
@@ -2569,6 +2570,7 @@ enum IrInstructionId {
IrInstructionIdErrorUnion,
IrInstructionIdAtomicRmw,
IrInstructionIdAtomicLoad,
+ IrInstructionIdAtomicStore,
IrInstructionIdSaveErrRetAddr,
IrInstructionIdAddImplicitReturnType,
IrInstructionIdErrSetCast,
@@ -3713,6 +3715,16 @@ struct IrInstructionAtomicLoad {
AtomicOrder resolved_ordering;
};
+struct IrInstructionAtomicStore {
+ IrInstruction base;
+
+ IrInstruction *operand_type;
+ IrInstruction *ptr;
+ IrInstruction *value;
+ IrInstruction *ordering;
+ AtomicOrder resolved_ordering;
+};
+
struct IrInstructionSaveErrRetAddr {
IrInstruction base;
};
diff --git a/src/codegen.cpp b/src/codegen.cpp
index a2fc0c0687..3ed269e621 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -5650,6 +5650,17 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,
return load_inst;
}
+static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable,
+ IrInstructionAtomicStore *instruction)
+{
+ LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
+ LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
+ LLVMValueRef value = ir_llvm_value(g, instruction->value);
+ LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value.type);
+ LLVMSetOrdering(store_inst, ordering);
+ return nullptr;
+}
+
static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {
LLVMValueRef op = ir_llvm_value(g, instruction->op1);
assert(instruction->base.value.type->id == ZigTypeIdFloat);
@@ -6253,6 +6264,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);
+ case IrInstructionIdAtomicStore:
+ return ir_render_atomic_store(g, executable, (IrInstructionAtomicStore *)instruction);
case IrInstructionIdSaveErrRetAddr:
return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
case IrInstructionIdFloatOp:
@@ -8064,6 +8077,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
+ create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);
create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
diff --git a/src/ir.cpp b/src/ir.cpp
index 4727c32d5d..f5f1ea3e80 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -1009,6 +1009,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) {
return IrInstructionIdAtomicLoad;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicStore *) {
+ return IrInstructionIdAtomicStore;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) {
return IrInstructionIdSaveErrRetAddr;
}
@@ -3186,6 +3190,25 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
+static IrInstruction *ir_build_atomic_store(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *value,
+ IrInstruction *ordering, AtomicOrder resolved_ordering)
+{
+ IrInstructionAtomicStore *instruction = ir_build_instruction(irb, scope, source_node);
+ instruction->operand_type = operand_type;
+ instruction->ptr = ptr;
+ instruction->value = value;
+ instruction->ordering = ordering;
+ instruction->resolved_ordering = resolved_ordering;
+
+ if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block);
+ ir_ref_instruction(ptr, irb->current_basic_block);
+ ir_ref_instruction(value, irb->current_basic_block);
+ if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) {
IrInstructionSaveErrRetAddr *instruction = ir_build_instruction(irb, scope, source_node);
return &instruction->base;
@@ -5730,6 +5753,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
AtomicOrderMonotonic);
return ir_lval_wrap(irb, scope, inst, lval, result_loc);
}
+ case BuiltinFnIdAtomicStore:
+ {
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
+ if (arg0_value == irb->codegen->invalid_instruction)
+ return arg0_value;
+
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
+ IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
+ if (arg1_value == irb->codegen->invalid_instruction)
+ return arg1_value;
+
+ AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
+ IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope);
+ if (arg2_value == irb->codegen->invalid_instruction)
+ return arg2_value;
+
+ AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
+ IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope);
+ if (arg3_value == irb->codegen->invalid_instruction)
+ return arg3_value;
+
+ IrInstruction *inst = ir_build_atomic_store(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value,
+ // this value does not mean anything since we passed non-null values for other arg
+ AtomicOrderMonotonic);
+ return ir_lval_wrap(irb, scope, inst, lval, result_loc);
+ }
case BuiltinFnIdIntToEnum:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -25748,6 +25798,56 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
return result;
}
+static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstructionAtomicStore *instruction) {
+ ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);
+ if (type_is_invalid(operand_type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *ptr_inst = instruction->ptr->child;
+ if (type_is_invalid(ptr_inst->value.type))
+ return ira->codegen->invalid_instruction;
+
+ ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true);
+ IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type);
+ if (type_is_invalid(casted_ptr->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *value = instruction->value->child;
+ if (type_is_invalid(value->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *casted_value = ir_implicit_cast(ira, value, operand_type);
+ if (type_is_invalid(casted_value->value.type))
+ return ira->codegen->invalid_instruction;
+
+
+ AtomicOrder ordering;
+ if (instruction->ordering == nullptr) {
+ ordering = instruction->resolved_ordering;
+ } else {
+ if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering))
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) {
+ ir_assert(instruction->ordering != nullptr, &instruction->base);
+ ir_add_error(ira, instruction->ordering,
+ buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel"));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) {
+ IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr);
+ ir_assert(result->value.type != nullptr, &instruction->base);
+ return result;
+ }
+
+ IrInstruction *result = ir_build_atomic_store(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, nullptr, casted_ptr, casted_value, nullptr, ordering);
+ result->value.type = ira->codegen->builtin_types.entry_void;
+ return result;
+}
+
static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) {
IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope,
instruction->base.source_node);
@@ -26782,6 +26882,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction);
+ case IrInstructionIdAtomicStore:
+ return ir_analyze_instruction_atomic_store(ira, (IrInstructionAtomicStore *)instruction);
case IrInstructionIdSaveErrRetAddr:
return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction);
case IrInstructionIdAddImplicitReturnType:
@@ -26962,6 +27064,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdSaveErrRetAddr:
case IrInstructionIdAddImplicitReturnType:
case IrInstructionIdAtomicRmw:
+ case IrInstructionIdAtomicStore:
case IrInstructionIdCmpxchgGen:
case IrInstructionIdCmpxchgSrc:
case IrInstructionIdAssertZero:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index da7ae38e5f..03224d8037 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -324,6 +324,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {
return "AtomicRmw";
case IrInstructionIdAtomicLoad:
return "AtomicLoad";
+ case IrInstructionIdAtomicStore:
+ return "AtomicStore";
case IrInstructionIdSaveErrRetAddr:
return "SaveErrRetAddr";
case IrInstructionIdAddImplicitReturnType:
@@ -1871,6 +1873,27 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct
fprintf(irp->f, ")");
}
+static void ir_print_atomic_store(IrPrint *irp, IrInstructionAtomicStore *instruction) {
+ fprintf(irp->f, "@atomicStore(");
+ if (instruction->operand_type != nullptr) {
+ ir_print_other_instruction(irp, instruction->operand_type);
+ } else {
+ fprintf(irp->f, "[TODO print]");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->ptr);
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->value);
+ fprintf(irp->f, ",");
+ if (instruction->ordering != nullptr) {
+ ir_print_other_instruction(irp, instruction->ordering);
+ } else {
+ fprintf(irp->f, "[TODO print]");
+ }
+ fprintf(irp->f, ")");
+}
+
+
static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) {
fprintf(irp->f, "@saveErrRetAddr()");
}
@@ -2431,6 +2454,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool
case IrInstructionIdAtomicLoad:
ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
break;
+ case IrInstructionIdAtomicStore:
+ ir_print_atomic_store(irp, (IrInstructionAtomicStore *)instruction);
+ break;
case IrInstructionIdEnumToInt:
ir_print_enum_to_int(irp, (IrInstructionEnumToInt *)instruction);
break;
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index c6344b17ca..9e41863fd1 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -123,3 +123,11 @@ test "atomic load and rmw with enum" {
expect(@atomicLoad(Value, &x, .SeqCst) != .a);
expect(@atomicLoad(Value, &x, .SeqCst) != .b);
}
+
+test "atomic store" {
+ var x: u32 = 0;
+ @atomicStore(u32, &x, 1, .SeqCst);
+ expect(@atomicLoad(u32, &x, .SeqCst) == 1);
+ @atomicStore(u32, &x, 12345678, .SeqCst);
+ expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
+}
\ No newline at end of file
From f0c94d95dde320ba5e7509dc1499b33e54a1c951 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Wed, 13 Nov 2019 00:45:37 +0200
Subject: [PATCH 078/129] use @atomicStore in std lib
---
lib/std/atomic/queue.zig | 2 +-
lib/std/atomic/stack.zig | 2 +-
lib/std/event/channel.zig | 4 ++--
lib/std/event/future.zig | 4 ++--
lib/std/event/lock.zig | 10 +++++-----
lib/std/event/loop.zig | 4 ++--
lib/std/event/rwlock.zig | 18 +++++++++---------
lib/std/os/linux.zig | 2 +-
lib/std/spinlock.zig | 3 +--
test/stage1/behavior/atomics.zig | 2 +-
10 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/lib/std/atomic/queue.zig b/lib/std/atomic/queue.zig
index 173355eb3b..9d6b15ff4a 100644
--- a/lib/std/atomic/queue.zig
+++ b/lib/std/atomic/queue.zig
@@ -199,7 +199,7 @@ test "std.atomic.Queue" {
for (putters) |t|
t.wait();
- _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
+ @atomicStore(u8, &context.puts_done, 1, AtomicOrder.SeqCst);
for (getters) |t|
t.wait();
diff --git a/lib/std/atomic/stack.zig b/lib/std/atomic/stack.zig
index 664191eb77..4246e15985 100644
--- a/lib/std/atomic/stack.zig
+++ b/lib/std/atomic/stack.zig
@@ -128,7 +128,7 @@ test "std.atomic.stack" {
for (putters) |t|
t.wait();
- _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
+ @atomicStore(u8, &context.puts_done, 1, AtomicOrder.SeqCst);
for (getters) |t|
t.wait();
}
diff --git a/lib/std/event/channel.zig b/lib/std/event/channel.zig
index 2ea99d234d..ac5a65e1b0 100644
--- a/lib/std/event/channel.zig
+++ b/lib/std/event/channel.zig
@@ -161,7 +161,7 @@ pub fn Channel(comptime T: type) type {
fn dispatch(self: *SelfChannel) void {
// set the "need dispatch" flag
- _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 1, .SeqCst);
+ @atomicStore(u8, &self.need_dispatch, 1, .SeqCst);
lock: while (true) {
// set the lock flag
@@ -169,7 +169,7 @@ pub fn Channel(comptime T: type) type {
if (prev_lock != 0) return;
// clear the need_dispatch flag since we're about to do it
- _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.need_dispatch, 0, .SeqCst);
while (true) {
one_dispatch: {
diff --git a/lib/std/event/future.zig b/lib/std/event/future.zig
index 43593b348a..5261db990c 100644
--- a/lib/std/event/future.zig
+++ b/lib/std/event/future.zig
@@ -62,12 +62,12 @@ pub fn Future(comptime T: type) type {
pub async fn start(self: *Self) ?*T {
const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
switch (state) {
- 1 => {
+ .Started => {
const held = self.lock.acquire();
held.release();
return &self.data;
},
- 2 => return &self.data,
+ .Finished => return &self.data,
else => unreachable,
}
}
diff --git a/lib/std/event/lock.zig b/lib/std/event/lock.zig
index 576a09064f..a95c5bf7e2 100644
--- a/lib/std/event/lock.zig
+++ b/lib/std/event/lock.zig
@@ -31,8 +31,8 @@ pub const Lock = struct {
}
// We need to release the lock.
- _ = @atomicRmw(u8, &self.lock.queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(u8, &self.lock.shared_bit, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.lock.queue_empty_bit, 1, .SeqCst);
+ @atomicStore(u8, &self.lock.shared_bit, 0, .SeqCst);
// There might be a queue item. If we know the queue is empty, we can be done,
// because the other actor will try to obtain the lock.
@@ -56,8 +56,8 @@ pub const Lock = struct {
}
// Release the lock again.
- _ = @atomicRmw(u8, &self.lock.queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(u8, &self.lock.shared_bit, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.lock.queue_empty_bit, 1, .SeqCst);
+ @atomicStore(u8, &self.lock.shared_bit, 0, .SeqCst);
// Find out if we can be done.
if (@atomicLoad(u8, &self.lock.queue_empty_bit, .SeqCst) == 1) {
@@ -101,7 +101,7 @@ pub const Lock = struct {
// We set this bit so that later we can rely on the fact, that if queue_empty_bit is 1, some actor
// will attempt to grab the lock.
- _ = @atomicRmw(u8, &self.queue_empty_bit, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.queue_empty_bit, 0, .SeqCst);
const old_bit = @atomicRmw(u8, &self.shared_bit, .Xchg, 1, .SeqCst);
if (old_bit == 0) {
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 543863c71e..a6284411eb 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -820,7 +820,7 @@ pub const Loop = struct {
_ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
},
.linux => {
- _ = @atomicRmw(i32, &self.os_data.fs_queue_item, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
+ @atomicStore(i32, &self.os_data.fs_queue_item, 1, AtomicOrder.SeqCst);
const rc = os.linux.futex_wake(&self.os_data.fs_queue_item, os.linux.FUTEX_WAKE, 1);
switch (os.linux.getErrno(rc)) {
0 => {},
@@ -843,7 +843,7 @@ pub const Loop = struct {
fn posixFsRun(self: *Loop) void {
while (true) {
if (builtin.os == .linux) {
- _ = @atomicRmw(i32, &self.os_data.fs_queue_item, .Xchg, 0, .SeqCst);
+ @atomicStore(i32, &self.os_data.fs_queue_item, 0, .SeqCst);
}
while (self.os_data.fs_queue.get()) |node| {
switch (node.data.msg) {
diff --git a/lib/std/event/rwlock.zig b/lib/std/event/rwlock.zig
index 3a64b9df8c..ec4ab8f6d0 100644
--- a/lib/std/event/rwlock.zig
+++ b/lib/std/event/rwlock.zig
@@ -40,7 +40,7 @@ pub const RwLock = struct {
return;
}
- _ = @atomicRmw(u8, &self.lock.reader_queue_empty_bit, .Xchg, 1, .SeqCst);
+ @atomicStore(u8, &self.lock.reader_queue_empty_bit, 1, .SeqCst);
if (@cmpxchgStrong(State, &self.lock.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
// Didn't unlock. Someone else's problem.
return;
@@ -64,15 +64,15 @@ pub const RwLock = struct {
// We need to release the write lock. Check if any readers are waiting to grab the lock.
if (@atomicLoad(u8, &self.lock.reader_queue_empty_bit, .SeqCst) == 0) {
// Switch to a read lock.
- _ = @atomicRmw(State, &self.lock.shared_state, .Xchg, .ReadLock, .SeqCst);
+ @atomicStore(State, &self.lock.shared_state, .ReadLock, .SeqCst);
while (self.lock.reader_queue.get()) |node| {
global_event_loop.onNextTick(node);
}
return;
}
- _ = @atomicRmw(u8, &self.lock.writer_queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(State, &self.lock.shared_state, .Xchg, State.Unlocked, .SeqCst);
+ @atomicStore(u8, &self.lock.writer_queue_empty_bit, 1, .SeqCst);
+ @atomicStore(State, &self.lock.shared_state, .Unlocked, .SeqCst);
self.lock.commonPostUnlock();
}
@@ -113,7 +113,7 @@ pub const RwLock = struct {
// We set this bit so that later we can rely on the fact, that if reader_queue_empty_bit is 1,
// some actor will attempt to grab the lock.
- _ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.reader_queue_empty_bit, 0, .SeqCst);
// Here we don't care if we are the one to do the locking or if it was already locked for reading.
const have_read_lock = if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .ReadLock, .SeqCst, .SeqCst)) |old_state| old_state == .ReadLock else true;
@@ -144,7 +144,7 @@ pub const RwLock = struct {
// We set this bit so that later we can rely on the fact, that if writer_queue_empty_bit is 1,
// some actor will attempt to grab the lock.
- _ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 0, .SeqCst);
+ @atomicStore(u8, &self.writer_queue_empty_bit, 0, .SeqCst);
// Here we must be the one to acquire the write lock. It cannot already be locked.
if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .WriteLock, .SeqCst, .SeqCst) == null) {
@@ -176,8 +176,8 @@ pub const RwLock = struct {
return;
}
// Release the lock again.
- _ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 1, .SeqCst);
- _ = @atomicRmw(State, &self.shared_state, .Xchg, .Unlocked, .SeqCst);
+ @atomicStore(u8, &self.writer_queue_empty_bit, 1, .SeqCst);
+ @atomicStore(State, &self.shared_state, .Unlocked, .SeqCst);
continue;
}
@@ -195,7 +195,7 @@ pub const RwLock = struct {
return;
}
// Release the lock again.
- _ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 1, .SeqCst);
+ @atomicStore(u8, &self.reader_queue_empty_bit, 1, .SeqCst);
if (@cmpxchgStrong(State, &self.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
// Didn't unlock. Someone else's problem.
return;
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 618a21f456..7e2f14021f 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -531,7 +531,7 @@ extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
// Note that we may not have a VDSO at all, update the stub address anyway
// so that clock_gettime will fall back on the good old (and slow) syscall
- _ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);
+ @atomicStore(?*const c_void, &vdso_clock_gettime, ptr, .Monotonic);
// Call into the VDSO if available
if (ptr) |fn_ptr| {
const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig
index 3bed3d3891..bd811f709c 100644
--- a/lib/std/spinlock.zig
+++ b/lib/std/spinlock.zig
@@ -11,8 +11,7 @@ pub const SpinLock = struct {
spinlock: *SpinLock,
pub fn release(self: Held) void {
- // TODO: @atomicStore() https://github.com/ziglang/zig/issues/2995
- assert(@atomicRmw(u8, &self.spinlock.lock, .Xchg, 0, .Release) == 1);
+ @atomicStore(u8, &self.spinlock.lock, 0, .Release);
}
};
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index 9e41863fd1..894f99b7e0 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -130,4 +130,4 @@ test "atomic store" {
expect(@atomicLoad(u32, &x, .SeqCst) == 1);
@atomicStore(u32, &x, 12345678, .SeqCst);
expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
-}
\ No newline at end of file
+}
From 41914321b4593e3ed246cadda705e1076ab670d7 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Wed, 13 Nov 2019 01:32:16 +0200
Subject: [PATCH 079/129] fix comptime atomicStore and add tests
---
src/ir.cpp | 6 +++---
test/compile_errors.zig | 10 ++++++++++
test/stage1/behavior/atomics.zig | 13 +++++++++++++
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index f5f1ea3e80..e794e8db03 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25807,7 +25807,7 @@ static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInst
if (type_is_invalid(ptr_inst->value.type))
return ira->codegen->invalid_instruction;
- ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true);
+ ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false);
IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type);
if (type_is_invalid(casted_ptr->value.type))
return ira->codegen->invalid_instruction;
@@ -25837,8 +25837,8 @@ static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInst
}
if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) {
- IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr);
- ir_assert(result->value.type != nullptr, &instruction->base);
+ IrInstruction *result = ir_analyze_store_ptr(ira, &instruction->base, casted_ptr, value, false);
+ result->value.type = ira->codegen->builtin_types.entry_void;
return result;
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 1adf3c3f8e..c42c95465a 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,16 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "atomic orderings of atomicStore Acquire or AcqRel",
+ \\export fn entry() void {
+ \\ var x: u32 = 0;
+ \\ @atomicStore(u32, &x, 1, .Acquire);
+ \\}
+ ,
+ "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel",
+ );
+
cases.add(
"missing const in slice with nested array type",
\\const Geo3DTex2D = struct { vertices: [][2]f32 };
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index 894f99b7e0..694eb160e4 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -131,3 +131,16 @@ test "atomic store" {
@atomicStore(u32, &x, 12345678, .SeqCst);
expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
}
+
+test "atomic store comptime" {
+ comptime testAtomicStore();
+ testAtomicStore();
+}
+
+fn testAtomicStore() void {
+ var x: u32 = 0;
+ @atomicStore(u32, &x, 1, .SeqCst);
+ expect(@atomicLoad(u32, &x, .SeqCst) == 1);
+ @atomicStore(u32, &x, 12345678, .SeqCst);
+ expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
+}
\ No newline at end of file
From 37318bf15138d0a7b158b32ca43cbcdcf5382942 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Nov 2019 17:59:24 -0500
Subject: [PATCH 080/129] fn parameters participate in result location
semantics
See #3665
---
doc/langref.html.in | 2 +-
lib/std/event/loop.zig | 23 ------
src/all_types.hpp | 1 +
src/codegen.cpp | 5 ++
src/ir.cpp | 155 +++++++++++++++++++++++++++++-------
test/compile_errors.zig | 8 +-
test/stage1/behavior/fn.zig | 16 ++++
7 files changed, 154 insertions(+), 56 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index b0003a714b..bca12c62d7 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -5404,7 +5404,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
For example, if we were to introduce another function to the above snippet:
- {#code_begin|test_err|cannot store runtime value in type 'type'#}
+ {#code_begin|test_err|values of type 'type' must be comptime known#}
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 543863c71e..588cd3c8b5 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -645,12 +645,6 @@ pub const Loop = struct {
}
}
- /// This is equivalent to function call, except it calls `startCpuBoundOperation` first.
- pub fn call(comptime func: var, args: ...) @typeOf(func).ReturnType {
- startCpuBoundOperation();
- return func(args);
- }
-
/// Yielding lets the event loop run, starting any unstarted async operations.
/// Note that async operations automatically start when a function yields for any other reason,
/// for example, when async I/O is performed. This function is intended to be used only when
@@ -942,23 +936,6 @@ test "std.event.Loop - basic" {
loop.run();
}
-test "std.event.Loop - call" {
- // https://github.com/ziglang/zig/issues/1908
- if (builtin.single_threaded) return error.SkipZigTest;
-
- var loop: Loop = undefined;
- try loop.initMultiThreaded();
- defer loop.deinit();
-
- var did_it = false;
- var handle = async Loop.call(testEventLoop);
- var handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
-
- loop.run();
-
- testing.expect(did_it);
-}
-
async fn testEventLoop() i32 {
return 1234;
}
diff --git a/src/all_types.hpp b/src/all_types.hpp
index e38e857209..1464dfba59 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -3665,6 +3665,7 @@ struct IrInstructionArgType {
IrInstruction *fn_type;
IrInstruction *arg_index;
+ bool allow_var;
};
struct IrInstructionExport {
diff --git a/src/codegen.cpp b/src/codegen.cpp
index a2fc0c0687..558a7011f0 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -7820,6 +7820,11 @@ static void define_builtin_types(CodeGen *g) {
buf_init_from_str(&entry->name, "(null)");
g->builtin_types.entry_null = entry;
}
+ {
+ ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
+ buf_init_from_str(&entry->name, "(var)");
+ g->builtin_types.entry_var = entry;
+ }
{
ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
buf_init_from_str(&entry->name, "(args)");
diff --git a/src/ir.cpp b/src/ir.cpp
index 4727c32d5d..3b7ef42f04 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -206,6 +206,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
+static ResultLoc *no_result_loc(void);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -3115,11 +3116,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast
}
static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *fn_type, IrInstruction *arg_index)
+ IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var)
{
IrInstructionArgType *instruction = ir_build_instruction(irb, scope, source_node);
instruction->fn_type = fn_type;
instruction->arg_index = arg_index;
+ instruction->allow_var = allow_var;
ir_ref_instruction(fn_type, irb->current_basic_block);
ir_ref_instruction(arg_index, irb->current_basic_block);
@@ -5647,7 +5649,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
- IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
+ IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false);
return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
}
case BuiltinFnIdExport:
@@ -5842,13 +5844,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
if (fn_ref == irb->codegen->invalid_instruction)
return fn_ref;
+ IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref);
+
size_t arg_count = node->data.fn_call_expr.params.length;
IrInstruction **args = allocate(arg_count);
for (size_t i = 0; i < arg_count; i += 1) {
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
- args[i] = ir_gen_node(irb, arg_node, scope);
- if (args[i] == irb->codegen->invalid_instruction)
- return args[i];
+
+ IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i);
+ IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true);
+ ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc());
+
+ IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base);
+ if (arg == irb->codegen->invalid_instruction)
+ return arg;
+
+ args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast);
}
IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
@@ -12504,6 +12515,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou
return result;
}
+static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *value, ZigType *wanted_type)
+{
+ ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array"));
+ return ira->codegen->invalid_instruction;
+}
+
+static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *value, ZigType *wanted_type)
+{
+ ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct"));
+ return ira->codegen->invalid_instruction;
+}
+
+static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *value, ZigType *wanted_type)
+{
+ ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union"));
+ return ira->codegen->invalid_instruction;
+}
+
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
{
@@ -12515,6 +12547,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ira->codegen->invalid_instruction;
}
+ // This means the wanted type is anything.
+ if (wanted_type == ira->codegen->builtin_types.entry_var) {
+ return value;
+ }
+
// perfect match or non-const to const
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
source_node, false);
@@ -13071,6 +13108,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
}
+ // cast from inferred struct type to array, union, or struct
+ if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) {
+ AstNode *decl_node = actual_type->data.structure.decl_node;
+ ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr);
+ ContainerInitKind init_kind = decl_node->data.container_init_expr.kind;
+ uint32_t field_count = actual_type->data.structure.src_field_count;
+ if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) &&
+ wanted_type->data.array.len == field_count)
+ {
+ return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type);
+ } else if (wanted_type->id == ZigTypeIdStruct &&
+ (init_kind == ContainerInitKindStruct || field_count == 0))
+ {
+ return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type);
+ } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) {
+ return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type);
+ }
+ }
+
// cast from undefined to anything
if (actual_type->id == ZigTypeIdUndefined) {
return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
@@ -15537,21 +15593,31 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
ptr->value.data.x_ptr.data.ref.pointee = undef_child;
}
-static bool ir_result_has_type(ResultLoc *result_loc) {
+static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) {
switch (result_loc->id) {
case ResultLocIdInvalid:
case ResultLocIdPeerParent:
zig_unreachable();
case ResultLocIdNone:
case ResultLocIdPeer:
- return false;
+ *out = false;
+ return ErrorNone;
case ResultLocIdReturn:
case ResultLocIdInstruction:
case ResultLocIdBitCast:
- case ResultLocIdCast:
- return true;
+ *out = true;
+ return ErrorNone;
+ case ResultLocIdCast: {
+ ResultLocCast *result_cast = reinterpret_cast(result_loc);
+ ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
+ if (type_is_invalid(dest_type))
+ return ErrorSemanticAnalyzeFail;
+ *out = (dest_type != ira->codegen->builtin_types.entry_var);
+ return ErrorNone;
+ }
case ResultLocIdVar:
- return reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
+ *out = reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
+ return ErrorNone;
}
zig_unreachable();
}
@@ -15698,7 +15764,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
}
return nullptr;
}
- if (ir_result_has_type(peer_parent->parent)) {
+ bool peer_parent_has_type;
+ if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
+ return ira->codegen->invalid_instruction;
+ if (peer_parent_has_type) {
if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {
reinterpret_cast(peer_parent->parent)->implicit_return_type_done = true;
ira->src_implicit_return_type_list.append(value);
@@ -15741,6 +15810,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
if (type_is_invalid(dest_type))
return ira->codegen->invalid_instruction;
+ if (dest_type == ira->codegen->builtin_types.entry_var) {
+ return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
+ force_runtime, non_null_comptime);
+ }
+
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type,
result_cast->base.source_instruction->source_node, false);
if (const_cast_result.id == ConstCastResultIdInvalid)
@@ -15948,6 +16022,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
if (type_is_invalid(implicit_elem_type))
return ira->codegen->invalid_instruction;
} else {
+ implicit_elem_type = ira->codegen->builtin_types.entry_var;
+ }
+ if (implicit_elem_type == ira->codegen->builtin_types.entry_var) {
Buf *bare_name = buf_alloc();
Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
instruction->base.scope, instruction->base.source_node, bare_name);
@@ -17532,6 +17609,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira,
}
static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
+ Error err;
+
if (ira->const_predecessor_bb) {
for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
@@ -17663,24 +17742,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
}
ZigType *resolved_type;
- if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) {
- if (peer_parent->parent->id == ResultLocIdReturn) {
- resolved_type = ira->explicit_return_type;
- } else if (peer_parent->parent->id == ResultLocIdCast) {
- resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
- if (type_is_invalid(resolved_type))
- return ira->codegen->invalid_instruction;
- } else {
- ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
- ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
- resolved_type = resolved_loc_ptr_type->data.pointer.child_type;
+ if (peer_parent != nullptr) {
+ bool peer_parent_has_type;
+ if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
+ return ira->codegen->invalid_instruction;
+ if (peer_parent_has_type) {
+ if (peer_parent->parent->id == ResultLocIdReturn) {
+ resolved_type = ira->explicit_return_type;
+ } else if (peer_parent->parent->id == ResultLocIdCast) {
+ resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
+ if (type_is_invalid(resolved_type))
+ return ira->codegen->invalid_instruction;
+ } else {
+ ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
+ ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
+ resolved_type = resolved_loc_ptr_type->data.pointer.child_type;
+ }
+ goto skip_resolve_peer_types;
}
- } else {
+ }
+ {
resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,
new_incoming_values.items, new_incoming_values.length);
if (type_is_invalid(resolved_type))
return ira->codegen->invalid_instruction;
}
+skip_resolve_peer_types:
switch (type_has_one_possible_value(ira->codegen, resolved_type)) {
case OnePossibleValueInvalid:
@@ -18379,7 +18466,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n
inferred_struct_field->inferred_struct_type = container_type;
inferred_struct_field->field_name = field_name;
- ZigType *elem_type = ira->codegen->builtin_types.entry_c_void;
+ ZigType *elem_type = ira->codegen->builtin_types.entry_var;
ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile,
PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field);
@@ -25547,6 +25634,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
if (!ir_resolve_usize(ira, arg_index_inst, &arg_index))
return ira->codegen->invalid_instruction;
+ if (fn_type->id == ZigTypeIdBoundFn) {
+ fn_type = fn_type->data.bound_fn.fn_type;
+ arg_index += 1;
+ }
if (fn_type->id != ZigTypeIdFn) {
ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name)));
return ira->codegen->invalid_instruction;
@@ -25554,6 +25645,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
if (arg_index >= fn_type_id->param_count) {
+ if (instruction->allow_var) {
+ // TODO remove this with var args
+ return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var);
+ }
ir_add_error(ira, arg_index_inst,
buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",
arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count));
@@ -25565,10 +25660,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
// Args are only unresolved if our function is generic.
ir_assert(fn_type->data.fn.is_generic, &instruction->base);
- ir_add_error(ira, arg_index_inst,
- buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
- arg_index, buf_ptr(&fn_type->name)));
- return ira->codegen->invalid_instruction;
+ if (instruction->allow_var) {
+ return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var);
+ } else {
+ ir_add_error(ira, arg_index_inst,
+ buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
+ arg_index, buf_ptr(&fn_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
}
return ir_const_type(ira, &instruction->base, result_type);
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 1adf3c3f8e..47333b7db4 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2113,8 +2113,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\
\\fn bar(x: *b.Foo) void {}
,
- "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",
- "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
+ "tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'",
+ "tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
"a.zig:1:17: note: a.Foo declared here",
"b.zig:1:17: note: b.Foo declared here",
);
@@ -4978,7 +4978,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
,
- "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",
+ "tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'",
);
cases.add(
@@ -5675,7 +5675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ x.* += 1;
\\}
,
- "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",
+ "tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'",
);
cases.add(
diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig
index 1fc586f39f..99d145f1b1 100644
--- a/test/stage1/behavior/fn.zig
+++ b/test/stage1/behavior/fn.zig
@@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" {
S.entry();
comptime S.entry();
}
+
+test "function call with anon list literal" {
+ const S = struct {
+ fn doTheTest() void {
+ consumeVec(.{9, 8, 7});
+ }
+
+ fn consumeVec(vec: [3]f32) void {
+ expect(vec[0] == 9);
+ expect(vec[1] == 8);
+ expect(vec[2] == 7);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From 32b37e695aa0581b863a395e0a28b7b4aa76c07d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Nov 2019 21:34:06 -0500
Subject: [PATCH 081/129] fix anonymous struct literal assigned to variable
closes #3667
---
src/analyze.cpp | 23 ++++++++++++++++++++++-
src/analyze.hpp | 2 ++
src/codegen.cpp | 7 ++++++-
src/ir.cpp | 17 +++++++++--------
test/stage1/behavior/struct.zig | 11 ++++++++++-
5 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 4c63c566e9..1232cebe8b 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
return false;
}
-// Whether the type has bits at runtime.
+// Deprecated. Use type_has_bits2.
bool type_has_bits(ZigType *type_entry) {
assert(type_entry != nullptr);
assert(!type_is_invalid(type_entry));
@@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
return type_entry->abi_size != 0;
}
+// Whether the type has bits at runtime.
+Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) {
+ Error err;
+
+ if (type_is_invalid(type_entry))
+ return ErrorSemanticAnalyzeFail;
+
+ if (type_entry->id == ZigTypeIdStruct &&
+ type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
+ {
+ *result = true;
+ return ErrorNone;
+ }
+
+ if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
+ return err;
+
+ *result = type_entry->abi_size != 0;
+ return ErrorNone;
+}
+
// Whether you can infer the value based solely on the type.
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
assert(type_entry != nullptr);
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 06c8847eda..884f525717 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
bool handle_is_ptr(ZigType *type_entry);
bool type_has_bits(ZigType *type_entry);
+Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
+
Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
bool ptr_allows_addr_zero(ZigType *ptr_type);
bool type_is_nonnull_ptr(ZigType *type);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 558a7011f0..387c6120c2 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
}
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
+ Error err;
+
ZigType *ptr_type = instruction->ptr->value.type;
assert(ptr_type->id == ZigTypeIdPointer);
- if (!type_has_bits(ptr_type))
+ bool ptr_type_has_bits;
+ if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
+ codegen_report_errors_and_exit(g);
+ if (!ptr_type_has_bits)
return nullptr;
if (instruction->ptr->ref_count == 0) {
// In this case, this StorePtr instruction should be elided. Something happened like this:
diff --git a/src/ir.cpp b/src/ir.cpp
index 3b7ef42f04..676f69dea7 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
result->base.value.data.x_ptr.data.ref.pointee = pointee;
- if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
+ bool var_type_has_bits;
+ if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits)))
return ira->codegen->invalid_instruction;
if (align != 0) {
if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
return ira->codegen->invalid_instruction;
- if (!type_has_bits(var_type)) {
- ir_add_error(ira, source_inst,
- buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
- name_hint, buf_ptr(&var_type->name)));
+ if (!var_type_has_bits) {
+ ir_add_error(ira, source_inst,
+ buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
+ name_hint, buf_ptr(&var_type->name)));
return ira->codegen->invalid_instruction;
}
}
@@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
}
for (size_t i = 0; i < errors_len; i += 1) {
Stage2ErrorMsg *clang_err = &errors_ptr[i];
- // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
- if (clang_err->source && clang_err->filename_ptr) {
+ // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
+ if (clang_err->source && clang_err->filename_ptr) {
ErrorMsg *err_msg = err_msg_create_with_offset(
clang_err->filename_ptr ?
buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
err_msg_add_note(parent_err_msg, err_msg);
- }
+ }
}
return ira->codegen->invalid_instruction;
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index a42c261e3b..722f44d352 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -755,7 +755,7 @@ test "fully anonymous struct" {
test "fully anonymous list literal" {
const S = struct {
fn doTheTest() void {
- dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
+ dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
}
fn dump(args: var) void {
expect(args.@"0" == 1234);
@@ -768,3 +768,12 @@ test "fully anonymous list literal" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "anonymous struct literal assigned to variable" {
+ var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
+ expect(vec.@"0" == 22);
+ expect(vec.@"1" == 55);
+ expect(vec.@"2" == 99);
+ vec.@"1" += 1;
+ expect(vec.@"1" == 56);
+}
From 0237e7a701892a0bf3c57e6868f54421782ff91d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Nov 2019 20:36:07 -0500
Subject: [PATCH 082/129] std.io.getStdOut and related fns no longer can error
Thanks to the Windows Process Environment Block, it is possible to
obtain handles to the standard input, output, and error streams without
possibility of failure.
---
doc/langref.html.in | 7 ++---
lib/std/crypto/benchmark.zig | 4 +--
lib/std/debug.zig | 14 +++++-----
lib/std/io.zig | 25 ++++++-----------
lib/std/json.zig | 4 +--
lib/std/progress.zig | 7 ++---
lib/std/special/build_runner.zig | 35 ++++++++----------------
lib/std/unicode/throughput_test.zig | 4 +--
lib/std/zig/parser_test.zig | 11 ++++----
src-self-hosted/main.zig | 11 +++-----
src-self-hosted/stage1.zig | 12 +++-----
src-self-hosted/test.zig | 4 +--
test/compare_output.zig | 30 ++++++++++----------
test/standalone/brace_expansion/main.zig | 4 +--
test/standalone/cat/main.zig | 14 ++++------
test/standalone/guess_number/main.zig | 3 +-
test/standalone/hello_world/hello.zig | 2 +-
17 files changed, 76 insertions(+), 115 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 5d989c1bbd..dc44dd287f 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -202,11 +202,8 @@
const std = @import("std");
pub fn main() !void {
- // If this program is run without stdout attached, exit with an error.
- const stdout_file = try std.io.getStdOut();
- // If this program encounters pipe failure when printing to stdout, exit
- // with an error.
- try stdout_file.write("Hello, world!\n");
+ const stdout = &std.io.getStdOut().outStream().stream;
+ try stdout.print("Hello, {}!\n", "world");
}
{#code_end#}
diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig
index 7b0747da7b..05edae0b9b 100644
--- a/lib/std/crypto/benchmark.zig
+++ b/lib/std/crypto/benchmark.zig
@@ -131,9 +131,7 @@ fn printPad(stdout: var, s: []const u8) !void {
}
pub fn main() !void {
- var stdout_file = try std.io.getStdOut();
- var stdout_out_stream = stdout_file.outStream();
- const stdout = &stdout_out_stream.stream;
+ const stdout = &std.io.getStdOut().outStream().stream;
var buffer: [1024]u8 = undefined;
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 02305086cc..3cf4306ea5 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -49,15 +49,15 @@ var stderr_mutex = std.Mutex.init();
pub fn warn(comptime fmt: []const u8, args: ...) void {
const held = stderr_mutex.acquire();
defer held.release();
- const stderr = getStderrStream() catch return;
+ const stderr = getStderrStream();
stderr.print(fmt, args) catch return;
}
-pub fn getStderrStream() !*io.OutStream(File.WriteError) {
+pub fn getStderrStream() *io.OutStream(File.WriteError) {
if (stderr_stream) |st| {
return st;
} else {
- stderr_file = try io.getStdErr();
+ stderr_file = io.getStdErr();
stderr_file_out_stream = stderr_file.outStream();
const st = &stderr_file_out_stream.stream;
stderr_stream = st;
@@ -90,7 +90,7 @@ fn wantTtyColor() bool {
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
- const stderr = getStderrStream() catch return;
+ const stderr = getStderrStream();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
return;
@@ -109,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
/// unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
- const stderr = getStderrStream() catch return;
+ const stderr = getStderrStream();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
return;
@@ -182,7 +182,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
- const stderr = getStderrStream() catch return;
+ const stderr = getStderrStream();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
return;
@@ -237,7 +237,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
// which first called panic can finish printing a stack trace.
os.abort();
}
- const stderr = getStderrStream() catch os.abort();
+ const stderr = getStderrStream();
stderr.print(format ++ "\n", args) catch os.abort();
if (trace) |t| {
dumpStackTrace(t.*);
diff --git a/lib/std/io.zig b/lib/std/io.zig
index f2cbeff922..a5a8b6efbc 100644
--- a/lib/std/io.zig
+++ b/lib/std/io.zig
@@ -34,28 +34,23 @@ else
Mode.blocking;
pub const is_async = mode != .blocking;
-pub const GetStdIoError = os.windows.GetStdHandleError;
-
-pub fn getStdOut() GetStdIoError!File {
+pub fn getStdOut() File {
if (builtin.os == .windows) {
- const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);
- return File.openHandle(handle);
+ return File.openHandle(os.windows.peb().ProcessParameters.hStdOutput);
}
return File.openHandle(os.STDOUT_FILENO);
}
-pub fn getStdErr() GetStdIoError!File {
+pub fn getStdErr() File {
if (builtin.os == .windows) {
- const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);
- return File.openHandle(handle);
+ return File.openHandle(os.windows.peb().ProcessParameters.hStdError);
}
return File.openHandle(os.STDERR_FILENO);
}
-pub fn getStdIn() GetStdIoError!File {
+pub fn getStdIn() File {
if (builtin.os == .windows) {
- const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);
- return File.openHandle(handle);
+ return File.openHandle(os.windows.peb().ProcessParameters.hStdInput);
}
return File.openHandle(os.STDIN_FILENO);
}
@@ -598,7 +593,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr
self.index = 0;
}
- fn writeFn(out_stream: *Stream, bytes: []const u8) !void {
+ fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
const self = @fieldParentPtr(Self, "stream", out_stream);
if (bytes.len >= self.buffer.len) {
@@ -814,8 +809,7 @@ pub const BufferedAtomicFile = struct {
};
pub fn readLine(buf: *std.Buffer) ![]u8 {
- var stdin = try getStdIn();
- var stdin_stream = stdin.inStream();
+ var stdin_stream = getStdIn().inStream();
return readLineFrom(&stdin_stream.stream, buf);
}
@@ -856,8 +850,7 @@ test "io.readLineFrom" {
}
pub fn readLineSlice(slice: []u8) ![]u8 {
- var stdin = try getStdIn();
- var stdin_stream = stdin.inStream();
+ var stdin_stream = getStdIn().inStream();
return readLineSliceFrom(&stdin_stream.stream, slice);
}
diff --git a/lib/std/json.zig b/lib/std/json.zig
index ecf0bf822b..6946ba0170 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -1015,7 +1015,7 @@ pub const Value = union(enum) {
var held = std.debug.getStderrMutex().acquire();
defer held.release();
- const stderr = std.debug.getStderrStream() catch return;
+ const stderr = std.debug.getStderrStream();
self.dumpStream(stderr, 1024) catch return;
}
@@ -1026,7 +1026,7 @@ pub const Value = union(enum) {
var held = std.debug.getStderrMutex().acquire();
defer held.release();
- const stderr = std.debug.getStderrStream() catch return;
+ const stderr = std.debug.getStderrStream();
self.dumpStreamIndent(indent, stderr, 1024) catch return;
}
}
diff --git a/lib/std/progress.zig b/lib/std/progress.zig
index fba77092b3..034d7ade26 100644
--- a/lib/std/progress.zig
+++ b/lib/std/progress.zig
@@ -98,11 +98,8 @@ pub const Progress = struct {
/// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
/// API to return Progress rather than accept it as a parameter.
pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node {
- if (std.io.getStdErr()) |stderr| {
- self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null;
- } else |_| {
- self.terminal = null;
- }
+ const stderr = std.io.getStdErr();
+ self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null;
self.root = Node{
.context = self,
.parent = null,
diff --git a/lib/std/special/build_runner.zig b/lib/std/special/build_runner.zig
index efe3275fe6..fdf5193c03 100644
--- a/lib/std/special/build_runner.zig
+++ b/lib/std/special/build_runner.zig
@@ -43,19 +43,8 @@ pub fn main() !void {
var targets = ArrayList([]const u8).init(allocator);
- var stderr_file = io.getStdErr();
- var stderr_file_stream: File.OutStream = undefined;
- var stderr_stream = if (stderr_file) |f| x: {
- stderr_file_stream = f.outStream();
- break :x &stderr_file_stream.stream;
- } else |err| err;
-
- var stdout_file = io.getStdOut();
- var stdout_file_stream: File.OutStream = undefined;
- var stdout_stream = if (stdout_file) |f| x: {
- stdout_file_stream = f.outStream();
- break :x &stdout_file_stream.stream;
- } else |err| err;
+ const stderr_stream = &io.getStdErr().outStream().stream;
+ const stdout_stream = &io.getStdOut().outStream().stream;
while (arg_it.next(allocator)) |err_or_arg| {
const arg = try unwrapArg(err_or_arg);
@@ -63,37 +52,37 @@ pub fn main() !void {
const option_contents = arg[2..];
if (option_contents.len == 0) {
warn("Expected option name after '-D'\n\n");
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
}
if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
const option_name = option_contents[0..name_end];
const option_value = option_contents[name_end + 1 ..];
if (try builder.addUserInputOption(option_name, option_value))
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
} else {
if (try builder.addUserInputFlag(option_contents))
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
}
} else if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "--verbose")) {
builder.verbose = true;
} else if (mem.eql(u8, arg, "--help")) {
- return usage(builder, false, try stdout_stream);
+ return usage(builder, false, stdout_stream);
} else if (mem.eql(u8, arg, "--prefix")) {
builder.install_prefix = try unwrapArg(arg_it.next(allocator) orelse {
warn("Expected argument after --prefix\n\n");
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
});
} else if (mem.eql(u8, arg, "--search-prefix")) {
const search_prefix = try unwrapArg(arg_it.next(allocator) orelse {
warn("Expected argument after --search-prefix\n\n");
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
});
builder.addSearchPrefix(search_prefix);
} else if (mem.eql(u8, arg, "--override-lib-dir")) {
builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse {
warn("Expected argument after --override-lib-dir\n\n");
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
});
} else if (mem.eql(u8, arg, "--verbose-tokenize")) {
builder.verbose_tokenize = true;
@@ -111,7 +100,7 @@ pub fn main() !void {
builder.verbose_cc = true;
} else {
warn("Unrecognized argument: {}\n\n", arg);
- return usageAndErr(builder, false, try stderr_stream);
+ return usageAndErr(builder, false, stderr_stream);
}
} else {
try targets.append(arg);
@@ -122,12 +111,12 @@ pub fn main() !void {
try runBuild(builder);
if (builder.validateUserInputDidItFail())
- return usageAndErr(builder, true, try stderr_stream);
+ return usageAndErr(builder, true, stderr_stream);
builder.make(targets.toSliceConst()) catch |err| {
switch (err) {
error.InvalidStepName => {
- return usageAndErr(builder, true, try stderr_stream);
+ return usageAndErr(builder, true, stderr_stream);
},
error.UncleanExit => process.exit(1),
else => return err,
diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig
index f8b18af734..8122e537ed 100644
--- a/lib/std/unicode/throughput_test.zig
+++ b/lib/std/unicode/throughput_test.zig
@@ -2,9 +2,7 @@ const builtin = @import("builtin");
const std = @import("std");
pub fn main() !void {
- var stdout_file = try std.io.getStdOut();
- var stdout_out_stream = stdout_file.outStream();
- const stdout = &stdout_out_stream.stream;
+ const stdout = &std.io.getStdOut().outStream().stream;
const args = try std.process.argsAlloc(std.heap.direct_allocator);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index f61442adfc..cabbe823f6 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1451,11 +1451,11 @@ test "zig fmt: preserve spacing" {
\\const std = @import("std");
\\
\\pub fn main() !void {
- \\ var stdout_file = try std.io.getStdOut;
- \\ var stdout_file = try std.io.getStdOut;
+ \\ var stdout_file = std.io.getStdOut;
+ \\ var stdout_file = std.io.getStdOut;
\\
- \\ var stdout_file = try std.io.getStdOut;
- \\ var stdout_file = try std.io.getStdOut;
+ \\ var stdout_file = std.io.getStdOut;
+ \\ var stdout_file = std.io.getStdOut;
\\}
\\
);
@@ -2565,8 +2565,7 @@ const maxInt = std.math.maxInt;
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {
- var stderr_file = try io.getStdErr();
- var stderr = &stderr_file.outStream().stream;
+ const stderr = &io.getStdErr().outStream().stream;
const tree = try std.zig.parse(allocator, source);
defer tree.deinit();
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index a2e77394ce..71f9781186 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -56,13 +56,10 @@ pub fn main() !void {
// libc allocator is guaranteed to have this property.
const allocator = std.heap.c_allocator;
- var stdout_file = try std.io.getStdOut();
- var stdout_out_stream = stdout_file.outStream();
- stdout = &stdout_out_stream.stream;
+ stdout = &std.io.getStdOut().outStream().stream;
- stderr_file = try std.io.getStdErr();
- var stderr_out_stream = stderr_file.outStream();
- stderr = &stderr_out_stream.stream;
+ stderr_file = std.io.getStdErr();
+ stderr = &stderr_file.outStream().stream;
const args = try process.argsAlloc(allocator);
// TODO I'm getting unreachable code here, which shouldn't happen
@@ -619,7 +616,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
process.exit(1);
}
- var stdin_file = try io.getStdIn();
+ var stdin_file = io.getStdIn();
var stdin = stdin_file.inStream();
const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);
diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig
index e84f7b0ac1..37945bf029 100644
--- a/src-self-hosted/stage1.zig
+++ b/src-self-hosted/stage1.zig
@@ -166,13 +166,9 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));
}
- var stdout_file = try std.io.getStdOut();
- var stdout_out_stream = stdout_file.outStream();
- stdout = &stdout_out_stream.stream;
-
- stderr_file = try std.io.getStdErr();
- var stderr_out_stream = stderr_file.outStream();
- stderr = &stderr_out_stream.stream;
+ stdout = &std.io.getStdOut().outStream().stream;
+ stderr_file = std.io.getStdErr();
+ stderr = &stderr_file.outStream().stream;
const args = args_list.toSliceConst();
var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[2..]);
@@ -203,7 +199,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
process.exit(1);
}
- var stdin_file = try io.getStdIn();
+ const stdin_file = io.getStdIn();
var stdin = stdin_file.inStream();
const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig
index ce51de9a7b..496a7e0504 100644
--- a/src-self-hosted/test.zig
+++ b/src-self-hosted/test.zig
@@ -181,7 +181,7 @@ pub const TestContext = struct {
},
Compilation.Event.Error => |err| return err,
Compilation.Event.Fail => |msgs| {
- var stderr = try std.io.getStdErr();
+ const stderr = std.io.getStdErr();
try stderr.write("build incorrectly failed:\n");
for (msgs) |msg| {
defer msg.destroy();
@@ -231,7 +231,7 @@ pub const TestContext = struct {
text,
);
std.debug.warn("\n====found:========\n");
- var stderr = try std.io.getStdErr();
+ const stderr = std.io.getStdErr();
for (msgs) |msg| {
defer msg.destroy();
try msg.printToFile(stderr, errmsg.Color.Auto);
diff --git a/test/compare_output.zig b/test/compare_output.zig
index dfa33e26bd..0842fc4629 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -19,7 +19,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub fn main() void {
\\ privateFunction();
- \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &getStdOut().outStream().stream;
\\ stdout.print("OK 2\n") catch unreachable;
\\}
\\
@@ -34,7 +34,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\// purposefully conflicting function with main.zig
\\// but it's private so it should be OK
\\fn privateFunction() void {
- \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &getStdOut().outStream().stream;
\\ stdout.print("OK 1\n") catch unreachable;
\\}
\\
@@ -60,7 +60,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
tc.addSourceFile("foo.zig",
\\usingnamespace @import("std").io;
\\pub fn foo_function() void {
- \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &getStdOut().outStream().stream;
\\ stdout.print("OK\n") catch unreachable;
\\}
);
@@ -71,7 +71,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub fn bar_function() void {
\\ if (foo_function()) {
- \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &getStdOut().outStream().stream;
\\ stdout.print("OK\n") catch unreachable;
\\ }
\\}
@@ -103,7 +103,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub const a_text = "OK\n";
\\
\\pub fn ok() void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print(b_text) catch unreachable;
\\}
);
@@ -121,7 +121,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const io = @import("std").io;
\\
\\pub fn main() void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", @as(u32, 12), @as(u16, 0x12), @as(u8, 'a')) catch unreachable;
\\}
, "Hello, world!\n 12 12 a\n");
@@ -264,7 +264,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var x_local : i32 = print_ok(x);
\\}
\\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("OK\n") catch unreachable;
\\ return 0;
\\}
@@ -346,7 +346,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ const bar = Bar {.field2 = 13,};
\\ const foo = Foo {.field1 = bar,};
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ if (!foo.method()) {
\\ stdout.print("BAD\n") catch unreachable;
\\ }
@@ -360,7 +360,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.add("defer with only fallthrough",
\\const io = @import("std").io;
\\pub fn main() void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
\\ defer stdout.print("defer2\n") catch unreachable;
@@ -373,7 +373,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const io = @import("std").io;
\\const os = @import("std").os;
\\pub fn main() void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
\\ defer stdout.print("defer2\n") catch unreachable;
@@ -390,7 +390,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ do_test() catch return;
\\}
\\fn do_test() !void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
\\ errdefer stdout.print("deferErr\n") catch unreachable;
@@ -409,7 +409,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ do_test() catch return;
\\}
\\fn do_test() !void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
\\ errdefer stdout.print("deferErr\n") catch unreachable;
@@ -426,7 +426,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const io = @import("std").io;
\\
\\pub fn main() void {
- \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
+ \\ const stdout = &io.getStdOut().outStream().stream;
\\ stdout.print(foo_txt) catch unreachable;
\\}
, "1234\nabcd\n");
@@ -445,7 +445,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub fn main() !void {
\\ var args_it = std.process.args();
- \\ var stdout_file = try io.getStdOut();
+ \\ var stdout_file = io.getStdOut();
\\ var stdout_adapter = stdout_file.outStream();
\\ const stdout = &stdout_adapter.stream;
\\ var index: usize = 0;
@@ -486,7 +486,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub fn main() !void {
\\ var args_it = std.process.args();
- \\ var stdout_file = try io.getStdOut();
+ \\ var stdout_file = io.getStdOut();
\\ var stdout_adapter = stdout_file.outStream();
\\ const stdout = &stdout_adapter.stream;
\\ var index: usize = 0;
diff --git a/test/standalone/brace_expansion/main.zig b/test/standalone/brace_expansion/main.zig
index c1b8106e07..e291f2313b 100644
--- a/test/standalone/brace_expansion/main.zig
+++ b/test/standalone/brace_expansion/main.zig
@@ -179,8 +179,8 @@ fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {
}
pub fn main() !void {
- var stdin_file = try io.getStdIn();
- var stdout_file = try io.getStdOut();
+ const stdin_file = io.getStdIn();
+ const stdout_file = io.getStdOut();
var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator);
defer arena.deinit();
diff --git a/test/standalone/cat/main.zig b/test/standalone/cat/main.zig
index c57c1e4bcb..7c15c15e53 100644
--- a/test/standalone/cat/main.zig
+++ b/test/standalone/cat/main.zig
@@ -10,30 +10,28 @@ pub fn main() !void {
var args_it = process.args();
const exe = try unwrapArg(args_it.next(allocator).?);
var catted_anything = false;
- var stdout_file = try io.getStdOut();
+ const stdout_file = io.getStdOut();
while (args_it.next(allocator)) |arg_or_err| {
const arg = try unwrapArg(arg_or_err);
if (mem.eql(u8, arg, "-")) {
catted_anything = true;
- var stdin_file = try io.getStdIn();
- try cat_file(&stdout_file, &stdin_file);
+ try cat_file(stdout_file, io.getStdIn());
} else if (arg[0] == '-') {
return usage(exe);
} else {
- var file = File.openRead(arg) catch |err| {
+ const file = File.openRead(arg) catch |err| {
warn("Unable to open file: {}\n", @errorName(err));
return err;
};
defer file.close();
catted_anything = true;
- try cat_file(&stdout_file, &file);
+ try cat_file(stdout_file, file);
}
}
if (!catted_anything) {
- var stdin_file = try io.getStdIn();
- try cat_file(&stdout_file, &stdin_file);
+ try cat_file(stdout_file, io.getStdIn());
}
}
@@ -42,7 +40,7 @@ fn usage(exe: []const u8) !void {
return error.Invalid;
}
-fn cat_file(stdout: *File, file: *File) !void {
+fn cat_file(stdout: File, file: File) !void {
var buf: [1024 * 4]u8 = undefined;
while (true) {
diff --git a/test/standalone/guess_number/main.zig b/test/standalone/guess_number/main.zig
index b1e557fd20..8119b70d7e 100644
--- a/test/standalone/guess_number/main.zig
+++ b/test/standalone/guess_number/main.zig
@@ -4,8 +4,7 @@ const io = std.io;
const fmt = std.fmt;
pub fn main() !void {
- var stdout_file = try io.getStdOut();
- const stdout = &stdout_file.outStream().stream;
+ const stdout = &io.getStdOut().outStream().stream;
try stdout.print("Welcome to the Guess Number Game in Zig.\n");
diff --git a/test/standalone/hello_world/hello.zig b/test/standalone/hello_world/hello.zig
index cb7d5ef157..2ae5782328 100644
--- a/test/standalone/hello_world/hello.zig
+++ b/test/standalone/hello_world/hello.zig
@@ -2,7 +2,7 @@ const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
- const stdout_file = try std.io.getStdOut();
+ const stdout_file = std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
From c806de8ae723e363bb2f7e95e8a8aa754b464730 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 13 Nov 2019 13:44:19 -0500
Subject: [PATCH 083/129] README: update the short description of what zig is
---
README.md | 4 ++--
doc/langref.html.in | 12 +++++++-----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index d5199a1fa8..d4475fcf81 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@

-A general-purpose programming language designed for **robustness**,
-**optimality**, and **maintainability**.
+A general-purpose programming language for maintaining **robust**, **optimal**,
+and **reusable** code.
## Resources
diff --git a/doc/langref.html.in b/doc/langref.html.in
index dc44dd287f..5ecf312044 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -164,15 +164,17 @@
{#header_open|Introduction#}
- Zig is a general-purpose programming language designed for robustness,
- optimality, and maintainability.
+ Zig is a general-purpose programming language for maintaining robust,
+ optimal, and reusable code.
- Robust - behavior is correct even for edge cases such as out of memory.
- Optimal - write programs the best way they can behave and perform.
- - Maintainable - precisely communicate intent to the compiler and other programmers.
- The language imposes a low overhead to reading code and is resilient to changing requirements
- and environments.
+ - Reusable - the same code works in many environments which have different
+ constraints.
+ - Maintainable - precisely communicate intent to the compiler and
+ other programmers. The language imposes a low overhead to reading code and is
+ resilient to changing requirements and environments.
Often the most efficient way to learn something new is to see examples, so
From b83ce08a3b51c58096ab0b2383212a2124794c82 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Wed, 13 Nov 2019 12:05:15 +0200
Subject: [PATCH 084/129] add compile error for @atomicRmw on enum not being an
.Xchg
---
src/ir.cpp | 6 ++++++
test/compile_errors.zig | 16 ++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index b6cc3cd4cb..e5afc882d4 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25824,6 +25824,12 @@ static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstru
}
}
+ if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) {
+ ir_add_error(ira, instruction->op,
+ buf_sprintf("@atomicRmw on enum only works with .Xchg"));
+ return ira->codegen->invalid_instruction;
+ }
+
IrInstruction *operand = instruction->operand->child;
if (type_is_invalid(operand->value.type))
return ira->codegen->invalid_instruction;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 63d7240d42..d4c16a7d5f 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,22 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "atomicrmw with enum op not .Xchg",
+ \\export fn entry() void {
+ \\ const E = enum(u8) {
+ \\ a,
+ \\ b,
+ \\ c,
+ \\ d,
+ \\ };
+ \\ var x: E = .a;
+ \\ _ = @atomicRmw(E, &x, .Add, .b, .SeqCst);
+ \\}
+ ,
+ "tmp.zig:9:27: error: @atomicRmw on enum only works with .Xchg",
+ );
+
cases.add(
"atomic orderings of atomicStore Acquire or AcqRel",
\\export fn entry() void {
From ef6cec983c71b65058c54d98e7482b9926e7ddbf Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 14:59:21 +1100
Subject: [PATCH 085/129] std: add windows FILE_DEVICE_ defines
---
lib/std/os/windows/bits.zig | 87 +++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index 951edf2d67..bf71ca22aa 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -67,6 +67,93 @@ pub const va_list = *@OpaqueType();
pub const TRUE = 1;
pub const FALSE = 0;
+pub const DEVICE_TYPE = ULONG;
+pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
+pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
+pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
+pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
+pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
+pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
+pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
+pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
+pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
+pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
+pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
+pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
+pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
+pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
+pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
+pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
+pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
+pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
+pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
+pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
+pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
+pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
+pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
+pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
+pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
+pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
+pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
+pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
+pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
+pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
+pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
+pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
+pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
+pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
+pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
+pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
+pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
+pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
+pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
+pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
+pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
+pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
+pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
+pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
+pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
+pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
+pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
+pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
+pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
+pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
+pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
+pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
+pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
+pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
+pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
+pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
+pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
+pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
+pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
+// TODO: missing values?
+pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
+pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
+pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
+pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
+pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
+pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
+pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
+pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
+pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
+pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
+pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
+pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
+pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
+pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
+pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
+pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
+pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
+pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
+pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
+pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
+pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
+pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
+pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
+pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
+pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
+
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
From 0270545edb8db7f51e6b0581fad0bad5b783a7e0 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 15:00:32 +1100
Subject: [PATCH 086/129] std: add windows ioctl transfer types
---
lib/std/os/windows/bits.zig | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index bf71ca22aa..eb37a7e396 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -154,6 +154,14 @@ pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
+/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
+pub const TransferType = enum(u2) {
+ METHOD_BUFFERED = 0,
+ METHOD_IN_DIRECT = 1,
+ METHOD_OUT_DIRECT = 2,
+ METHOD_NEITHER = 3,
+};
+
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
From 4830415071c3d62e4e2c19e5f5342151632e72bb Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 15:59:03 +1100
Subject: [PATCH 087/129] std: add FILE_ANY_ constants for windows
---
lib/std/os/windows/bits.zig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index eb37a7e396..3dc772a7c3 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -162,6 +162,10 @@ pub const TransferType = enum(u2) {
METHOD_NEITHER = 3,
};
+pub const FILE_ANY_ACCESS = 0;
+pub const FILE_READ_ACCESS = 1;
+pub const FILE_WRITE_ACCESS = 2;
+
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
From be86e41d975325d30145e30369912a409012b76b Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 15:37:21 +1100
Subject: [PATCH 088/129] std: add CTL_CODE function for windows
---
lib/std/os/windows/bits.zig | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index 3dc772a7c3..2f65c27e47 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -166,6 +166,14 @@ pub const FILE_ANY_ACCESS = 0;
pub const FILE_READ_ACCESS = 1;
pub const FILE_WRITE_ACCESS = 2;
+/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
+pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
+ return (@as(DWORD, deviceType) << 16) |
+ (@as(DWORD, access) << 14) |
+ (@as(DWORD, function) << 2) |
+ @enumToInt(method);
+}
+
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
From a832b35c19801b02f97103bce9e86afd389a01dd Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 16:27:33 +1100
Subject: [PATCH 089/129] std: add windows socket constants
Taken from https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw
---
lib/std/os/bits/windows.zig | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig
index b5b8a9c2d4..a1ceb8ff5c 100644
--- a/lib/std/os/bits/windows.zig
+++ b/lib/std/os/bits/windows.zig
@@ -226,3 +226,17 @@ pub const AF_TCNMESSAGE = 30;
pub const AF_ICLFXBM = 31;
pub const AF_BTH = 32;
pub const AF_MAX = 33;
+
+pub const SOCK_STREAM = 1;
+pub const SOCK_DGRAM = 2;
+pub const SOCK_RAW = 3;
+pub const SOCK_RDM = 4;
+pub const SOCK_SEQPACKET = 5;
+
+pub const IPPROTO_ICMP = 1;
+pub const IPPROTO_IGMP = 2;
+pub const BTHPROTO_RFCOMM = 3;
+pub const IPPROTO_TCP = 6;
+pub const IPPROTO_UDP = 17;
+pub const IPPROTO_ICMPV6 = 58;
+pub const IPPROTO_RM = 113;
From f4c6cc3270db8f3557b3e7191eccc02098b4b2da Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 17:30:26 +1100
Subject: [PATCH 090/129] std: add winsock some definitions
---
lib/std/os/windows.zig | 1 +
lib/std/os/windows/ws2_32.zig | 186 ++++++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+)
create mode 100644 lib/std/os/windows/ws2_32.zig
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 9cdf8e9317..bc360e7e70 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -16,6 +16,7 @@ pub const kernel32 = @import("windows/kernel32.zig");
pub const ntdll = @import("windows/ntdll.zig");
pub const ole32 = @import("windows/ole32.zig");
pub const shell32 = @import("windows/shell32.zig");
+pub const ws2_32 = @import("windows/ws2_32.zig");
pub usingnamespace @import("windows/bits.zig");
diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig
new file mode 100644
index 0000000000..1fe5d87496
--- /dev/null
+++ b/lib/std/os/windows/ws2_32.zig
@@ -0,0 +1,186 @@
+usingnamespace @import("bits.zig");
+
+pub const SOCKET = *@OpaqueType();
+pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
+
+pub const MAX_PROTOCOL_CHAIN = 7;
+
+pub const WSAPROTOCOLCHAIN = extern struct {
+ ChainLen: c_int,
+ ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
+};
+
+pub const WSAPROTOCOL_LEN = 255;
+
+pub const WSAPROTOCOL_INFOA = extern struct {
+ dwServiceFlags1: DWORD,
+ dwServiceFlags2: DWORD,
+ dwServiceFlags3: DWORD,
+ dwServiceFlags4: DWORD,
+ dwProviderFlags: DWORD,
+ ProviderId: GUID,
+ dwCatalogEntryId: DWORD,
+ ProtocolChain: WSAPROTOCOLCHAIN,
+ iVersion: c_int,
+ iAddressFamily: c_int,
+ iMaxSockAddr: c_int,
+ iMinSockAddr: c_int,
+ iSocketType: c_int,
+ iProtocol: c_int,
+ iProtocolMaxOffset: c_int,
+ iNetworkByteOrder: c_int,
+ iSecurityScheme: c_int,
+ dwMessageSize: DWORD,
+ dwProviderReserved: DWORD,
+ szProtocol: [WSAPROTOCOL_LEN + 1]CHAR,
+};
+
+pub const WSAPROTOCOL_INFOW = extern struct {
+ dwServiceFlags1: DWORD,
+ dwServiceFlags2: DWORD,
+ dwServiceFlags3: DWORD,
+ dwServiceFlags4: DWORD,
+ dwProviderFlags: DWORD,
+ ProviderId: GUID,
+ dwCatalogEntryId: DWORD,
+ ProtocolChain: WSAPROTOCOLCHAIN,
+ iVersion: c_int,
+ iAddressFamily: c_int,
+ iMaxSockAddr: c_int,
+ iMinSockAddr: c_int,
+ iSocketType: c_int,
+ iProtocol: c_int,
+ iProtocolMaxOffset: c_int,
+ iNetworkByteOrder: c_int,
+ iSecurityScheme: c_int,
+ dwMessageSize: DWORD,
+ dwProviderReserved: DWORD,
+ szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,
+};
+
+pub const GROUP = u32;
+
+pub const SG_UNCONSTRAINED_GROUP = 0x1;
+pub const SG_CONSTRAINED_GROUP = 0x2;
+
+pub const WSA_FLAG_OVERLAPPED = 0x01;
+pub const WSA_FLAG_MULTIPOINT_C_ROOT = 0x02;
+pub const WSA_FLAG_MULTIPOINT_C_LEAF = 0x04;
+pub const WSA_FLAG_MULTIPOINT_D_ROOT = 0x08;
+pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10;
+pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40;
+pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80;
+
+pub const WSA_INVALID_HANDLE = 6;
+pub const WSA_NOT_ENOUGH_MEMORY = 8;
+pub const WSA_INVALID_PARAMETER = 87;
+pub const WSA_OPERATION_ABORTED = 995;
+pub const WSA_IO_INCOMPLETE = 996;
+pub const WSA_IO_PENDING = 997;
+pub const WSAEINTR = 10004;
+pub const WSAEBADF = 10009;
+pub const WSAEACCES = 10013;
+pub const WSAEFAULT = 10014;
+pub const WSAEINVAL = 10022;
+pub const WSAEMFILE = 10024;
+pub const WSAEWOULDBLOCK = 10035;
+pub const WSAEINPROGRESS = 10036;
+pub const WSAEALREADY = 10037;
+pub const WSAENOTSOCK = 10038;
+pub const WSAEDESTADDRREQ = 10039;
+pub const WSAEMSGSIZE = 10040;
+pub const WSAEPROTOTYPE = 10041;
+pub const WSAENOPROTOOPT = 10042;
+pub const WSAEPROTONOSUPPORT = 10043;
+pub const WSAESOCKTNOSUPPORT = 10044;
+pub const WSAEOPNOTSUPP = 10045;
+pub const WSAEPFNOSUPPORT = 10046;
+pub const WSAEAFNOSUPPORT = 10047;
+pub const WSAEADDRINUSE = 10048;
+pub const WSAEADDRNOTAVAIL = 10049;
+pub const WSAENETDOWN = 10050;
+pub const WSAENETUNREACH = 10051;
+pub const WSAENETRESET = 10052;
+pub const WSAECONNABORTED = 10053;
+pub const WSAECONNRESET = 10054;
+pub const WSAENOBUFS = 10055;
+pub const WSAEISCONN = 10056;
+pub const WSAENOTCONN = 10057;
+pub const WSAESHUTDOWN = 10058;
+pub const WSAETOOMANYREFS = 10059;
+pub const WSAETIMEDOUT = 10060;
+pub const WSAECONNREFUSED = 10061;
+pub const WSAELOOP = 10062;
+pub const WSAENAMETOOLONG = 10063;
+pub const WSAEHOSTDOWN = 10064;
+pub const WSAEHOSTUNREACH = 10065;
+pub const WSAENOTEMPTY = 10066;
+pub const WSAEPROCLIM = 10067;
+pub const WSAEUSERS = 10068;
+pub const WSAEDQUOT = 10069;
+pub const WSAESTALE = 10070;
+pub const WSAEREMOTE = 10071;
+pub const WSASYSNOTREADY = 10091;
+pub const WSAVERNOTSUPPORTED = 10092;
+pub const WSANOTINITIALISED = 10093;
+pub const WSAEDISCON = 10101;
+pub const WSAENOMORE = 10102;
+pub const WSAECANCELLED = 10103;
+pub const WSAEINVALIDPROCTABLE = 10104;
+pub const WSAEINVALIDPROVIDER = 10105;
+pub const WSAEPROVIDERFAILEDINIT = 10106;
+pub const WSASYSCALLFAILURE = 10107;
+pub const WSASERVICE_NOT_FOUND = 10108;
+pub const WSATYPE_NOT_FOUND = 10109;
+pub const WSA_E_NO_MORE = 10110;
+pub const WSA_E_CANCELLED = 10111;
+pub const WSAEREFUSED = 10112;
+pub const WSAHOST_NOT_FOUND = 11001;
+pub const WSATRY_AGAIN = 11002;
+pub const WSANO_RECOVERY = 11003;
+pub const WSANO_DATA = 11004;
+pub const WSA_QOS_RECEIVERS = 11005;
+pub const WSA_QOS_SENDERS = 11006;
+pub const WSA_QOS_NO_SENDERS = 11007;
+pub const WSA_QOS_NO_RECEIVERS = 11008;
+pub const WSA_QOS_REQUEST_CONFIRMED = 11009;
+pub const WSA_QOS_ADMISSION_FAILURE = 11010;
+pub const WSA_QOS_POLICY_FAILURE = 11011;
+pub const WSA_QOS_BAD_STYLE = 11012;
+pub const WSA_QOS_BAD_OBJECT = 11013;
+pub const WSA_QOS_TRAFFIC_CTRL_ERROR = 11014;
+pub const WSA_QOS_GENERIC_ERROR = 11015;
+pub const WSA_QOS_ESERVICETYPE = 11016;
+pub const WSA_QOS_EFLOWSPEC = 11017;
+pub const WSA_QOS_EPROVSPECBUF = 11018;
+pub const WSA_QOS_EFILTERSTYLE = 11019;
+pub const WSA_QOS_EFILTERTYPE = 11020;
+pub const WSA_QOS_EFILTERCOUNT = 11021;
+pub const WSA_QOS_EOBJLENGTH = 11022;
+pub const WSA_QOS_EFLOWCOUNT = 11023;
+pub const WSA_QOS_EUNKOWNPSOBJ = 11024;
+pub const WSA_QOS_EPOLICYOBJ = 11025;
+pub const WSA_QOS_EFLOWDESC = 11026;
+pub const WSA_QOS_EPSFLOWSPEC = 11027;
+pub const WSA_QOS_EPSFILTERSPEC = 11028;
+pub const WSA_QOS_ESDMODEOBJ = 11029;
+pub const WSA_QOS_ESHAPERATEOBJ = 11030;
+pub const WSA_QOS_RESERVED_PETYPE = 11031;
+
+pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int;
+pub extern "ws2_32" stdcallcc fn WSASocketA(
+ af: c_int,
+ type: c_int,
+ protocol: c_int,
+ lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
+ g: GROUP,
+ dwFlags: DWORD,
+) SOCKET;
+pub extern "ws2_32" stdcallcc fn WSASocketW(
+ af: c_int,
+ type: c_int,
+ protocol: c_int,
+ lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
+ g: GROUP,
+ dwFlags: DWORD,
+) SOCKET;
From d9d3268cc1fe6b581ccb44606346cb6847d557a5 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 18:22:33 +1100
Subject: [PATCH 091/129] std: add DeviceIoControl and GetOverlappedResult for
windows
---
lib/std/os/windows.zig | 36 +++++++++++++++++++++++++++++++++
lib/std/os/windows/kernel32.zig | 11 ++++++++++
2 files changed, 47 insertions(+)
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index bc360e7e70..4d2944b563 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -97,6 +97,42 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
}
}
+pub fn DeviceIoControl(
+ h: HANDLE,
+ ioControlCode: DWORD,
+ in: ?[]const u8,
+ out: ?[]u8,
+ overlapped: ?*OVERLAPPED,
+) !DWORD {
+ var bytes: DWORD = undefined;
+ if (kernel32.DeviceIoControl(
+ h,
+ ioControlCode,
+ if (in) |i| i.ptr else null,
+ if (in) |i| @intCast(u32, i.len) else 0,
+ if (out) |o| o.ptr else null,
+ if (out) |o| @intCast(u32, o.len) else 0,
+ &bytes,
+ overlapped,
+ ) == 0) {
+ switch (kernel32.GetLastError()) {
+ else => |err| return unexpectedError(err),
+ }
+ }
+ return bytes;
+}
+
+pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
+ var bytes: DWORD = undefined;
+ if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) {
+ switch (kernel32.GetLastError()) {
+ ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
+ else => |err| return unexpectedError(err),
+ }
+ }
+ return bytes;
+}
+
pub const SetHandleInformationError = error{Unexpected};
pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void {
diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig
index d466f9946d..30c4cf4785 100644
--- a/lib/std/os/windows/kernel32.zig
+++ b/lib/std/os/windows/kernel32.zig
@@ -45,6 +45,17 @@ pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, Ex
pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;
+pub extern "kernel32" stdcallcc fn DeviceIoControl(
+ h: HANDLE,
+ dwIoControlCode: DWORD,
+ lpInBuffer: ?*const c_void,
+ nInBufferSize: DWORD,
+ lpOutBuffer: ?LPVOID,
+ nOutBufferSize: DWORD,
+ lpBytesReturned: LPDWORD,
+ lpOverlapped: ?*OVERLAPPED,
+) BOOL;
+
pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL;
pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL;
From 4cf535a01b06c301239fb888dbdf87831c568867 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Wed, 13 Nov 2019 18:23:21 +1100
Subject: [PATCH 092/129] std: add WSASocketW for windows
---
lib/std/os/windows.zig | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 4d2944b563..e8011b7534 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -608,6 +608,27 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD
return rc;
}
+pub fn WSASocketW(
+ af: i32,
+ socket_type: i32,
+ protocol: i32,
+ protocolInfo: ?*ws2_32.WSAPROTOCOL_INFOW,
+ g: ws2_32.GROUP,
+ dwFlags: DWORD,
+) !ws2_32.SOCKET {
+ const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags);
+ if (rc == ws2_32.INVALID_SOCKET) {
+ switch (ws2_32.WSAGetLastError()) {
+ ws2_32.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
+ ws2_32.WSAEMFILE => return error.ProcessFdQuotaExceeded,
+ ws2_32.WSAENOBUFS => return error.SystemResources,
+ ws2_32.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
+ else => |err| return unexpectedWSAError(err),
+ }
+ }
+ return rc;
+}
+
const GetModuleFileNameError = error{Unexpected};
pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 {
@@ -905,6 +926,10 @@ pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {
return error.Unexpected;
}
+pub fn unexpectedWSAError(err: c_int) std.os.UnexpectedError {
+ return unexpectedError(@intCast(DWORD, err));
+}
+
/// Call this when you made a windows NtDll call
/// and you get an unexpected status.
pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
From f2f698a888afdc8709142912f8394376d28e16ea Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 13 Nov 2019 20:26:09 -0500
Subject: [PATCH 093/129] rework comptime struct value layout, removing 1/2
hacks
in the implementation of anonymous struct literals
---
src/all_types.hpp | 2 +-
src/analyze.cpp | 41 ++--
src/analyze.hpp | 2 +
src/codegen.cpp | 16 +-
src/ir.cpp | 482 +++++++++++++++++++++++-----------------------
5 files changed, 277 insertions(+), 266 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 25815ef64a..e246016006 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -152,7 +152,7 @@ struct ConstParent {
};
struct ConstStructValue {
- ConstExprValue *fields;
+ ConstExprValue **fields;
};
struct ConstUnionValue {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 1232cebe8b..ee95e5d246 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1461,8 +1461,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
if (type_is_invalid(result_val->type))
return false;
- ConstExprValue *ptr_field = &result_val->data.x_struct.fields[slice_ptr_index];
- ConstExprValue *len_field = &result_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *ptr_field = result_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *len_field = result_val->data.x_struct.fields[slice_len_index];
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
@@ -5283,7 +5283,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
zig_unreachable();
case ZigTypeIdStruct:
for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
- if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))
+ if (can_mutate_comptime_var_state(value->data.x_struct.fields[i]))
return true;
}
return false;
@@ -5798,11 +5798,11 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
const_val->special = ConstValSpecialStatic;
const_val->type = get_slice_type(g, ptr_type);
- const_val->data.x_struct.fields = create_const_vals(2);
+ const_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
- init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
+ init_const_ptr_array(g, const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
PtrLenUnknown);
- init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);
+ init_const_usize(g, const_val->data.x_struct.fields[slice_len_index], len);
}
ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {
@@ -5886,6 +5886,23 @@ ConstExprValue *create_const_vals(size_t count) {
return vals;
}
+ConstExprValue **alloc_const_vals_ptrs(size_t count) {
+ return realloc_const_vals_ptrs(nullptr, 0, count);
+}
+
+ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count) {
+ assert(new_count >= old_count);
+
+ size_t new_item_count = new_count - old_count;
+ ConstExprValue **result = reallocate(ptr, old_count, new_count, "ConstExprValue*");
+ ConstExprValue *vals = create_const_vals(new_item_count);
+ for (size_t i = old_count; i < new_count; i += 1) {
+ result[i] = &vals[i - old_count];
+ }
+ return result;
+}
+
+
static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
return orig_fn_type;
@@ -6567,8 +6584,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
}
case ZigTypeIdStruct:
for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
- ConstExprValue *field_a = &a->data.x_struct.fields[i];
- ConstExprValue *field_b = &b->data.x_struct.fields[i];
+ ConstExprValue *field_a = a->data.x_struct.fields[i];
+ ConstExprValue *field_b = b->data.x_struct.fields[i];
if (!const_values_equal(g, field_a, field_b))
return false;
}
@@ -6876,10 +6893,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
case ZigTypeIdStruct:
{
if (is_slice(type_entry)) {
- ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = const_val->data.x_struct.fields[slice_len_index];
size_t len = bigint_as_usize(&len_val->data.x_bigint);
- ConstExprValue *ptr_val = &const_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_val = const_val->data.x_struct.fields[slice_ptr_index];
if (ptr_val->special == ConstValSpecialUndef) {
assert(len == 0);
buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name));
@@ -7156,9 +7173,9 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
const_val->special = ConstValSpecialStatic;
size_t field_count = wanted_type->data.structure.src_field_count;
- const_val->data.x_struct.fields = create_const_vals(field_count);
+ const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
for (size_t i = 0; i < field_count; i += 1) {
- ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
+ ConstExprValue *field_val = const_val->data.x_struct.fields[i];
field_val->type = resolve_struct_field_type(g, &wanted_type->data.structure.fields[i]);
assert(field_val->type);
init_const_undefined(g, field_val);
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 884f525717..0cca75891a 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -177,6 +177,8 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
ConstExprValue *create_const_vals(size_t count);
+ConstExprValue **alloc_const_vals_ptrs(size_t count);
+ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count);
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index a0666a3522..ed9b69e529 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -3508,7 +3508,7 @@ static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val) {
case ConstValSpecialStatic:
if (const_val->type->id == ZigTypeIdStruct) {
for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {
- if (!value_is_all_undef(g, &const_val->data.x_struct.fields[i]))
+ if (!value_is_all_undef(g, const_val->data.x_struct.fields[i]))
return false;
}
return true;
@@ -6572,7 +6572,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
if (field->gen_index == SIZE_MAX) {
continue;
}
- LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]);
+ LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]);
uint32_t packed_bits_size = type_size_bits(g, field->type_entry);
if (is_big_endian) {
LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false);
@@ -6840,7 +6840,7 @@ check: switch (const_val->special) {
}
if (src_field_index + 1 == src_field_index_end) {
- ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index];
+ ConstExprValue *field_val = const_val->data.x_struct.fields[src_field_index];
LLVMValueRef val = gen_const_val(g, field_val, "");
fields[type_struct_field->gen_index] = val;
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
@@ -6858,7 +6858,7 @@ check: switch (const_val->special) {
continue;
}
LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,
- &const_val->data.x_struct.fields[i]);
+ const_val->data.x_struct.fields[i]);
uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry);
if (is_big_endian) {
LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,
@@ -6897,7 +6897,7 @@ check: switch (const_val->special) {
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
- ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
+ ConstExprValue *field_val = const_val->data.x_struct.fields[i];
assert(field_val->type != nullptr);
if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val,
type_struct_field->type_entry)))
@@ -9074,13 +9074,13 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
this_val->parent.id = ConstParentIdArray;
this_val->parent.data.p_array.array_val = test_fn_array;
this_val->parent.data.p_array.elem_index = i;
- this_val->data.x_struct.fields = create_const_vals(2);
+ this_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
- ConstExprValue *name_field = &this_val->data.x_struct.fields[0];
+ ConstExprValue *name_field = this_val->data.x_struct.fields[0];
ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);
init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true);
- ConstExprValue *fn_field = &this_val->data.x_struct.fields[1];
+ ConstExprValue *fn_field = this_val->data.x_struct.fields[1];
fn_field->type = fn_type;
fn_field->special = ConstValSpecialStatic;
fn_field->data.x_ptr.special = ConstPtrSpecialFunction;
diff --git a/src/ir.cpp b/src/ir.cpp
index e5afc882d4..d52daacc42 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -240,7 +240,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
case ConstPtrSpecialBaseStruct: {
ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
expand_undef_struct(g, struct_val);
- result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];
+ result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];
break;
}
case ConstPtrSpecialBaseErrorUnionCode:
@@ -10784,9 +10784,9 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_
if (src->special != ConstValSpecialStatic)
return;
if (dest->type->id == ZigTypeIdStruct) {
- dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count);
+ dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
- copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false);
+ copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false);
}
}
}
@@ -10982,8 +10982,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
IrInstruction *result = ir_const(ira, source_instr, wanted_type);
init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const);
- result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut =
- value->value.data.x_ptr.mut;
+ result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = value->value.data.x_ptr.mut;
result->value.type = wanted_type;
return result;
}
@@ -13491,8 +13490,8 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
if (!const_val)
return nullptr;
- ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index];
- ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *len_field = const_val->data.x_struct.fields[slice_len_index];
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
@@ -14820,11 +14819,11 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
} else if (is_slice(op1_type)) {
ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry;
child_type = ptr_type->data.pointer.child_type;
- ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index];
assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
- ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index];
op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint);
} else {
ir_add_error(ira, op1,
@@ -14853,11 +14852,11 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
} else if (is_slice(op2_type)) {
ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;
op2_type_valid = ptr_type->data.pointer.child_type == child_type;
- ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index];
assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
- ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index];
op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint);
} else {
ir_add_error(ira, op2,
@@ -14889,17 +14888,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
out_array_val->special = ConstValSpecialStatic;
out_array_val->type = get_array_type(ira->codegen, child_type, new_len);
- out_val->data.x_struct.fields = create_const_vals(2);
+ out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
- out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type;
- out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic;
- out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray;
- out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val;
- out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0;
+ out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type;
+ out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic;
+ out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray;
+ out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val;
+ out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0;
- out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize;
- out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic;
- bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len);
+ out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize;
+ out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic;
+ bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len);
} else {
new_len += 1; // null byte
@@ -16496,17 +16495,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
source_instr->source_node);
struct_val->special = ConstValSpecialStatic;
- if (new_field_count > 16) {
- // This thing with 16 is a hack to allow this functionality to work without
- // modifying the ConstExprValue layout of structs. That reworking needs to be
- // done, but this hack lets us do it separately, in the future.
- zig_panic("TODO need to rework the layout of ConstExprValue for structs. This realloc would have caused invalid pointer references");
- }
- if (struct_val->data.x_struct.fields == nullptr) {
- struct_val->data.x_struct.fields = create_const_vals(16);
- }
+ struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields,
+ old_field_count, new_field_count);
- ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];
+ ConstExprValue *field_val = struct_val->data.x_struct.fields[old_field_count];
field_val->special = ConstValSpecialUndef;
field_val->type = field->type_entry;
field_val->parent.id = ConstParentIdStruct;
@@ -18156,7 +18148,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len,
false);
- array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;
+ array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer;
} else {
ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
buf_sprintf("expected array type or [_], found '%s'",
@@ -18228,7 +18220,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
}
return result;
} else if (is_slice(array_type)) {
- ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index];
ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base);
if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
@@ -18237,7 +18229,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
result->value.type = return_type;
return result;
}
- ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index];
IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type);
ConstExprValue *out_val = &result->value;
uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint);
@@ -18466,10 +18458,10 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
if (type_is_invalid(struct_val->type))
return ira->codegen->invalid_instruction;
if (initializing && struct_val->special == ConstValSpecialUndef) {
- struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);
+ struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count);
struct_val->special = ConstValSpecialStatic;
for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
- ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
+ ConstExprValue *field_val = struct_val->data.x_struct.fields[i];
field_val->special = ConstValSpecialUndef;
field_val->type = resolve_struct_field_type(ira->codegen,
&struct_type->data.structure.fields[i]);
@@ -21005,17 +20997,17 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
declaration_val->special = ConstValSpecialStatic;
declaration_val->type = type_info_declaration_type;
- ConstExprValue *inner_fields = create_const_vals(3);
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);
- init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true);
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
- inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;
- inner_fields[2].special = ConstValSpecialStatic;
- inner_fields[2].type = type_info_declaration_data_type;
- inner_fields[2].parent.id = ConstParentIdStruct;
- inner_fields[2].parent.data.p_struct.struct_val = declaration_val;
- inner_fields[2].parent.data.p_struct.field_index = 1;
+ init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true);
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = ira->codegen->builtin_types.entry_bool;
+ inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub;
+ inner_fields[2]->special = ConstValSpecialStatic;
+ inner_fields[2]->type = type_info_declaration_data_type;
+ inner_fields[2]->parent.id = ConstParentIdStruct;
+ inner_fields[2]->parent.data.p_struct.struct_val = declaration_val;
+ inner_fields[2]->parent.data.p_struct.field_index = 1;
switch (curr_entry->value->id) {
case TldIdVar:
@@ -21027,19 +21019,19 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
if (var->const_value->type->id == ZigTypeIdMetaType) {
// We have a variable of type 'type', so it's actually a type declaration.
// 0: Data.Type: type
- bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);
- inner_fields[2].data.x_union.payload = var->const_value;
+ bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0);
+ inner_fields[2]->data.x_union.payload = var->const_value;
} else {
// We have a variable of another type, so we store the type of the variable.
// 1: Data.Var: type
- bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1);
+ bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1);
ConstExprValue *payload = create_const_vals(1);
payload->special = ConstValSpecialStatic;
payload->type = ira->codegen->builtin_types.entry_type;
payload->data.x_type = var->const_value->type;
- inner_fields[2].data.x_union.payload = payload;
+ inner_fields[2]->data.x_union.payload = payload;
}
break;
@@ -21047,7 +21039,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
case TldIdFn:
{
// 2: Data.Fn: Data.FnDecl
- bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);
+ bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2);
ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
assert(!fn_entry->is_test);
@@ -21063,63 +21055,63 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
fn_decl_val->special = ConstValSpecialStatic;
fn_decl_val->type = type_info_fn_decl_type;
fn_decl_val->parent.id = ConstParentIdUnion;
- fn_decl_val->parent.data.p_union.union_val = &inner_fields[2];
+ fn_decl_val->parent.data.p_union.union_val = inner_fields[2];
- ConstExprValue *fn_decl_fields = create_const_vals(9);
+ ConstExprValue **fn_decl_fields = alloc_const_vals_ptrs(9);
fn_decl_val->data.x_struct.fields = fn_decl_fields;
// fn_type: type
ensure_field_index(fn_decl_val->type, "fn_type", 0);
- fn_decl_fields[0].special = ConstValSpecialStatic;
- fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type;
- fn_decl_fields[0].data.x_type = fn_entry->type_entry;
+ fn_decl_fields[0]->special = ConstValSpecialStatic;
+ fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type;
+ fn_decl_fields[0]->data.x_type = fn_entry->type_entry;
// inline_type: Data.FnDecl.Inline
ensure_field_index(fn_decl_val->type, "inline_type", 1);
- fn_decl_fields[1].special = ConstValSpecialStatic;
- fn_decl_fields[1].type = type_info_fn_decl_inline_type;
- bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline);
+ fn_decl_fields[1]->special = ConstValSpecialStatic;
+ fn_decl_fields[1]->type = type_info_fn_decl_inline_type;
+ bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline);
// calling_convention: TypeInfo.CallingConvention
ensure_field_index(fn_decl_val->type, "calling_convention", 2);
- fn_decl_fields[2].special = ConstValSpecialStatic;
- fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
- bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc);
+ fn_decl_fields[2]->special = ConstValSpecialStatic;
+ fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
+ bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc);
// is_var_args: bool
ensure_field_index(fn_decl_val->type, "is_var_args", 3);
bool is_varargs = fn_node->is_var_args;
- fn_decl_fields[3].special = ConstValSpecialStatic;
- fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool;
- fn_decl_fields[3].data.x_bool = is_varargs;
+ fn_decl_fields[3]->special = ConstValSpecialStatic;
+ fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool;
+ fn_decl_fields[3]->data.x_bool = is_varargs;
// is_extern: bool
ensure_field_index(fn_decl_val->type, "is_extern", 4);
- fn_decl_fields[4].special = ConstValSpecialStatic;
- fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool;
- fn_decl_fields[4].data.x_bool = fn_node->is_extern;
+ fn_decl_fields[4]->special = ConstValSpecialStatic;
+ fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool;
+ fn_decl_fields[4]->data.x_bool = fn_node->is_extern;
// is_export: bool
ensure_field_index(fn_decl_val->type, "is_export", 5);
- fn_decl_fields[5].special = ConstValSpecialStatic;
- fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool;
- fn_decl_fields[5].data.x_bool = fn_node->is_export;
+ fn_decl_fields[5]->special = ConstValSpecialStatic;
+ fn_decl_fields[5]->type = ira->codegen->builtin_types.entry_bool;
+ fn_decl_fields[5]->data.x_bool = fn_node->is_export;
// lib_name: ?[]const u8
ensure_field_index(fn_decl_val->type, "lib_name", 6);
- fn_decl_fields[6].special = ConstValSpecialStatic;
+ fn_decl_fields[6]->special = ConstValSpecialStatic;
ZigType *u8_ptr = get_pointer_to_type_extra(
ira->codegen, ira->codegen->builtin_types.entry_u8,
true, false, PtrLenUnknown,
0, 0, 0, false);
- fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
+ fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
- fn_decl_fields[6].data.x_optional = create_const_vals(1);
+ fn_decl_fields[6]->data.x_optional = create_const_vals(1);
ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
- init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0,
+ init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0,
buf_len(fn_node->lib_name), true);
} else {
- fn_decl_fields[6].data.x_optional = nullptr;
+ fn_decl_fields[6]->data.x_optional = nullptr;
}
// return_type: type
ensure_field_index(fn_decl_val->type, "return_type", 7);
- fn_decl_fields[7].special = ConstValSpecialStatic;
- fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type;
- fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
+ fn_decl_fields[7]->special = ConstValSpecialStatic;
+ fn_decl_fields[7]->type = ira->codegen->builtin_types.entry_type;
+ fn_decl_fields[7]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
// arg_names: [][] const u8
ensure_field_index(fn_decl_val->type, "arg_names", 8);
size_t fn_arg_count = fn_entry->variable_list.length;
@@ -21130,7 +21122,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
- init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
+ init_const_slice(ira->codegen, fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
@@ -21143,7 +21135,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
}
- inner_fields[2].data.x_union.payload = fn_decl_val;
+ inner_fields[2]->data.x_union.payload = fn_decl_val;
break;
}
case TldIdContainer:
@@ -21153,14 +21145,14 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
return ErrorSemanticAnalyzeFail;
// This is a type.
- bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);
+ bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0);
ConstExprValue *payload = create_const_vals(1);
payload->special = ConstValSpecialStatic;
payload->type = ira->codegen->builtin_types.entry_type;
payload->data.x_type = type_entry;
- inner_fields[2].data.x_union.payload = payload;
+ inner_fields[2]->data.x_union.payload = payload;
break;
}
@@ -21169,7 +21161,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
}
declaration_val->data.x_struct.fields = inner_fields;
- declaration_index++;
+ declaration_index += 1;
}
assert(declaration_index == declaration_count);
@@ -21225,42 +21217,42 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
result->special = ConstValSpecialStatic;
result->type = type_info_pointer_type;
- ConstExprValue *fields = create_const_vals(6);
+ ConstExprValue **fields = alloc_const_vals_ptrs(6);
result->data.x_struct.fields = fields;
// size: Size
ensure_field_index(result->type, "size", 0);
ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);
assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown));
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = type_info_pointer_size_type;
- bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = type_info_pointer_size_type;
+ bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index);
// is_const: bool
ensure_field_index(result->type, "is_const", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_bool;
- fields[1].data.x_bool = attrs_type->data.pointer.is_const;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_bool;
+ fields[1]->data.x_bool = attrs_type->data.pointer.is_const;
// is_volatile: bool
ensure_field_index(result->type, "is_volatile", 2);
- fields[2].special = ConstValSpecialStatic;
- fields[2].type = ira->codegen->builtin_types.entry_bool;
- fields[2].data.x_bool = attrs_type->data.pointer.is_volatile;
+ fields[2]->special = ConstValSpecialStatic;
+ fields[2]->type = ira->codegen->builtin_types.entry_bool;
+ fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile;
// alignment: u32
ensure_field_index(result->type, "alignment", 3);
- fields[3].special = ConstValSpecialStatic;
- fields[3].type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type));
+ fields[3]->special = ConstValSpecialStatic;
+ fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type));
// child: type
ensure_field_index(result->type, "child", 4);
- fields[4].special = ConstValSpecialStatic;
- fields[4].type = ira->codegen->builtin_types.entry_type;
- fields[4].data.x_type = attrs_type->data.pointer.child_type;
+ fields[4]->special = ConstValSpecialStatic;
+ fields[4]->type = ira->codegen->builtin_types.entry_type;
+ fields[4]->data.x_type = attrs_type->data.pointer.child_type;
// is_allowzero: bool
ensure_field_index(result->type, "is_allowzero", 5);
- fields[5].special = ConstValSpecialStatic;
- fields[5].type = ira->codegen->builtin_types.entry_bool;
- fields[5].data.x_bool = attrs_type->data.pointer.allow_zero;
+ fields[5]->special = ConstValSpecialStatic;
+ fields[5]->type = ira->codegen->builtin_types.entry_bool;
+ fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero;
return result;
};
@@ -21271,14 +21263,14 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val,
enum_field_val->special = ConstValSpecialStatic;
enum_field_val->type = type_info_enum_field_type;
- ConstExprValue *inner_fields = create_const_vals(2);
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(2);
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name);
- init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true);
+ init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true);
- bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value);
+ bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value);
enum_field_val->data.x_struct.fields = inner_fields;
}
@@ -21322,19 +21314,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Int", nullptr);
- ConstExprValue *fields = create_const_vals(2);
+ ConstExprValue **fields = alloc_const_vals_ptrs(2);
result->data.x_struct.fields = fields;
// is_signed: bool
ensure_field_index(result->type, "is_signed", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_bool;
- fields[0].data.x_bool = type_entry->data.integral.is_signed;
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_bool;
+ fields[0]->data.x_bool = type_entry->data.integral.is_signed;
// bits: u8
ensure_field_index(result->type, "bits", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count);
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count);
break;
}
@@ -21344,14 +21336,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Float", nullptr);
- ConstExprValue *fields = create_const_vals(1);
+ ConstExprValue **fields = alloc_const_vals_ptrs(1);
result->data.x_struct.fields = fields;
// bits: u8
ensure_field_index(result->type, "bits", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count);
break;
}
@@ -21368,19 +21360,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Array", nullptr);
- ConstExprValue *fields = create_const_vals(2);
+ ConstExprValue **fields = alloc_const_vals_ptrs(2);
result->data.x_struct.fields = fields;
// len: usize
ensure_field_index(result->type, "len", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len);
// child: type
ensure_field_index(result->type, "child", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_type;
- fields[1].data.x_type = type_entry->data.array.child_type;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_type;
+ fields[1]->data.x_type = type_entry->data.array.child_type;
break;
}
@@ -21389,19 +21381,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Vector", nullptr);
- ConstExprValue *fields = create_const_vals(2);
+ ConstExprValue **fields = alloc_const_vals_ptrs(2);
result->data.x_struct.fields = fields;
// len: usize
ensure_field_index(result->type, "len", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len);
// child: type
ensure_field_index(result->type, "child", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_type;
- fields[1].data.x_type = type_entry->data.vector.elem_type;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_type;
+ fields[1]->data.x_type = type_entry->data.vector.elem_type;
break;
}
@@ -21411,14 +21403,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Optional", nullptr);
- ConstExprValue *fields = create_const_vals(1);
+ ConstExprValue **fields = alloc_const_vals_ptrs(1);
result->data.x_struct.fields = fields;
// child: type
ensure_field_index(result->type, "child", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_type;
- fields[0].data.x_type = type_entry->data.maybe.child_type;
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_type;
+ fields[0]->data.x_type = type_entry->data.maybe.child_type;
break;
}
@@ -21427,14 +21419,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);
- ConstExprValue *fields = create_const_vals(1);
+ ConstExprValue **fields = alloc_const_vals_ptrs(1);
result->data.x_struct.fields = fields;
// child: ?type
ensure_field_index(result->type, "child", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
- fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
+ fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :
create_const_type(ira->codegen, type_entry->data.any_frame.result_type);
break;
}
@@ -21444,19 +21436,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Enum", nullptr);
- ConstExprValue *fields = create_const_vals(4);
+ ConstExprValue **fields = alloc_const_vals_ptrs(4);
result->data.x_struct.fields = fields;
// layout: ContainerLayout
ensure_field_index(result->type, "layout", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
- bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
+ bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout);
// tag_type: type
ensure_field_index(result->type, "tag_type", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_type;
- fields[1].data.x_type = type_entry->data.enumeration.tag_int_type;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_type;
+ fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type;
// fields: []TypeInfo.EnumField
ensure_field_index(result->type, "fields", 2);
@@ -21472,7 +21464,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
enum_field_array->data.x_array.special = ConstArraySpecialNone;
enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
- init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);
+ init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false);
for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)
{
@@ -21485,7 +21477,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
}
// decls: []TypeInfo.Declaration
ensure_field_index(result->type, "decls", 3);
- if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
+ if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
type_entry->data.enumeration.decls_scope)))
{
return err;
@@ -21528,17 +21520,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
error_val->special = ConstValSpecialStatic;
error_val->type = type_info_error_type;
- ConstExprValue *inner_fields = create_const_vals(2);
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(2);
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
ConstExprValue *name = nullptr;
if (error->cached_error_name_val != nullptr)
name = error->cached_error_name_val;
if (name == nullptr)
name = create_const_str_lit(ira->codegen, &error->name);
- init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true);
- bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value);
+ init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true);
+ bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value);
error_val->data.x_struct.fields = inner_fields;
error_val->parent.id = ConstParentIdArray;
@@ -21554,20 +21546,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr);
- ConstExprValue *fields = create_const_vals(2);
+ ConstExprValue **fields = alloc_const_vals_ptrs(2);
result->data.x_struct.fields = fields;
// error_set: type
ensure_field_index(result->type, "error_set", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ira->codegen->builtin_types.entry_type;
- fields[0].data.x_type = type_entry->data.error_union.err_set_type;
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ira->codegen->builtin_types.entry_type;
+ fields[0]->data.x_type = type_entry->data.error_union.err_set_type;
// payload: type
ensure_field_index(result->type, "payload", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_type;
- fields[1].data.x_type = type_entry->data.error_union.payload_type;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_type;
+ fields[1]->data.x_type = type_entry->data.error_union.payload_type;
break;
}
@@ -21577,18 +21569,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Union", nullptr);
- ConstExprValue *fields = create_const_vals(4);
+ ConstExprValue **fields = alloc_const_vals_ptrs(4);
result->data.x_struct.fields = fields;
// layout: ContainerLayout
ensure_field_index(result->type, "layout", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
- bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
+ bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout);
// tag_type: ?type
ensure_field_index(result->type, "tag_type", 1);
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
AstNode *union_decl_node = type_entry->data.unionation.decl_node;
if (union_decl_node->data.container_decl.auto_enum ||
@@ -21598,9 +21590,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
tag_type->special = ConstValSpecialStatic;
tag_type->type = ira->codegen->builtin_types.entry_type;
tag_type->data.x_type = type_entry->data.unionation.tag_type;
- fields[1].data.x_optional = tag_type;
+ fields[1]->data.x_optional = tag_type;
} else {
- fields[1].data.x_optional = nullptr;
+ fields[1]->data.x_optional = nullptr;
}
// fields: []TypeInfo.UnionField
ensure_field_index(result->type, "fields", 2);
@@ -21616,7 +21608,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
union_field_array->data.x_array.special = ConstArraySpecialNone;
union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
- init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);
+ init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);
ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);
@@ -21627,23 +21619,23 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
union_field_val->special = ConstValSpecialStatic;
union_field_val->type = type_info_union_field_type;
- ConstExprValue *inner_fields = create_const_vals(3);
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type);
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type);
- if (fields[1].data.x_optional == nullptr) {
- inner_fields[1].data.x_optional = nullptr;
+ if (fields[1]->data.x_optional == nullptr) {
+ inner_fields[1]->data.x_optional = nullptr;
} else {
- inner_fields[1].data.x_optional = create_const_vals(1);
- make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type);
+ inner_fields[1]->data.x_optional = create_const_vals(1);
+ make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type);
}
- inner_fields[2].special = ConstValSpecialStatic;
- inner_fields[2].type = ira->codegen->builtin_types.entry_type;
- inner_fields[2].data.x_type = union_field->type_entry;
+ inner_fields[2]->special = ConstValSpecialStatic;
+ inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
+ inner_fields[2]->data.x_type = union_field->type_entry;
ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name);
- init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true);
+ init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
union_field_val->data.x_struct.fields = inner_fields;
union_field_val->parent.id = ConstParentIdArray;
@@ -21652,7 +21644,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
}
// decls: []TypeInfo.Declaration
ensure_field_index(result->type, "decls", 3);
- if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
+ if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
type_entry->data.unionation.decls_scope)))
{
return err;
@@ -21673,14 +21665,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Struct", nullptr);
- ConstExprValue *fields = create_const_vals(3);
+ ConstExprValue **fields = alloc_const_vals_ptrs(3);
result->data.x_struct.fields = fields;
// layout: ContainerLayout
ensure_field_index(result->type, "layout", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
- bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
+ bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout);
// fields: []TypeInfo.StructField
ensure_field_index(result->type, "fields", 1);
@@ -21696,7 +21688,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
struct_field_array->data.x_array.special = ConstArraySpecialNone;
struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
- init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);
+ init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false);
for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];
@@ -21705,9 +21697,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
struct_field_val->special = ConstValSpecialStatic;
struct_field_val->type = type_info_struct_field_type;
- ConstExprValue *inner_fields = create_const_vals(3);
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field);
if (field_type == nullptr)
@@ -21715,21 +21707,21 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
return err;
if (!type_has_bits(struct_field->type_entry)) {
- inner_fields[1].data.x_optional = nullptr;
+ inner_fields[1]->data.x_optional = nullptr;
} else {
size_t byte_offset = struct_field->offset;
- inner_fields[1].data.x_optional = create_const_vals(1);
- inner_fields[1].data.x_optional->special = ConstValSpecialStatic;
- inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
- bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset);
+ inner_fields[1]->data.x_optional = create_const_vals(1);
+ inner_fields[1]->data.x_optional->special = ConstValSpecialStatic;
+ inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
+ bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset);
}
- inner_fields[2].special = ConstValSpecialStatic;
- inner_fields[2].type = ira->codegen->builtin_types.entry_type;
- inner_fields[2].data.x_type = struct_field->type_entry;
+ inner_fields[2]->special = ConstValSpecialStatic;
+ inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
+ inner_fields[2]->data.x_type = struct_field->type_entry;
ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name);
- init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true);
+ init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);
struct_field_val->data.x_struct.fields = inner_fields;
struct_field_val->parent.id = ConstParentIdArray;
@@ -21738,7 +21730,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
}
// decls: []TypeInfo.Declaration
ensure_field_index(result->type, "decls", 2);
- if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2],
+ if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
type_entry->data.structure.decls_scope)))
{
return err;
@@ -21752,38 +21744,38 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Fn", nullptr);
- ConstExprValue *fields = create_const_vals(5);
+ ConstExprValue **fields = alloc_const_vals_ptrs(5);
result->data.x_struct.fields = fields;
// calling_convention: TypeInfo.CallingConvention
ensure_field_index(result->type, "calling_convention", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
- bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
+ fields[0]->special = ConstValSpecialStatic;
+ fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
+ bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
// is_generic: bool
ensure_field_index(result->type, "is_generic", 1);
bool is_generic = type_entry->data.fn.is_generic;
- fields[1].special = ConstValSpecialStatic;
- fields[1].type = ira->codegen->builtin_types.entry_bool;
- fields[1].data.x_bool = is_generic;
+ fields[1]->special = ConstValSpecialStatic;
+ fields[1]->type = ira->codegen->builtin_types.entry_bool;
+ fields[1]->data.x_bool = is_generic;
// is_varargs: bool
ensure_field_index(result->type, "is_var_args", 2);
bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;
- fields[2].special = ConstValSpecialStatic;
- fields[2].type = ira->codegen->builtin_types.entry_bool;
- fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
+ fields[2]->special = ConstValSpecialStatic;
+ fields[2]->type = ira->codegen->builtin_types.entry_bool;
+ fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
// return_type: ?type
ensure_field_index(result->type, "return_type", 3);
- fields[3].special = ConstValSpecialStatic;
- fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
+ fields[3]->special = ConstValSpecialStatic;
+ fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
if (type_entry->data.fn.fn_type_id.return_type == nullptr)
- fields[3].data.x_optional = nullptr;
+ fields[3]->data.x_optional = nullptr;
else {
ConstExprValue *return_type = create_const_vals(1);
return_type->special = ConstValSpecialStatic;
return_type->type = ira->codegen->builtin_types.entry_type;
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
- fields[3].data.x_optional = return_type;
+ fields[3]->data.x_optional = return_type;
}
// args: []TypeInfo.FnArg
ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);
@@ -21799,7 +21791,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
- init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false);
+ init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false);
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
@@ -21811,24 +21803,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
bool arg_is_generic = fn_param_info->type == nullptr;
if (arg_is_generic) assert(is_generic);
- ConstExprValue *inner_fields = create_const_vals(3);
- inner_fields[0].special = ConstValSpecialStatic;
- inner_fields[0].type = ira->codegen->builtin_types.entry_bool;
- inner_fields[0].data.x_bool = arg_is_generic;
- inner_fields[1].special = ConstValSpecialStatic;
- inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
- inner_fields[1].data.x_bool = fn_param_info->is_noalias;
- inner_fields[2].special = ConstValSpecialStatic;
- inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
+ ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
+ inner_fields[0]->special = ConstValSpecialStatic;
+ inner_fields[0]->type = ira->codegen->builtin_types.entry_bool;
+ inner_fields[0]->data.x_bool = arg_is_generic;
+ inner_fields[1]->special = ConstValSpecialStatic;
+ inner_fields[1]->type = ira->codegen->builtin_types.entry_bool;
+ inner_fields[1]->data.x_bool = fn_param_info->is_noalias;
+ inner_fields[2]->special = ConstValSpecialStatic;
+ inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
if (arg_is_generic)
- inner_fields[2].data.x_optional = nullptr;
+ inner_fields[2]->data.x_optional = nullptr;
else {
ConstExprValue *arg_type = create_const_vals(1);
arg_type->special = ConstValSpecialStatic;
arg_type->type = ira->codegen->builtin_types.entry_type;
arg_type->data.x_type = fn_param_info->type;
- inner_fields[2].data.x_optional = arg_type;
+ inner_fields[2]->data.x_optional = arg_type;
}
fn_arg_val->data.x_struct.fields = inner_fields;
@@ -21889,8 +21881,8 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira,
static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)
{
ensure_field_index(struct_value->type, name, field_index);
- assert(struct_value->data.x_struct.fields[field_index].special == ConstValSpecialStatic);
- return &struct_value->data.x_struct.fields[field_index];
+ assert(struct_value->data.x_struct.fields[field_index]->special == ConstValSpecialStatic);
+ return struct_value->data.x_struct.fields[field_index];
}
static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)
@@ -22698,7 +22690,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
if (!val)
return ira->codegen->invalid_instruction;
- ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = val->data.x_struct.fields[slice_len_index];
if (value_is_comptime(len_val)) {
known_len = bigint_as_u64(&len_val->data.x_bigint);
have_known_len = true;
@@ -22765,17 +22757,17 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type);
- result->value.data.x_struct.fields = create_const_vals(2);
+ result->value.data.x_struct.fields = alloc_const_vals_ptrs(2);
- ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index];
- ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_val = result->value.data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
copy_const_val(ptr_val, target_ptr_val, false);
ptr_val->type = dest_ptr_type;
- ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = result->value.data.x_struct.fields[slice_len_index];
len_val->special = ConstValSpecialStatic;
len_val->type = ira->codegen->builtin_types.entry_usize;
- ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *target_len_val = target_val->data.x_struct.fields[slice_len_index];
ZigType *elem_type = src_ptr_type->data.pointer.child_type;
BigInt elem_size_bigint;
bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
@@ -23664,13 +23656,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
return ira->codegen->invalid_instruction;
}
- parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index];
+ parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index];
if (parent_ptr->special == ConstValSpecialUndef) {
ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined"));
return ira->codegen->invalid_instruction;
}
- ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index];
switch (parent_ptr->data.x_ptr.special) {
case ConstPtrSpecialInvalid:
@@ -23742,9 +23734,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
IrInstruction *result = ir_const(ira, &instruction->base, return_type);
ConstExprValue *out_val = &result->value;
- out_val->data.x_struct.fields = create_const_vals(2);
+ out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
- ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
+ ConstExprValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index];
if (array_val) {
size_t index = abs_offset + start_scalar;
@@ -23791,7 +23783,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
zig_panic("TODO");
}
- ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
+ ConstExprValue *len_val = out_val->data.x_struct.fields[slice_len_index];
init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
return result;
@@ -25141,7 +25133,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
if (struct_field->gen_index == SIZE_MAX)
continue;
- ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
+ ConstExprValue *field_val = val->data.x_struct.fields[field_i];
size_t offset = struct_field->offset;
buf_write_value_bytes(codegen, buf + offset, field_val);
}
@@ -25172,7 +25164,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
if (field->gen_index != gen_i)
break;
uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);
- buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]);
+ buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]);
BigInt child_val;
bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian,
false);
@@ -25310,9 +25302,9 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
}
case ContainerLayoutExtern: {
size_t src_field_count = val->type->data.structure.src_field_count;
- val->data.x_struct.fields = create_const_vals(src_field_count);
+ val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
- ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
+ ConstExprValue *field_val = val->data.x_struct.fields[field_i];
field_val->special = ConstValSpecialStatic;
TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
field_val->type = struct_field->type_entry;
@@ -25327,7 +25319,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
}
case ContainerLayoutPacked: {
size_t src_field_count = val->type->data.structure.src_field_count;
- val->data.x_struct.fields = create_const_vals(src_field_count);
+ val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
size_t gen_field_count = val->type->data.structure.gen_field_count;
size_t gen_i = 0;
size_t src_i = 0;
@@ -25349,7 +25341,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
src_assert(field->gen_index != SIZE_MAX, source_node);
if (field->gen_index != gen_i)
break;
- ConstExprValue *field_val = &val->data.x_struct.fields[src_i];
+ ConstExprValue *field_val = val->data.x_struct.fields[src_i];
field_val->special = ConstValSpecialStatic;
field_val->type = field->type_entry;
uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);
From d89f39d71949c85b26f2ccd4071c9445aa8b6d7c Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 13 Nov 2019 20:43:32 -0500
Subject: [PATCH 094/129] rework layout of struct type fields
This removes the remaining hack in the implementation of anonymous
struct literals, and they can now therefore now have greater than 16
fields/elements.
---
src/all_types.hpp | 2 +-
src/analyze.cpp | 93 +++++++++++++++++++++++++------------------
src/analyze.hpp | 3 ++
src/codegen.cpp | 88 ++++++++++++++++++++--------------------
src/dump_analysis.cpp | 6 +--
src/ir.cpp | 84 ++++++++++++++++++--------------------
6 files changed, 143 insertions(+), 133 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index e246016006..a1e9d76be7 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1279,7 +1279,7 @@ struct RootStruct {
struct ZigTypeStruct {
AstNode *decl_node;
- TypeStructField *fields;
+ TypeStructField **fields;
ScopeDecls *decls_scope;
HashMap fields_by_name;
RootStruct *root_struct;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ee95e5d246..0a8b32dca7 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -803,19 +803,19 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
entry->data.structure.is_slice = true;
entry->data.structure.src_field_count = element_count;
entry->data.structure.gen_field_count = element_count;
- entry->data.structure.fields = allocate(element_count);
+ entry->data.structure.fields = alloc_type_struct_fields(element_count);
entry->data.structure.fields_by_name.init(element_count);
- entry->data.structure.fields[slice_ptr_index].name = ptr_field_name;
- entry->data.structure.fields[slice_ptr_index].type_entry = ptr_type;
- entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index;
- entry->data.structure.fields[slice_ptr_index].gen_index = 0;
- entry->data.structure.fields[slice_len_index].name = len_field_name;
- entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize;
- entry->data.structure.fields[slice_len_index].src_index = slice_len_index;
- entry->data.structure.fields[slice_len_index].gen_index = 1;
+ entry->data.structure.fields[slice_ptr_index]->name = ptr_field_name;
+ entry->data.structure.fields[slice_ptr_index]->type_entry = ptr_type;
+ entry->data.structure.fields[slice_ptr_index]->src_index = slice_ptr_index;
+ entry->data.structure.fields[slice_ptr_index]->gen_index = 0;
+ entry->data.structure.fields[slice_len_index]->name = len_field_name;
+ entry->data.structure.fields[slice_len_index]->type_entry = g->builtin_types.entry_usize;
+ entry->data.structure.fields[slice_len_index]->src_index = slice_len_index;
+ entry->data.structure.fields[slice_len_index]->gen_index = 1;
- entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);
- entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);
+ entry->data.structure.fields_by_name.put(ptr_field_name, entry->data.structure.fields[slice_ptr_index]);
+ entry->data.structure.fields_by_name.put(len_field_name, entry->data.structure.fields[slice_len_index]);
switch (type_requires_comptime(g, ptr_type)) {
case ReqCompTimeInvalid:
@@ -828,8 +828,8 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
if (!type_has_bits(ptr_type)) {
entry->data.structure.gen_field_count = 1;
- entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX;
- entry->data.structure.fields[slice_len_index].gen_index = 0;
+ entry->data.structure.fields[slice_ptr_index]->gen_index = SIZE_MAX;
+ entry->data.structure.fields[slice_len_index]->gen_index = 0;
}
ZigType *child_type = ptr_type->data.pointer.child_type;
@@ -1984,12 +1984,12 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
struct_type->data.structure.src_field_count = field_count;
struct_type->data.structure.gen_field_count = 0;
struct_type->data.structure.resolve_status = ResolveStatusSizeKnown;
- struct_type->data.structure.fields = allocate(field_count);
+ struct_type->data.structure.fields = alloc_type_struct_fields(field_count);
struct_type->data.structure.fields_by_name.init(field_count);
size_t abi_align = min_abi_align;
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
field->name = buf_create_from_str(fields[i].name);
field->type_entry = fields[i].ty;
field->src_index = i;
@@ -2009,7 +2009,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
size_t next_offset = 0;
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
if (!type_has_bits(field->type_entry))
continue;
@@ -2018,7 +2018,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
// find the next non-zero-byte field for offset calculations
size_t next_src_field_index = i + 1;
for (; next_src_field_index < field_count; next_src_field_index += 1) {
- if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
+ if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
break;
}
size_t next_abi_align;
@@ -2026,7 +2026,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
next_abi_align = abi_align;
} else {
next_abi_align = max(fields[next_src_field_index].align,
- struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align);
+ struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align);
}
next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);
}
@@ -2109,7 +2109,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
// Calculate offsets
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
if (field->gen_index == SIZE_MAX)
continue;
@@ -2178,12 +2178,12 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
gen_field_index += 1;
size_t next_src_field_index = i + 1;
for (; next_src_field_index < field_count; next_src_field_index += 1) {
- if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) {
+ if (struct_type->data.structure.fields[next_src_field_index]->gen_index != SIZE_MAX) {
break;
}
}
size_t next_align = (next_src_field_index == field_count) ?
- abi_align : struct_type->data.structure.fields[next_src_field_index].align;
+ abi_align : struct_type->data.structure.fields[next_src_field_index]->align;
next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align);
size_in_bits = next_offset * 8;
}
@@ -2206,7 +2206,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
// Resolve types for fields
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
ZigType *field_type = resolve_struct_field_type(g, field);
if (field_type == nullptr) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
@@ -2697,7 +2697,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
struct_type->data.structure.src_field_count = (uint32_t)field_count;
src_assert(struct_type->data.structure.fields == nullptr, decl_node);
- struct_type->data.structure.fields = allocate(field_count);
+ struct_type->data.structure.fields = alloc_type_struct_fields(field_count);
} else if (decl_node->type == NodeTypeContainerInitExpr) {
src_assert(struct_type->data.structure.is_inferred, decl_node);
src_assert(struct_type->data.structure.fields != nullptr, decl_node);
@@ -2711,7 +2711,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
size_t gen_field_index = 0;
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
+ TypeStructField *type_struct_field = struct_type->data.structure.fields[i];
AstNode *field_node;
if (decl_node->type == NodeTypeContainerDecl) {
@@ -2843,7 +2843,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
if (field->gen_index == SIZE_MAX)
continue;
@@ -5506,7 +5506,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
return type_has_one_possible_value(g, type_entry->data.array.child_type);
case ZigTypeIdStruct:
for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
- TypeStructField *field = &type_entry->data.structure.fields[i];
+ TypeStructField *field = type_entry->data.structure.fields[i];
OnePossibleValue opv = (field->type_entry != nullptr) ?
type_has_one_possible_value(g, field->type_entry) :
type_val_resolve_has_one_possible_value(g, field->type_val);
@@ -5902,6 +5902,21 @@ ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count,
return result;
}
+TypeStructField **alloc_type_struct_fields(size_t count) {
+ return realloc_type_struct_fields(nullptr, 0, count);
+}
+
+TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count) {
+ assert(new_count >= old_count);
+
+ size_t new_item_count = new_count - old_count;
+ TypeStructField **result = reallocate(ptr, old_count, new_count, "TypeStructField*");
+ TypeStructField *vals = allocate(new_item_count, "TypeStructField");
+ for (size_t i = old_count; i < new_count; i += 1) {
+ result[i] = &vals[i - old_count];
+ }
+ return result;
+}
static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
@@ -7176,7 +7191,7 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
for (size_t i = 0; i < field_count; i += 1) {
ConstExprValue *field_val = const_val->data.x_struct.fields[i];
- field_val->type = resolve_struct_field_type(g, &wanted_type->data.structure.fields[i]);
+ field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]);
assert(field_val->type);
init_const_undefined(g, field_val);
field_val->parent.id = ConstParentIdStruct;
@@ -7608,7 +7623,7 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size
}
X64CABIClass working_class = X64CABIClass_Unknown;
for (uint32_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
- X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields->type_entry);
+ X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields[0]->type_entry);
if (field_class == X64CABIClass_Unknown)
return X64CABIClass_Unknown;
if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) {
@@ -7740,7 +7755,7 @@ Buf *type_h_name(ZigType *t) {
static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
if (type->data.structure.resolve_status >= wanted_resolve_status) return;
- ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *ptr_type = type->data.structure.fields[slice_ptr_index]->type_entry;
ZigType *child_type = ptr_type->data.pointer.child_type;
ZigType *usize_type = g->builtin_types.entry_usize;
@@ -7762,7 +7777,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
// If the child type is []const T then we need to make sure the type ref
// and debug info is the same as if the child type were []T.
if (is_slice(child_type)) {
- ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(child_ptr_type->id == ZigTypeIdPointer);
if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
@@ -7939,7 +7954,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
// trigger all the recursive get_llvm_type calls
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
ZigType *field_type = field->type_entry;
if (!type_has_bits(field_type))
continue;
@@ -7953,7 +7968,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
// inserting padding bytes where LLVM would do it automatically.
size_t llvm_struct_abi_align = 0;
for (size_t i = 0; i < field_count; i += 1) {
- ZigType *field_type = struct_type->data.structure.fields[i].type_entry;
+ ZigType *field_type = struct_type->data.structure.fields[i]->type_entry;
if (!type_has_bits(field_type))
continue;
LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
@@ -7962,7 +7977,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
}
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
ZigType *field_type = field->type_entry;
if (!type_has_bits(field_type)) {
@@ -8012,23 +8027,23 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
// find the next non-zero-byte field for offset calculations
size_t next_src_field_index = i + 1;
for (; next_src_field_index < field_count; next_src_field_index += 1) {
- if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
+ if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
break;
}
size_t next_abi_align;
if (next_src_field_index == field_count) {
next_abi_align = struct_type->abi_align;
} else {
- if (struct_type->data.structure.fields[next_src_field_index].align == 0) {
- next_abi_align = struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
+ if (struct_type->data.structure.fields[next_src_field_index]->align == 0) {
+ next_abi_align = struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align;
} else {
- next_abi_align = struct_type->data.structure.fields[next_src_field_index].align;
+ next_abi_align = struct_type->data.structure.fields[next_src_field_index]->align;
}
}
size_t llvm_next_abi_align = (next_src_field_index == field_count) ?
llvm_struct_abi_align :
LLVMABIAlignmentOfType(g->target_data_ref,
- get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry));
+ get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index]->type_entry));
size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,
field_type->abi_size, next_abi_align);
@@ -8067,7 +8082,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
ZigLLVMDIType **di_element_types = allocate(debug_field_count);
size_t debug_field_index = 0;
for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
size_t gen_field_index = field->gen_index;
if (gen_field_index == SIZE_MAX) {
continue;
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 0cca75891a..ddfb31c286 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -180,6 +180,9 @@ ConstExprValue *create_const_vals(size_t count);
ConstExprValue **alloc_const_vals_ptrs(size_t count);
ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count);
+TypeStructField **alloc_type_struct_fields(size_t count);
+TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count);
+
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
void expand_undef_struct(CodeGen *g, ConstExprValue *const_val);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index ed9b69e529..a97f5cbd55 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1108,15 +1108,15 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0);
LLVMValueRef address_value = LLVMGetParam(fn_val, 1);
- size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
+ size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, "");
- size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
+ size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");
- ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
- size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
+ ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
+ size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
- size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
+ size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
@@ -2176,16 +2176,16 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block);
LLVMPositionBuilderAtEnd(g->builder, non_null_block);
- size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
- size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
+ size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
+ size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
(unsigned)src_index_field_index, "");
LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
(unsigned)src_addresses_field_index, "");
- ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
- size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
+ ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
+ size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
- size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
+ size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
@@ -3010,21 +3010,21 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
assert(actual_type->id == ZigTypeIdStruct);
assert(actual_type->data.structure.is_slice);
- ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;
+ ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry;
ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
- ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
+ ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry;
ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
- size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index;
- size_t actual_len_index = actual_type->data.structure.fields[slice_len_index].gen_index;
- size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index].gen_index;
- size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index].gen_index;
+ size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index;
+ size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index;
+ size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index;
+ size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
- get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), "");
+ get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), "");
LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
(unsigned)wanted_ptr_index, "");
gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
@@ -3140,9 +3140,9 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex
{
ZigType *actual_type = instruction->operand->value.type;
ZigType *slice_type = instruction->base.value.type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
- size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
- size_t len_index = slice_type->data.structure.fields[slice_len_index].gen_index;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
+ size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
+ size_t len_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
@@ -3766,14 +3766,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
if (safety_check_on) {
- size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index;
+ size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(len_index != SIZE_MAX);
LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);
}
- size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index;
+ size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(ptr_index != SIZE_MAX);
LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");
LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");
@@ -3865,7 +3865,7 @@ static void render_async_spills(CodeGen *g) {
if (instruction->field_index == SIZE_MAX)
continue;
- size_t gen_index = frame_type->data.structure.fields[instruction->field_index].gen_index;
+ size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index;
instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
instruction->name_hint);
}
@@ -4992,10 +4992,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment;
ptr_val = target_val;
} else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) {
- ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry;
align_bytes = get_ptr_align(g, slice_ptr_type);
- size_t ptr_index = target_type->data.structure.fields[slice_ptr_index].gen_index;
+ size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index;
LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, "");
ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, "");
} else {
@@ -5240,13 +5240,13 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
}
if (type_has_bits(array_type)) {
- size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index].gen_index;
+ size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index]->gen_index;
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
}
- size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index].gen_index;
+ size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
@@ -5258,9 +5258,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind);
- size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index;
+ size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(ptr_index != SIZE_MAX);
- size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index;
+ size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(len_index != SIZE_MAX);
LLVMValueRef prev_end = nullptr;
@@ -6568,7 +6568,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);
size_t used_bits = 0;
for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
- TypeStructField *field = &type_entry->data.structure.fields[i];
+ TypeStructField *field = type_entry->data.structure.fields[i];
if (field->gen_index == SIZE_MAX) {
continue;
}
@@ -6647,7 +6647,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
return const_val->global_refs->llvm_value;
}
size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;
- size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index].gen_index;
+ size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index]->gen_index;
LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,
gen_field_index);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type));
@@ -6826,7 +6826,7 @@ check: switch (const_val->special) {
if (type_entry->data.structure.layout == ContainerLayoutPacked) {
size_t src_field_index = 0;
while (src_field_index < src_field_count) {
- TypeStructField *type_struct_field = &type_entry->data.structure.fields[src_field_index];
+ TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index];
if (type_struct_field->gen_index == SIZE_MAX) {
src_field_index += 1;
continue;
@@ -6834,7 +6834,7 @@ check: switch (const_val->special) {
size_t src_field_index_end = src_field_index + 1;
for (; src_field_index_end < src_field_count; src_field_index_end += 1) {
- TypeStructField *it_field = &type_entry->data.structure.fields[src_field_index_end];
+ TypeStructField *it_field = type_entry->data.structure.fields[src_field_index_end];
if (it_field->gen_index != type_struct_field->gen_index)
break;
}
@@ -6853,7 +6853,7 @@ check: switch (const_val->special) {
LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);
size_t used_bits = 0;
for (size_t i = src_field_index; i < src_field_index_end; i += 1) {
- TypeStructField *it_field = &type_entry->data.structure.fields[i];
+ TypeStructField *it_field = type_entry->data.structure.fields[i];
if (it_field->gen_index == SIZE_MAX) {
continue;
}
@@ -6893,7 +6893,7 @@ check: switch (const_val->special) {
}
} else {
for (uint32_t i = 0; i < src_field_count; i += 1) {
- TypeStructField *type_struct_field = &type_entry->data.structure.fields[i];
+ TypeStructField *type_struct_field = type_entry->data.structure.fields[i];
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
@@ -6910,10 +6910,10 @@ check: switch (const_val->special) {
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
size_t end_pad_gen_index = (i + 1 < src_field_count) ?
- type_entry->data.structure.fields[i + 1].gen_index :
+ type_entry->data.structure.fields[i + 1]->gen_index :
type_entry->data.structure.gen_field_count;
size_t next_offset = (i + 1 < src_field_count) ?
- type_entry->data.structure.fields[i + 1].offset : type_entry->abi_size;
+ type_entry->data.structure.fields[i + 1]->offset : type_entry->abi_size;
if (end_pad_gen_index != SIZE_MAX) {
for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index;
gen_i += 1)
@@ -7576,15 +7576,15 @@ static void do_code_gen(CodeGen *g) {
// finishing error return trace setup. we have to do this after all the allocas.
if (have_err_ret_trace_stack) {
ZigType *usize = g->builtin_types.entry_usize;
- size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
+ size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false);
- size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
+ size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
- ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
- size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
+ ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
+ size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
LLVMValueRef zero = LLVMConstNull(usize->llvm_type);
LLVMValueRef indices[] = {zero, zero};
@@ -7593,7 +7593,7 @@ static void do_code_gen(CodeGen *g) {
ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false);
gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type);
- size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
+ size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
}
@@ -9508,7 +9508,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
return;
case ZigTypeIdStruct:
for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
- TypeStructField *field = &type_entry->data.structure.fields[i];
+ TypeStructField *field = type_entry->data.structure.fields[i];
prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
}
gen_h->types_to_declare.append(type_entry);
@@ -9874,7 +9874,7 @@ static void gen_h_file(CodeGen *g) {
if (type_entry->data.structure.layout == ContainerLayoutExtern) {
fprintf(out_h, "struct %s {\n", buf_ptr(type_h_name(type_entry)));
for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
- TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
+ TypeStructField *struct_field = type_entry->data.structure.fields[field_i];
Buf *type_name_buf = buf_alloc();
get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp
index 9703d3e57d..b5fd38e266 100644
--- a/src/dump_analysis.cpp
+++ b/src/dump_analysis.cpp
@@ -268,7 +268,7 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) {
ZigList children = {};
uint64_t sum_from_fields = 0;
for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
+ TypeStructField *field = struct_type->data.structure.fields[i];
children.append(field->type_entry);
sum_from_fields += field->type_entry->abi_size;
}
@@ -747,7 +747,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
if (ty->data.structure.is_slice) {
jw_object_field(jw, "len");
jw_int(jw, 2);
- anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index].type_entry);
+ anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index]->type_entry);
break;
}
@@ -803,7 +803,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
jw_array_elem(jw);
- anal_dump_type_ref(ctx, ty->data.structure.fields[i].type_entry);
+ anal_dump_type_ref(ctx, ty->data.structure.fields[i]->type_entry);
}
jw_end_array(jw);
}
diff --git a/src/ir.cpp b/src/ir.cpp
index d52daacc42..99af2e7861 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -277,7 +277,7 @@ static bool is_slice(ZigType *type) {
static bool slice_is_const(ZigType *type) {
assert(is_slice(type));
- return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
+ return type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
}
// This function returns true when you can change the type of a ConstExprValue and the
@@ -9858,8 +9858,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
// slice const
if (is_slice(wanted_type) && is_slice(actual_type)) {
- ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry;
- ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry;
+ ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
result.id = ConstCastResultIdInvalid;
return result;
@@ -10623,7 +10623,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
ZigType *array_type = cur_type->data.pointer.child_type;
ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ?
prev_type->data.error_union.payload_type : prev_type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
types_match_const_cast_only(ira,
slice_ptr_type->data.pointer.child_type,
@@ -10644,7 +10644,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
ZigType *array_type = prev_type->data.pointer.child_type;
ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ?
cur_type->data.error_union.payload_type : cur_type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
types_match_const_cast_only(ira,
slice_ptr_type->data.pointer.child_type,
@@ -10658,10 +10658,10 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
// [N]T to []T
if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) &&
- (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
+ (prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const ||
cur_type->data.array.len == 0) &&
types_match_const_cast_only(ira,
- prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
+ prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type,
cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
{
convert_to_const_slice = false;
@@ -10670,10 +10670,10 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
// [N]T to []T
if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) &&
- (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
+ (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const ||
prev_type->data.array.len == 0) &&
types_match_const_cast_only(ira,
- cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
+ cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type,
prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
{
prev_inst = cur_inst;
@@ -10978,7 +10978,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
assert(value->value.type->id == ZigTypeIdPointer);
ZigType *array_type = value->value.type->data.pointer.child_type;
assert(is_slice(wanted_type));
- bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
+ bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
IrInstruction *result = ir_const(ira, source_instr, wanted_type);
init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const);
@@ -12775,7 +12775,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
// cast from [N]T to []const T
// TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this
if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) {
- ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(ptr_type->id == ZigTypeIdPointer);
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
@@ -12792,7 +12792,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->id == ZigTypeIdArray)
{
ZigType *ptr_type =
- wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
+ wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(ptr_type->id == ZigTypeIdPointer);
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
@@ -12841,7 +12841,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
{
ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ?
wanted_type->data.error_union.payload_type : wanted_type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(slice_ptr_type->id == ZigTypeIdPointer);
ZigType *array_type = actual_type->data.pointer.child_type;
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
@@ -12895,7 +12895,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->data.pointer.child_type->id == ZigTypeIdArray)
{
ZigType *slice_type = wanted_type->data.error_union.payload_type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(slice_ptr_type->id == ZigTypeIdPointer);
ZigType *array_type = actual_type->data.pointer.child_type;
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
@@ -12972,7 +12972,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->id == ZigTypeIdArray)
{
ZigType *ptr_type =
- wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
+ wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index]->type_entry;
assert(ptr_type->id == ZigTypeIdPointer);
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
@@ -14817,7 +14817,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index;
op1_array_end = op1_array_val->type->data.array.len - 1;
} else if (is_slice(op1_type)) {
- ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry;
child_type = ptr_type->data.pointer.child_type;
ConstExprValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index];
assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
@@ -14850,7 +14850,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;
op2_array_end = op2_array_val->type->data.array.len - 1;
} else if (is_slice(op2_type)) {
- ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry;
op2_type_valid = ptr_type->data.pointer.child_type == child_type;
ConstExprValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index];
assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
@@ -16458,18 +16458,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
uint32_t new_field_count = old_field_count + 1;
isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
- if (new_field_count > 16) {
- // This thing with 16 is a hack to allow this functionality to work without
- // modifying the ConstExprValue layout of structs. That reworking needs to be
- // done, but this hack lets us do it separately, in the future.
- zig_panic("TODO need to rework the layout of ZigTypeStruct. This realloc would have caused invalid pointer references");
- }
- if (isf->inferred_struct_type->data.structure.fields == nullptr) {
- isf->inferred_struct_type->data.structure.fields = allocate(16);
- }
+ isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields(
+ isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count);
- // This reference can't live long, don't keep it around outside this block.
- TypeStructField *field = &isf->inferred_struct_type->data.structure.fields[old_field_count];
+ TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count];
field->name = isf->field_name;
field->type_entry = uncasted_value->value.type;
field->type_val = create_const_type(ira->codegen, field->type_entry);
@@ -17900,7 +17892,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali
static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) {
assert(is_slice(slice_type));
- ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry,
+ ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry,
new_align);
return get_slice_type(g, ptr_type);
}
@@ -17986,7 +17978,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
}
return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);
} else if (is_slice(array_type)) {
- return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry,
+ return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry,
elem_ptr_instruction->ptr_len);
} else if (array_type->id == ZigTypeIdArgTuple) {
ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
@@ -18464,7 +18456,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
ConstExprValue *field_val = struct_val->data.x_struct.fields[i];
field_val->special = ConstValSpecialUndef;
field_val->type = resolve_struct_field_type(ira->codegen,
- &struct_type->data.structure.fields[i]);
+ struct_type->data.structure.fields[i]);
field_val->parent.id = ConstParentIdStruct;
field_val->parent.data.p_struct.struct_val = struct_val;
field_val->parent.data.p_struct.field_index = i;
@@ -20385,7 +20377,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
if (field_assign_nodes[i] != nullptr) continue;
// look for a default field value
- TypeStructField *field = &container_type->data.structure.fields[i];
+ TypeStructField *field = container_type->data.structure.fields[i];
if (field->init_val == nullptr) {
// it's not memoized. time to go analyze it
AstNode *init_node;
@@ -20396,7 +20388,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
}
if (init_node == nullptr) {
ir_add_error_node(ira, instruction->source_node,
- buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
+ buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name)));
any_missing = true;
continue;
}
@@ -21198,7 +21190,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
ZigType *attrs_type;
BuiltinPtrSize size_enum_index;
if (is_slice(ptr_type_entry)) {
- attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;
+ attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry;
size_enum_index = BuiltinPtrSizeSlice;
} else if (ptr_type_entry->id == ZigTypeIdPointer) {
attrs_type = ptr_type_entry;
@@ -21691,7 +21683,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false);
for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
- TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];
+ TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index];
ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];
struct_field_val->special = ConstValSpecialStatic;
@@ -22647,7 +22639,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align)))
return ira->codegen->invalid_instruction;
} else if (is_slice(target->value.type)) {
- ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
src_ptr_const = src_ptr_type->data.pointer.is_const;
src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
@@ -22740,7 +22732,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
}
- ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
uint32_t alignment;
if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
@@ -23548,7 +23540,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
}
}
} else if (is_slice(array_type)) {
- ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;
return_type = get_slice_type(ira->codegen, ptr_type);
} else {
ir_add_error(ira, &instruction->base,
@@ -23857,7 +23849,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr
member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
return ira->codegen->invalid_instruction;
}
- TypeStructField *field = &container_type->data.structure.fields[member_index];
+ TypeStructField *field = container_type->data.structure.fields[member_index];
return ir_const_type(ira, &instruction->base, field->type_entry);
} else if (container_type->id == ZigTypeIdUnion) {
@@ -23899,7 +23891,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr
member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
return ira->codegen->invalid_instruction;
}
- TypeStructField *field = &container_type->data.structure.fields[member_index];
+ TypeStructField *field = container_type->data.structure.fields[member_index];
IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
init_const_str_lit(ira->codegen, &result->value, field->name);
@@ -24885,7 +24877,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id);
result_type = get_optional_type(ira->codegen, fn_type);
} else if (is_slice(target_type)) {
- ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry;
if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes)))
return ira->codegen->invalid_instruction;
ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes);
@@ -25130,7 +25122,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ContainerLayoutExtern: {
size_t src_field_count = val->type->data.structure.src_field_count;
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
- TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
+ TypeStructField *struct_field = val->type->data.structure.fields[field_i];
if (struct_field->gen_index == SIZE_MAX)
continue;
ConstExprValue *field_val = val->data.x_struct.fields[field_i];
@@ -25159,7 +25151,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
bigint_init_unsigned(&big_int, 0);
size_t used_bits = 0;
while (src_i < src_field_count) {
- TypeStructField *field = &val->type->data.structure.fields[src_i];
+ TypeStructField *field = val->type->data.structure.fields[src_i];
assert(field->gen_index != SIZE_MAX);
if (field->gen_index != gen_i)
break;
@@ -25306,7 +25298,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
ConstExprValue *field_val = val->data.x_struct.fields[field_i];
field_val->special = ConstValSpecialStatic;
- TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
+ TypeStructField *struct_field = val->type->data.structure.fields[field_i];
field_val->type = struct_field->type_entry;
if (struct_field->gen_index == SIZE_MAX)
continue;
@@ -25337,7 +25329,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
BigInt big_int;
bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
while (src_i < src_field_count) {
- TypeStructField *field = &val->type->data.structure.fields[src_i];
+ TypeStructField *field = val->type->data.structure.fields[src_i];
src_assert(field->gen_index != SIZE_MAX, source_node);
if (field->gen_index != gen_i)
break;
@@ -25600,7 +25592,7 @@ static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstru
ZigType *elem_type = nullptr;
if (is_slice(target->value.type)) {
- ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;
+ ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
elem_type = slice_ptr_type->data.pointer.child_type;
} else if (target->value.type->id == ZigTypeIdPointer) {
elem_type = target->value.type->data.pointer.child_type;
From b92f42d1f4b91bb343558f72af84ea052da4ac98 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Sat, 12 Oct 2019 12:38:09 +0300
Subject: [PATCH 095/129] implemented container doc comments in stage 2
---
lib/std/zig/ast.zig | 1 -
lib/std/zig/parse.zig | 35 ++++++++++++++++-----
lib/std/zig/parser_test.zig | 56 +++++++++++++++++++++++++++++++++
lib/std/zig/render.zig | 11 +++++++
lib/std/zig/tokenizer.zig | 14 ++++++++-
src-self-hosted/translate_c.zig | 1 -
6 files changed, 108 insertions(+), 10 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index e705aea477..65fbc51606 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -576,7 +576,6 @@ pub const Node = struct {
pub const Root = struct {
base: Node,
- doc_comments: ?*DocComment,
decls: DeclList,
eof_token: TokenIndex,
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 6d5d4b5f2d..d803beeffa 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -58,13 +58,6 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
node.* = Node.Root{
.base = Node{ .id = .Root },
.decls = undefined,
- // TODO: Because zig fmt collapses consecutive comments separated by blank lines into
- // a single multi-line comment, it is currently impossible to have a container-level
- // doc comment and NO doc comment on the first decl. For now, simply
- // ignore the problem and assume that there will be no container-level
- // doc comments.
- // See: https://github.com/ziglang/zig/issues/2288
- .doc_comments = null,
.eof_token = undefined,
};
node.decls = parseContainerMembers(arena, it, tree) catch |err| {
@@ -94,6 +87,11 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
var list = Node.Root.DeclList.init(arena);
while (true) {
+ if (try parseContainerDocComments(arena, it, tree)) |node| {
+ try list.push(node);
+ continue;
+ }
+
const doc_comments = try parseDocComment(arena, it, tree);
if (try parseTestDecl(arena, it, tree)) |node| {
@@ -155,12 +153,35 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
continue;
}
+ // Dangling doc comment
+ if (doc_comments != null) {
+ try tree.errors.push(AstError{
+ .UnattachedDocComment = AstError.UnattachedDocComment{ .token = doc_comments.?.firstToken() },
+ });
+ }
break;
}
return list;
}
+/// Eat a multiline container doc comment
+fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+ var lines = Node.DocComment.LineList.init(arena);
+ while (eatToken(it, .ContainerDocComment)) |line| {
+ try lines.push(line);
+ }
+
+ if (lines.len == 0) return null;
+
+ const node = try arena.create(Node.DocComment);
+ node.* = Node.DocComment{
+ .base = Node{ .id = .DocComment },
+ .lines = lines,
+ };
+ return &node.base;
+}
+
/// TestDecl <- KEYWORD_test STRINGLITERAL Block
fn parseTestDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const test_token = eatToken(it, .Keyword_test) orelse return null;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index cabbe823f6..b429a575a3 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -2556,6 +2556,62 @@ test "zig fmt: comments at several places in struct init" {
);
}
+test "zig fmt: top level doc comments" {
+ try testCanonical(
+ \\//! tld 1
+ \\//! tld 2
+ \\//! tld 3
+ \\
+ \\// comment
+ \\
+ \\/// A doc
+ \\const A = struct {
+ \\ //! A tld 1
+ \\ //! A tld 2
+ \\ //! A tld 3
+ \\};
+ \\
+ \\/// B doc
+ \\const B = struct {
+ \\ //! B tld 1
+ \\ //! B tld 2
+ \\ //! B tld 3
+ \\
+ \\ /// b doc
+ \\ b: u32,
+ \\};
+ \\
+ \\/// C doc
+ \\const C = struct {
+ \\ //! C tld 1
+ \\ //! C tld 2
+ \\ //! C tld 3
+ \\
+ \\ /// c1 doc
+ \\ c1: u32,
+ \\
+ \\ //! C tld 4
+ \\ //! C tld 5
+ \\ //! C tld 6
+ \\
+ \\ /// c2 doc
+ \\ c2: u32,
+ \\};
+ \\
+ );
+ try testCanonical(
+ \\//! Top-level documentation.
+ \\
+ \\/// This is A
+ \\pub const A = usize;
+ \\
+ );
+ try testCanonical(
+ \\//! Nothing here
+ \\
+ );
+}
+
const std = @import("std");
const mem = std.mem;
const warn = std.debug.warn;
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index c824939296..258a5493de 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -299,6 +299,17 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
assert(!decl.requireSemiColon());
try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Newline);
},
+
+ ast.Node.Id.DocComment => {
+ const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl);
+ var it = comment.lines.iterator(0);
+ while (it.next()) |line_token_index| {
+ try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);
+ if (it.peek()) |_| {
+ try stream.writeByteNTimes(' ', indent);
+ }
+ }
+ },
else => unreachable,
}
}
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index ae82cb7602..d3646a6a6b 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -142,6 +142,7 @@ pub const Token = struct {
FloatLiteral,
LineComment,
DocComment,
+ ContainerDocComment,
BracketStarBracket,
BracketStarCBracket,
ShebangLine,
@@ -211,6 +212,7 @@ pub const Token = struct {
.FloatLiteral => "FloatLiteral",
.LineComment => "LineComment",
.DocComment => "DocComment",
+ .ContainerDocComment => "ContainerDocComment",
.ShebangLine => "ShebangLine",
.Bang => "!",
@@ -387,6 +389,7 @@ pub const Tokenizer = struct {
LineComment,
DocCommentStart,
DocComment,
+ ContainerDocComment,
Zero,
IntegerLiteral,
IntegerLiteralWithRadix,
@@ -1076,6 +1079,10 @@ pub const Tokenizer = struct {
'/' => {
state = State.DocCommentStart;
},
+ '!' => {
+ result.id = Token.Id.ContainerDocComment;
+ state = State.ContainerDocComment;
+ },
'\n' => break,
else => {
state = State.LineComment;
@@ -1096,7 +1103,7 @@ pub const Tokenizer = struct {
self.checkLiteralCharacter();
},
},
- State.LineComment, State.DocComment => switch (c) {
+ State.LineComment, State.DocComment, State.ContainerDocComment => switch (c) {
'\n' => break,
else => self.checkLiteralCharacter(),
},
@@ -1234,6 +1241,9 @@ pub const Tokenizer = struct {
State.DocComment, State.DocCommentStart => {
result.id = Token.Id.DocComment;
},
+ State.ContainerDocComment => {
+ result.id = Token.Id.ContainerDocComment;
+ },
State.NumberDot,
State.NumberDotHex,
@@ -1601,6 +1611,8 @@ test "tokenizer - line comment and doc comment" {
testTokenize("/// a", [_]Token.Id{Token.Id.DocComment});
testTokenize("///", [_]Token.Id{Token.Id.DocComment});
testTokenize("////", [_]Token.Id{Token.Id.LineComment});
+ testTokenize("//!", [_]Token.Id{Token.Id.ContainerDocComment});
+ testTokenize("//!!", [_]Token.Id{Token.Id.ContainerDocComment});
}
test "tokenizer - line comment followed by identifier" {
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index f8d3a12343..e919977116 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -174,7 +174,6 @@ pub fn translate(
tree.root_node.* = ast.Node.Root{
.base = ast.Node{ .id = ast.Node.Id.Root },
.decls = ast.Node.Root.DeclList.init(arena),
- .doc_comments = null,
// initialized with the eof token at the end
.eof_token = undefined,
};
From a11da377347aea1085d3b43726040993952122c9 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Thu, 14 Nov 2019 10:20:57 +0100
Subject: [PATCH 096/129] Update discriminant value also for zero-sized unions
Fixes #3681
---
src/codegen.cpp | 33 ++++++++++++++++++++++++---------
test/stage1/behavior/union.zig | 19 +++++++++++++++----
2 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index a97f5cbd55..a288f397fd 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4351,17 +4351,32 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
TypeUnionField *field = instruction->field;
if (!type_has_bits(field->type_entry)) {
- if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
+ ZigType *tag_type = union_type->data.unionation.tag_type;
+ if (!instruction->initializing || !type_has_bits(tag_type))
return nullptr;
+
+ // The field has no bits but we still have to change the discriminant
+ // value here
+ LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
+
+ LLVMTypeRef tag_type_ref = get_llvm_type(g, tag_type);
+ LLVMValueRef tag_field_ptr = nullptr;
+ if (union_type->data.unionation.gen_field_count == 0) {
+ assert(union_type->data.unionation.gen_tag_index == SIZE_MAX);
+ // The whole union is collapsed into the discriminant
+ tag_field_ptr = LLVMBuildBitCast(g->builder, union_ptr,
+ LLVMPointerType(tag_type_ref, 0), "");
+ } else {
+ assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
+ tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
+ union_type->data.unionation.gen_tag_index, "");
}
- if (instruction->initializing) {
- LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
- union_type->data.unionation.gen_tag_index, "");
- LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
- &field->enum_field->value);
- gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
- }
+
+ LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref,
+ &field->enum_field->value);
+ assert(tag_field_ptr != nullptr);
+ gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
+
return nullptr;
}
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index caad1d474f..d7481b21c7 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -110,7 +110,7 @@ fn doTest() void {
}
fn bar(value: Payload) i32 {
- expect(@as(Letter,value) == Letter.A);
+ expect(@as(Letter, value) == Letter.A);
return switch (value) {
Payload.A => |x| return x - 1244,
Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
@@ -208,7 +208,7 @@ test "cast union to tag type of union" {
}
fn testCastUnionToTagType(x: TheUnion) void {
- expect(@as(TheTag,x) == TheTag.B);
+ expect(@as(TheTag, x) == TheTag.B);
}
test "cast tag type of union to union" {
@@ -558,16 +558,27 @@ test "anonymous union literal syntax" {
};
fn doTheTest() void {
- var i: Number = .{.int = 42};
+ var i: Number = .{ .int = 42 };
var f = makeNumber();
expect(i.int == 42);
expect(f.float == 12.34);
}
fn makeNumber() Number {
- return .{.float = 12.34};
+ return .{ .float = 12.34 };
}
};
S.doTheTest();
comptime S.doTheTest();
}
+
+test "update the tag value for zero-sized unions" {
+ const S = union(enum) {
+ U0: void,
+ U1: void,
+ };
+ var x = S{ .U0 = {} };
+ expect(x == .U0);
+ x = S{ .U1 = {} };
+ expect(x == .U1);
+}
From 8c4784f9c181a13eae36d7a1ac57f278cf5fcd72 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Nov 2019 12:38:12 -0500
Subject: [PATCH 097/129] remove no longer correct comment
---
test/standalone/hello_world/hello.zig | 1 -
1 file changed, 1 deletion(-)
diff --git a/test/standalone/hello_world/hello.zig b/test/standalone/hello_world/hello.zig
index 2ae5782328..e3fc5c0e3e 100644
--- a/test/standalone/hello_world/hello.zig
+++ b/test/standalone/hello_world/hello.zig
@@ -1,7 +1,6 @@
const std = @import("std");
pub fn main() !void {
- // If this program is run without stdout attached, exit with an error.
const stdout_file = std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
From 6469900e79369f5ff7539501767842dc6922f887 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Thu, 14 Nov 2019 14:37:08 +1100
Subject: [PATCH 098/129] std: add WSAStartup and WSACleanup for windows
---
lib/std/os/windows.zig | 18 ++++++++++++++++++
lib/std/os/windows/ws2_32.zig | 30 ++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index e8011b7534..e55ac3fe8f 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -608,6 +608,24 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD
return rc;
}
+pub fn WSAStartup(majorVersion: u8, minorVersion: u8) !ws2_32.WSADATA {
+ var wsadata: ws2_32.WSADATA = undefined;
+ return switch (ws2_32.WSAStartup((@as(WORD, minorVersion) << 8) | majorVersion, &wsadata)) {
+ 0 => wsadata,
+ else => |err| unexpectedWSAError(err),
+ };
+}
+
+pub fn WSACleanup() !void {
+ return switch (ws2_32.WSACleanup()) {
+ 0 => {},
+ ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
+ else => |err| return unexpectedWSAError(err),
+ },
+ else => unreachable,
+ };
+}
+
pub fn WSASocketW(
af: i32,
socket_type: i32,
diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig
index 1fe5d87496..d47c5a3d1d 100644
--- a/lib/std/os/windows/ws2_32.zig
+++ b/lib/std/os/windows/ws2_32.zig
@@ -2,6 +2,31 @@ usingnamespace @import("bits.zig");
pub const SOCKET = *@OpaqueType();
pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
+pub const SOCKET_ERROR = -1;
+
+pub const WSADESCRIPTION_LEN = 256;
+pub const WSASYS_STATUS_LEN = 128;
+
+pub const WSADATA = if (usize.bit_count == u64.bit_count)
+ extern struct {
+ wVersion: WORD,
+ wHighVersion: WORD,
+ iMaxSockets: u16,
+ iMaxUdpDg: u16,
+ lpVendorInfo: *u8,
+ szDescription: [WSADESCRIPTION_LEN + 1]u8,
+ szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
+ }
+else
+ extern struct {
+ wVersion: WORD,
+ wHighVersion: WORD,
+ szDescription: [WSADESCRIPTION_LEN + 1]u8,
+ szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
+ iMaxSockets: u16,
+ iMaxUdpDg: u16,
+ lpVendorInfo: *u8,
+ };
pub const MAX_PROTOCOL_CHAIN = 7;
@@ -167,6 +192,11 @@ pub const WSA_QOS_ESDMODEOBJ = 11029;
pub const WSA_QOS_ESHAPERATEOBJ = 11030;
pub const WSA_QOS_RESERVED_PETYPE = 11031;
+pub extern "ws2_32" stdcallcc fn WSAStartup(
+ wVersionRequired: WORD,
+ lpWSAData: *WSADATA,
+) c_int;
+pub extern "ws2_32" stdcallcc fn WSACleanup() c_int;
pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int;
pub extern "ws2_32" stdcallcc fn WSASocketA(
af: c_int,
From 3b8afe31a0c4cc1f6febb5f83566a897f765c98e Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Thu, 14 Nov 2019 15:33:47 +1100
Subject: [PATCH 099/129] std: add NtDeviceIoControlFile definition for windows
---
lib/std/os/windows/ntdll.zig | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig
index 293891123e..d70b1cfefa 100644
--- a/lib/std/os/windows/ntdll.zig
+++ b/lib/std/os/windows/ntdll.zig
@@ -21,6 +21,18 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
EaBuffer: ?*c_void,
EaLength: ULONG,
) NTSTATUS;
+pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
+ FileHandle: HANDLE,
+ Event: ?HANDLE,
+ ApcRoutine: ?*IO_APC_ROUTINE,
+ ApcContext: usize,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ IoControlCode: ULONG,
+ InputBuffer: ?*const c_void,
+ InputBufferLength: ULONG,
+ OutputBuffer: ?PVOID,
+ OutputBufferLength: ULONG,
+) NTSTATUS;
pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS;
pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U(
DosPathName: [*]const u16,
From 431eeb5e20d20584688235078c9f5d730e59a5b9 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Thu, 14 Nov 2019 16:34:13 +1100
Subject: [PATCH 100/129] std: add pieces for WSAIoctl on windows
---
lib/std/os/windows.zig | 29 +++++++++++++++++++++++++
lib/std/os/windows/ws2_32.zig | 41 +++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index e55ac3fe8f..06da223d5c 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -647,6 +647,35 @@ pub fn WSASocketW(
return rc;
}
+pub fn WSAIoctl(
+ s: ws2_32.SOCKET,
+ dwIoControlCode: DWORD,
+ inBuffer: ?[]const u8,
+ outBuffer: []u8,
+ overlapped: ?*ws2_32.WSAOVERLAPPED,
+ completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
+) !DWORD {
+ var bytes: DWORD = undefined;
+ switch (ws2_32.WSAIoctl(
+ s,
+ dwIoControlCode,
+ if (inBuffer) |i| i.ptr else null,
+ if (inBuffer) |i| @intCast(DWORD, i.len) else 0,
+ outBuffer.ptr,
+ @intCast(DWORD, outBuffer.len),
+ &bytes,
+ overlapped,
+ completionRoutine,
+ )) {
+ 0 => {},
+ ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
+ else => |err| return unexpectedWSAError(err),
+ },
+ else => unreachable,
+ }
+ return bytes;
+}
+
const GetModuleFileNameError = error{Unexpected};
pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 {
diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig
index d47c5a3d1d..c34077a9dc 100644
--- a/lib/std/os/windows/ws2_32.zig
+++ b/lib/std/os/windows/ws2_32.zig
@@ -96,6 +96,23 @@ pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10;
pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40;
pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80;
+pub const WSAEVENT = HANDLE;
+
+pub const WSAOVERLAPPED = extern struct {
+ Internal: DWORD,
+ InternalHigh: DWORD,
+ Offset: DWORD,
+ OffsetHigh: DWORD,
+ hEvent: ?WSAEVENT,
+};
+
+pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (
+ dwError: DWORD,
+ cbTransferred: DWORD,
+ lpOverlapped: *WSAOVERLAPPED,
+ dwFlags: DWORD
+) void;
+
pub const WSA_INVALID_HANDLE = 6;
pub const WSA_NOT_ENOUGH_MEMORY = 8;
pub const WSA_INVALID_PARAMETER = 87;
@@ -192,6 +209,19 @@ pub const WSA_QOS_ESDMODEOBJ = 11029;
pub const WSA_QOS_ESHAPERATEOBJ = 11030;
pub const WSA_QOS_RESERVED_PETYPE = 11031;
+
+/// no parameters
+const IOC_VOID = 0x80000000;
+/// copy out parameters
+const IOC_OUT = 0x40000000;
+/// copy in parameters
+const IOC_IN = 0x80000000;
+
+/// The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.
+const IOC_WS2 = 0x08000000;
+
+pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
+
pub extern "ws2_32" stdcallcc fn WSAStartup(
wVersionRequired: WORD,
lpWSAData: *WSADATA,
@@ -214,3 +244,14 @@ pub extern "ws2_32" stdcallcc fn WSASocketW(
g: GROUP,
dwFlags: DWORD,
) SOCKET;
+pub extern "ws2_32" stdcallcc fn WSAIoctl(
+ s: SOCKET,
+ dwIoControlCode: DWORD,
+ lpvInBuffer: ?*const c_void,
+ cbInBuffer: DWORD,
+ lpvOutBuffer: ?LPVOID,
+ cbOutBuffer: DWORD,
+ lpcbBytesReturned: LPDWORD,
+ lpOverlapped: ?*WSAOVERLAPPED,
+ lpCompletionRoutine: ?*WSAOVERLAPPED_COMPLETION_ROUTINE,
+) c_int;
From e509d21f39af726da3c6001b0c20f2c765be07a5 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 15 Nov 2019 14:12:14 +0200
Subject: [PATCH 101/129] implemented container doc comments in stage 1
---
src/all_types.hpp | 1 +
src/parser.cpp | 23 ++++++++++++++++++++++-
src/tokenizer.cpp | 32 ++++++++++++++++++++++++++++++++
src/tokenizer.hpp | 1 +
4 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index a1e9d76be7..c4178cb130 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -968,6 +968,7 @@ struct AstNodeContainerDecl {
AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
ZigList fields;
ZigList decls;
+ Buf doc_comments;
ContainerKind kind;
ContainerLayout layout;
diff --git a/src/parser.cpp b/src/parser.cpp
index 484e145cfa..eef832e32c 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -493,6 +493,7 @@ static AstNode *ast_parse_root(ParseContext *pc) {
node->data.container_decl.layout = ContainerLayoutAuto;
node->data.container_decl.kind = ContainerKindStruct;
node->data.container_decl.is_root = true;
+ node->data.container_decl.doc_comments = members.doc_comments;
return node;
}
@@ -514,6 +515,21 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
return first_doc_token;
}
+static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) {
+ if (buf_len(buf) != 0 && peek_token(pc)->id == TokenIdContainerDocComment) {
+ buf_append_char(buf, '\n');
+ }
+ Token *doc_token = nullptr;
+ while ((doc_token = eat_token_if(pc, TokenIdContainerDocComment))) {
+ if (buf->list.length == 0) {
+ buf_resize(buf, 0);
+ }
+ // chops off '//!' but leaves '\n'
+ buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3,
+ doc_token->end_pos - doc_token->start_pos - 3);
+ }
+}
+
// ContainerMembers
// <- TestDecl ContainerMembers
// / TopLevelComptime ContainerMembers
@@ -523,7 +539,11 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
// /
static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
AstNodeContainerDecl res = {};
+ Buf tld_doc_comment_buf = BUF_INIT;
+ buf_resize(&tld_doc_comment_buf, 0);
for (;;) {
+ ast_parse_container_doc_comments(pc, &tld_doc_comment_buf);
+
AstNode *test_decl = ast_parse_test_decl(pc);
if (test_decl != nullptr) {
res.decls.append(test_decl);
@@ -566,7 +586,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
break;
}
-
+ res.doc_comments = tld_doc_comment_buf;
return res;
}
@@ -2797,6 +2817,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
res->data.container_decl.fields = members.fields;
res->data.container_decl.decls = members.decls;
+ res->data.container_decl.doc_comments = members.doc_comments;
return res;
}
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 8b301f85ac..7ece5ff3fe 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -198,6 +198,7 @@ enum TokenizeState {
TokenizeStateSawSlash,
TokenizeStateSawSlash2,
TokenizeStateSawSlash3,
+ TokenizeStateSawSlashBang,
TokenizeStateSawBackslash,
TokenizeStateSawPercent,
TokenizeStateSawPlus,
@@ -209,6 +210,7 @@ enum TokenizeState {
TokenizeStateSawBar,
TokenizeStateSawBarBar,
TokenizeStateDocComment,
+ TokenizeStateContainerDocComment,
TokenizeStateLineComment,
TokenizeStateLineString,
TokenizeStateLineStringEnd,
@@ -938,6 +940,9 @@ void tokenize(Buf *buf, Tokenization *out) {
case '/':
t.state = TokenizeStateSawSlash3;
break;
+ case '!':
+ t.state = TokenizeStateSawSlashBang;
+ break;
case '\n':
cancel_token(&t);
t.state = TokenizeStateStart;
@@ -965,6 +970,19 @@ void tokenize(Buf *buf, Tokenization *out) {
break;
}
break;
+ case TokenizeStateSawSlashBang:
+ switch (c) {
+ case '\n':
+ set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
+ end_token(&t);
+ t.state = TokenizeStateStart;
+ break;
+ default:
+ set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
+ t.state = TokenizeStateContainerDocComment;
+ break;
+ }
+ break;
case TokenizeStateSawBackslash:
switch (c) {
case '\\':
@@ -1055,6 +1073,17 @@ void tokenize(Buf *buf, Tokenization *out) {
break;
}
break;
+ case TokenizeStateContainerDocComment:
+ switch (c) {
+ case '\n':
+ end_token(&t);
+ t.state = TokenizeStateStart;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ break;
case TokenizeStateSymbolFirstC:
switch (c) {
case '"':
@@ -1545,6 +1574,7 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateSawBarBar:
case TokenizeStateLBracket:
case TokenizeStateDocComment:
+ case TokenizeStateContainerDocComment:
end_token(&t);
break;
case TokenizeStateSawDotDot:
@@ -1559,6 +1589,7 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateLineComment:
case TokenizeStateSawSlash2:
case TokenizeStateSawSlash3:
+ case TokenizeStateSawSlashBang:
break;
}
if (t.state != TokenizeStateError) {
@@ -1606,6 +1637,7 @@ const char * token_name(TokenId id) {
case TokenIdDash: return "-";
case TokenIdDivEq: return "/=";
case TokenIdDocComment: return "DocComment";
+ case TokenIdContainerDocComment: return "ContainerDocComment";
case TokenIdDot: return ".";
case TokenIdDotStar: return ".*";
case TokenIdEllipsis2: return "..";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index ee336123bb..149e58b6a7 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -43,6 +43,7 @@ enum TokenId {
TokenIdDash,
TokenIdDivEq,
TokenIdDocComment,
+ TokenIdContainerDocComment,
TokenIdDot,
TokenIdDotStar,
TokenIdEllipsis2,
From 977b6138817c4b09d6d1e47fa3562d9f9e0268a8 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 15 Nov 2019 15:03:28 +0200
Subject: [PATCH 102/129] add container doc comments to generated docs
---
lib/std/special/docs/index.html | 2 +-
lib/std/special/docs/main.js | 31 +++++++++++++++++++------------
lib/std/zig/ast.zig | 1 -
src/dump_analysis.cpp | 1 +
src/parser.cpp | 8 ++++++--
5 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/lib/std/special/docs/index.html b/lib/std/special/docs/index.html
index 81df8f30f1..b170ad4a14 100644
--- a/lib/std/special/docs/index.html
+++ b/lib/std/special/docs/index.html
@@ -484,7 +484,7 @@
doc comments.
-
+
Errors
diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js
index e0d6cdaf05..1812671227 100644
--- a/lib/std/special/docs/main.js
+++ b/lib/std/special/docs/main.js
@@ -20,7 +20,7 @@
var domListValues = document.getElementById("listValues");
var domFnProto = document.getElementById("fnProto");
var domFnProtoCode = document.getElementById("fnProtoCode");
- var domFnDocs = document.getElementById("fnDocs");
+ var domTldDocs = document.getElementById("tldDocs");
var domSectFnErrors = document.getElementById("sectFnErrors");
var domListFnErrors = document.getElementById("listFnErrors");
var domTableFnErrors = document.getElementById("tableFnErrors");
@@ -34,7 +34,6 @@
var domListSearchResults = document.getElementById("listSearchResults");
var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
var domSectInfo = document.getElementById("sectInfo");
- var domListInfo = document.getElementById("listInfo");
var domTdTarget = document.getElementById("tdTarget");
var domTdZigVer = document.getElementById("tdZigVer");
var domHdrName = document.getElementById("hdrName");
@@ -102,7 +101,7 @@
function render() {
domStatus.classList.add("hidden");
domFnProto.classList.add("hidden");
- domFnDocs.classList.add("hidden");
+ domTldDocs.classList.add("hidden");
domSectPkgs.classList.add("hidden");
domSectTypes.classList.add("hidden");
domSectNamespaces.classList.add("hidden");
@@ -190,11 +189,11 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
+ domTldDocs.innerHTML = markdown(docs);
} else {
- domFnDocs.innerHTML = '
There are no doc comments for this declaration.
';
+ domTldDocs.innerHTML = '
There are no doc comments for this declaration.
';
}
- domFnDocs.classList.remove("hidden");
+ domTldDocs.classList.remove("hidden");
}
function typeIsErrSet(typeIndex) {
@@ -274,8 +273,8 @@
docsSource = protoSrcNode.docs;
}
if (docsSource != null) {
- domFnDocs.innerHTML = markdown(docsSource);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docsSource);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
}
@@ -893,8 +892,8 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
@@ -906,8 +905,8 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
@@ -957,6 +956,14 @@
varsList.sort(byNameProperty);
valsList.sort(byNameProperty);
+ if (container.src != null) {
+ var docs = zigAnalysis.astNodes[container.src].docs;
+ if (docs != null) {
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
+ }
+ }
+
if (typesList.length !== 0) {
resizeDomList(domListTypes, typesList.length, '
');
for (var i = 0; i < typesList.length; i += 1) {
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 65fbc51606..0a7bfe2f56 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -2253,7 +2253,6 @@ pub const Node = struct {
test "iterate" {
var root = Node.Root{
.base = Node{ .id = Node.Id.Root },
- .doc_comments = null,
.decls = Node.Root.DeclList.init(std.debug.global_allocator),
.eof_token = 0,
};
diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp
index b5fd38e266..98bbcc6a42 100644
--- a/src/dump_analysis.cpp
+++ b/src/dump_analysis.cpp
@@ -1088,6 +1088,7 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
break;
case NodeTypeContainerDecl:
field_nodes = &node->data.container_decl.fields;
+ doc_comments_buf = &node->data.container_decl.doc_comments;
break;
default:
break;
diff --git a/src/parser.cpp b/src/parser.cpp
index eef832e32c..04dccb0d2a 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -493,7 +493,9 @@ static AstNode *ast_parse_root(ParseContext *pc) {
node->data.container_decl.layout = ContainerLayoutAuto;
node->data.container_decl.kind = ContainerKindStruct;
node->data.container_decl.is_root = true;
- node->data.container_decl.doc_comments = members.doc_comments;
+ if (buf_len(&members.doc_comments) != 0) {
+ node->data.container_decl.doc_comments = members.doc_comments;
+ }
return node;
}
@@ -2817,7 +2819,9 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
res->data.container_decl.fields = members.fields;
res->data.container_decl.decls = members.decls;
- res->data.container_decl.doc_comments = members.doc_comments;
+ if (buf_len(&members.doc_comments) != 0) {
+ res->data.container_decl.doc_comments = members.doc_comments;
+ }
return res;
}
From 314cb707fce553e51d2ffd5c1ea506fbd1acdf76 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 15 Nov 2019 18:44:29 +0200
Subject: [PATCH 103/129] fix containerdoccomment not handled in docgen.zig
---
doc/docgen.zig | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index b25a903501..502ffda784 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -856,6 +856,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.LineComment,
.DocComment,
+ .ContainerDocComment,
.ShebangLine,
=> {
try out.write("