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 2ad47b5d915d32bf105fad237be3b6f85d4fa7b0..0000000000000000000000000000000000000000 --- 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 ea6257009fe941383f28314ecaee48e64f45b4ce..8ba67e79a233c02d1ba1b254dd1c594524ca3202 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; -- 2.54.0 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 736d81ae584ae2c456e145b4b66fc7182d183ba5..d466f9946dbabb0b2d74ee158985a801c665679a 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 905460a2d0c6ec21e775d2256cb21276b0e218f9..894acd0fc4e09020f39c718bdbf27def36596298 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" { -- 2.54.0 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 894acd0fc4e09020f39c718bdbf27def36596298..8a485ef0fe64e85b0e4f09c48fef90672f5243ec 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" { -- 2.54.0 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 8a485ef0fe64e85b0e4f09c48fef90672f5243ec..c45778cec1f7d41253e3a75af858d76c9939a43d 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(); -- 2.54.0 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 d466f9946dbabb0b2d74ee158985a801c665679a..97c5a5b69557db77a5cf861f358e75ff3cccad04 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 f9149200930d7d2de9f458ec162a30272111e019..293891123e4dfff52dd3fae19b0fea41bea0701e 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 0000000000000000000000000000000000000000..b6945fa000c98ee8da76d5c4f41ba7c8749eef69 --- /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 8ba67e79a233c02d1ba1b254dd1c594524ca3202..78b7cc5b12128c5f1fbbfe34d750ad6741c04ef8 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"); -- 2.54.0 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 5f3b9272d932a9dc860a762113f852b6701cf1bb..26f0142c7c812d212d5c5b1b671b002edbd1e10b 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 b6945fa000c98ee8da76d5c4f41ba7c8749eef69..8571c894236b51cac8780556d9d8950a3a3a3628 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 c45778cec1f7d41253e3a75af858d76c9939a43d..3fd73ab8a38cc5eb6a568ca6b17d19f8f2211df4 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(), -- 2.54.0 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 3fd73ab8a38cc5eb6a568ca6b17d19f8f2211df4..dadf96cef5ccbd7097ad34999d40205c89e2fd6b 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), } } -- 2.54.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 18940c4b80438441801cfec73804cea49b60f9c6..c016f629d1eaf1feec66581a340de5c1a222e658 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; -- 2.54.0 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 61b492c20d25a5d555acf1bdc083931a70ad8f38..cd0c3863ffe2b15c2d76f0abf14f93639856256e 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 e126f103aec3c7f0c70e143e34dc288ff4a1efe0..6cd032806e1e425c399562ec7b642f6d46e94062 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 0702a3e9f571b5e27b915a6b5961bcd4f2fd8046..fbf860965fdd83b88e1d74ec76a15ebcbcb59db9 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); }, } } -- 2.54.0 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 d3d795bf9da26ba6444b71ab191cf8f5cfa0deed..3c860bc59503e5c9275653a190ca04b65fd5eb77 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], -- 2.54.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 8571c894236b51cac8780556d9d8950a3a3a3628..2dc38d2b38e71fab54222ef7be338f2d19490334 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, -- 2.54.0 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 1c9e3e100b99f085b8631753735877e0a7ef025c..6a2405566707c743efc0718e435fdd9f023ecb17 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 8723c7eab667d71b509afa8682b7ef1f39f8bf35..ccdab8d33297988572afc98e39c4ce9d86b148a7 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 bf8f7b8be79905edc8ff53e0eaa8deb3faa0aa87..89248283786c89856c9a4988d2354856a4bd42f3 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 d4687e5adb570d8e40f61c9aa2d17fb62736a9ac..dae759ed84ef9b8a25ffafebf7b220f3eed3952d 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 8176f5cf8304f07ce8e22cc0a468168512e2bbe1..6bc8540b7db848fc66fa73941ef33585b22d9cca 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)); +} -- 2.54.0 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 ff0040860b97c1814ee16b08d30b32b2fdd65210..b8a39d18156a2f21580ee01fa00d5edaba73abea 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 0000000000000000000000000000000000000000..a945608f88a19b30105e1c4bbf4dc2065b8507ce --- /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 0000000000000000000000000000000000000000..b7b281e2492c589b122768a9b94f4203eda85ab4 --- /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 18fb082235be75b7641bd0c5308c7b85f0110f3e..e6c37936b96fa6acd367a13cad680a8524c86089 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 89231b51a8acc3e7eac4167116d4a6d9cf13c5e1..39d1aa2e3e197f1f890688610bb62076ea07b042 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 -- 2.54.0 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 b8a39d18156a2f21580ee01fa00d5edaba73abea..f3c3747e1ef2986b6619d4ebcb8125e08b1a805b 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 0000000000000000000000000000000000000000..a86e2cbba2727063273d185ed58d1607174ba1ad --- /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 0000000000000000000000000000000000000000..a412dc3c7b28f8085bcf35e68ad2ce7a93fe1d8f --- /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 0000000000000000000000000000000000000000..9ecbb2960767074d27a2a0622eb15d4cd63bd3cf --- /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 0000000000000000000000000000000000000000..a2cf6e2eca8b0c9139e420c812304a26ac32aa7d --- /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 0000000000000000000000000000000000000000..492fe450ba42087f47a409bd57229c63dada2a31 --- /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 0000000000000000000000000000000000000000..f5e62734b67241080daec1d58c06b7ec8e9873a6 --- /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 0000000000000000000000000000000000000000..266f2964f96897f04a899ecd1ca44cccd72ed733 --- /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 0000000000000000000000000000000000000000..2f499b50c6d0a9fa03a3f9d8093b424c6776bd7a --- /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 }, + }; +}; -- 2.54.0 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 c66a50802adacea6e21082956efee96916c469e8..d34408dfba2306ba96a104deaa36452a96640454 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 e6c37936b96fa6acd367a13cad680a8524c86089..2358b4f84238c9733f4f83f0ade4c4f6064486cf 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 6ace8e400155d2b6a0126be14a749931a45d0885..3e0fd589e30a66966a1fd402c2299f6a1b14e584 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, -- 2.54.0 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 154c21893a534919d0d747a91bc789ac7d3438a5..7d3ae656fb63b816111782421aad4c66a66d6a79 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 6bc8540b7db848fc66fa73941ef33585b22d9cca..e5650bc3fc036c7beedcc83dbd7dca12f4be00db 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)); +} -- 2.54.0 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 672bd482da0f55cdbf7929565536bc487091cf14..19488ba87317843caeb823df6e3f20cd95bb16c7 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| { -- 2.54.0 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 7d3ae656fb63b816111782421aad4c66a66d6a79..89c41b61cc13b33a76e3ffadc7b966ac02c26f43 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); -- 2.54.0 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 2dc38d2b38e71fab54222ef7be338f2d19490334..8df6dcaa92d3829fa8b39869a50486a8a92e9ef2 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); } -- 2.54.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 5c4d77b69456c88cf6e00eb6ed0c192a9729d7ec..c56d50d7c403b01343fe1b67602b805d34fab990 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(); -- 2.54.0 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 f073bb3df24441611f46e3efa7c9d4b10a19eed4..77dd2cd1aaf474182e9e3507db103095072a64ea 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; } -- 2.54.0 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 d2cd30cc7c7715a58a488ad2be44e03273449fb6..5dbfe5a3389a10ecee9fed1972368f2a6487cdd1 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: -- 2.54.0 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 71e111a61de4442a61ab9fa6b577a5d26911eda7..201aa6b103291ced0022a1cec67332f72625ae36 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 26f0142c7c812d212d5c5b1b671b002edbd1e10b..110f581f5ec0ad723d703e31259beae60401451e 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 efddc9aafb4fa21f079c0408483eb73178072522..72dd2a7196a687b704834cec25daf05767893ded 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 d9f1f4e311fe9ea35ff03111b981c2bbfbc39154..a7dedefb43626b1e471ffe4b6b590293ba2ea0ca 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 dadf96cef5ccbd7097ad34999d40205c89e2fd6b..55b92f51d1a374977949aa3e405d0bdf843f00e3 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 { -- 2.54.0 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 97c5a5b69557db77a5cf861f358e75ff3cccad04..d466f9946dbabb0b2d74ee158985a801c665679a 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 8df6dcaa92d3829fa8b39869a50486a8a92e9ef2..7c0a7a65f84ea880bd0b1915efb0d04ca6292c75 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 { -- 2.54.0 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 55b92f51d1a374977949aa3e405d0bdf843f00e3..f69aae1bec5b4d9a7cdc646b96682284a73cf4c7 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), } } -- 2.54.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 201aa6b103291ced0022a1cec67332f72625ae36..26fa71fe68404bb84a636d0c7f1a6bc790416b0a 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 110f581f5ec0ad723d703e31259beae60401451e..5387bd4b15eba9d93916d7593956d74d55f8eb2a 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 72dd2a7196a687b704834cec25daf05767893ded..2f19ee2a7d0495c06cc0e2dacab3f6dfbbbbe6ea 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 f69aae1bec5b4d9a7cdc646b96682284a73cf4c7..f2f283387596d8b58830e0dd833b73e9002d9818 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 { -- 2.54.0 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 2f19ee2a7d0495c06cc0e2dacab3f6dfbbbbe6ea..d9355490f7be772e628d393050f4d90370451856 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), } } -- 2.54.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 f2f283387596d8b58830e0dd833b73e9002d9818..b374eba3eb3680bad6158c4f6e82838f33b488a9 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 -- 2.54.0 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 474f5b6d09f08e634b51a07a52d789d5297d30dd..8fff358a9303c9db69437657e2b73f7ad5bb6061 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: -- 2.54.0 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 7c0a7a65f84ea880bd0b1915efb0d04ca6292c75..11d3f749de1b50746ec3c85c4bfb43c463d61dea 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; }; -- 2.54.0 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 11d3f749de1b50746ec3c85c4bfb43c463d61dea..036fe160ce56cb593de2c9e9447eb6e307786acb 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; } }; -- 2.54.0 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 | 143 +++++++++++------------ 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, 315 insertions(+), 285 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 f70c7e30c41972050ac66c4593bb4fc8f74f027a..3fd39b26f5412c205ac363ee86f8e9edadd4d859 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 f3cd77ec6feaf2e25f022e31425369b87fc63d10..eaccb1dcfdddd96a0e9c51c8c4d0aa874920afda 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 bd44a2551419aeddfa0471af14e3b19968f2102f..a271b2e86915fc44fbf2fc65e0e544a46d10db06 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 0000000000000000000000000000000000000000..e91e1421c7e3cb83d00c3ae7deb54f3eee42c919 --- /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 550b5a59b1d82aab5bbdbb4142ed423d7dd23f37..4f18df15fd244130306954472fcb180c6b3e3671 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 0000000000000000000000000000000000000000..4f52b8900d576bc10669c818e255b4ad80698b13 --- /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 0000000000000000000000000000000000000000..eb1e52a6184d313ac42cf6bfcd691add475e8667 --- /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 0000000000000000000000000000000000000000..b9be76c3bac61f4444e24edc54a630b8289e395a --- /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 a1db162e20f82b07c667da2a7ffaa89999f3edd2..07fdceec9a1ea845b31624c37a27b39e464e6977 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 0000000000000000000000000000000000000000..98ec087a933f5d1250ee9da0270df90c9c157ea3 --- /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 417c78db6994450851d14453bdecd7672b90168c..c253362ac14e522a821de58644ccf9d0bb68c926 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 0000000000000000000000000000000000000000..22963b08c33e5c09275f605c80f5cb7db660ab42 --- /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 0000000000000000000000000000000000000000..7c70a01fc4ac1c9281c6ad6476c61d959ddb2889 --- /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 5387bd4b15eba9d93916d7593956d74d55f8eb2a..9b44e2edc3b2dc85b2d7fa97be5b4636c3ad8c8b 100644 --- a/lib/std/mutex.zig +++ b/lib/std/mutex.zig @@ -37,80 +37,83 @@ pub const Mutex = if (builtin.single_threaded) return Held{ .mutex = self }; } } -else struct { - state: u32, // TODO: make this an enum - parker: ThreadParker, - - 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; - - pub fn init() Mutex { - return Mutex{ - .state = Unlocked, - .parker = ThreadParker.init(), +else + struct { + state: u32, // TODO: make this an enum + parker: ThreadParker, + + 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; + + 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 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 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) + 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 }; - state = Sleeping; - self.parker.park(&self.state, Sleeping); + + 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() 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); + } } - } -}; + }; const TestContext = struct { mutex: *Mutex, diff --git a/lib/std/os.zig b/lib/std/os.zig index cf97a5ee4578265e08c1897ee170ebafa19ba816..6803006bf175e949cf7aa12708eba66d5ade94c4 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 6d6163b8fa3f29ee8c61722445ac1648f27586f5..7dd968e473991e1d2b2fcabeeb402a0d1c2f810a 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 ca7f66366193ad08d40685eb2c15fea3762c808d..335f296dd68c542c5c57da84f69ccec66e4cb31e 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 d1b65707f45a8a2eac8d39d788ce5a5d9c0c372b..87d89df7d8f823daa3f288157bd9dcb539237c32 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 b0506ad0e11a36e879b73a902510ff57f5789544..a7a2536133b3f40f141133cb7d563fc251b16ff8 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 0cf30920e4f0d0d5de247e6fc37fa4cee7e445c8..0fd528b0c0da82d447bb5731d59225431b8f10ab 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 f93bbbf10643d6ec14bc64684015921c0840b83d..497c4a03445b307de2412f67d8b6a92e6d2a9b0f 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 036fe160ce56cb593de2c9e9447eb6e307786acb..4ba0100b9ed7bb6eeb0d4337ab9a739fb41c805d 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 b374eba3eb3680bad6158c4f6e82838f33b488a9..3bed3d3891fec6c9ba060d5ff892488d73660bca 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 { -- 2.54.0 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 42f14539f3d5f7f48bb20d2a05cbfebbac17991a..8ba2bfc50351a0c78045d25661746d57d48eadd4 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 89c41b61cc13b33a76e3ffadc7b966ac02c26f43..4861def16cac5302665c4bf82dd671fec292d0f0 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 dae759ed84ef9b8a25ffafebf7b220f3eed3952d..ae5987d03015e1026abd416bd99532abbd2f8072 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 aa53b11e03f176cf137497951696c1f416f5e7d9..85b58faefc177a0dc531e99ee7dc530e49218e82 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); -- 2.54.0 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 ca78bdf1979715272bd1addcf223d79dc83acbb9..7cd6d1b7bb113e162bd13647451424d53028f42a 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 a57839ec3b83196fd03fbee798dbee9c3c130d03..59fd2a10e517ff7fa181148fc4324d3b8878a6e9 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 2bc11ba3f25bec17522c536ffc9f6b2ce3e69e5c..71f52bfd17473b1282eb3e5c38bb4f056b2f5dfe 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 dbc011bed3a86731757791d710ba231c4ea580c7..173355eb3b7f29ab53eb13989f1388c38c7fedc6 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 dd288adbf1607b02c31fbc0ce19fb83c1e4ed4b9..664191eb7773b632b0c50ff2fc8e341f5e76a4f3 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 c36c5e9dfa0f367514d6f4de6df8a020b5759c74..2734e7d54fb715255106115d1450074912b17cf6 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 eaccb1dcfdddd96a0e9c51c8c4d0aa874920afda..4d40e8aee5368eab54661b37f2c2ae98c0f96bc8 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 5fae9447a99562d868da92dd78a65afa678fea9e..e6d81aeb4fd5cfd9c9cc60555accb39c6529673f 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 4e7a4f2e134d4428cef5f77d0f24803d937efa4d..ddccd0b1b326349f94bfdb7409232807a050ff63 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 6bb2764b92bf61242aa83502c5bad61d83388a0b..d6b1e497245f3bd57ef6f14b85cf03a25acd4e1a 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 0d997e0d142c949dceb44e8e8fdd51ea17e61973..d5d03f2bfa214e9d39414ac34a49978452dd19c5 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 0a0a5056c667405e2ca13249f34caecf62557ccd..0d18afd705ca9f2f2aafb1f791f35ae2d1615043 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 ddbb39a9df2ac0674fedd8dae6d7f5784b3b65c9..db6150699d7e61759397c3e53dba02661589c41f 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 bd0b33e5860b0f85518a0fe1f5ce3ec3210208c2..78881ba049b53170b3c01841fe76176d658b613e 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 c5160a1f376fed2264d0a3326dcc10e242695acd..c17ef2daf775e5085ac503927a9961e798e6be09 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 b40a39d5797ed969f390d18325348a4eaad27eb9..77698176bd117b1af7cf5b73ee1e0fdf1258e409 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 659e7a254f21f8d2ddbc9ffe9de814dd539d6ba6..d417ef07e25131ffa5868b762b7497cd04a11c04 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 7f9220c3f4eebb3d0a1185a1497888e0d66bfda9..223d65f8f42d333eb3eaad96be2b08517354b121 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 cd0c3863ffe2b15c2d76f0abf14f93639856256e..02305086cc5ea6904474d0d9c6d001b25db5f6ba 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 cb59c5b0d2143929c491c84554b66874a949495a..ee1d1ac9eec60e509d45bc2fe1c4ac0bdc4b274c 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 341378801970212b5d90d0ab8f55eb26271dea0a..0e8792ca9099bff4bf0c2673b7e3d6f34cb1dce4 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 b3aea3e5c62e7775c257ad8b7935893c19df9bfc..3bb4054bfe414e79c0cf8607b6a9695fce843521 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 d86bcbaed57b1af821bb20dfa1063cf086dbc42d..1035a51b81beaf8573634dcd709fe956687eec53 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 b47dda34def57bc9cf16d53a5c9b5abf0bdb55fd..73f9b2dee7fd12fd1fdc50207e2a8713386daf47 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 a835195fc7025142a22110e374a97ddc2112845c..e697b7d42fa2f62bc7a3be13de6948290af6b62b 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 9a35e27c21909d9bb933f2b9f12728bdc1d36de4..aa3ac6d45870325dfcd8788a5545cc490b4b29ff 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 431b89bebf16062dd30010191a8513531a1f58e7..117e49369a7429edbc12239188efafef4ca2b289 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 3a4abcbcd91bfe5c3e63b1a09f3aeb82ca648012..1df434116c4d460599944a86d32a8c33e1a8c81b 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 43e5b7a385cc30e657ded4b253fa3c2a99a85a8f..d31ee17105ed26acfb2c91e8c74c7874528e7a2f 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 cdcaf55610b22d80dfec90ce6aca2d932e1c8f4d..6176ded81dc0a9bf889acf5e2ed146226ba1f08f 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 a0c8f91338ce4ad29b5204dd80ae00664de209f6..f70190d31197bcb54b2cdf5da815299a2382005d 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 3d67ba685b6201acca2e9024cc5423e7fa0dd726..c3a9184fa42966dfc021722615b98edf6a9c2b7f 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 7c872de5ca403c20b0d83a7510b721ca54739fa0..aae3b60831acfde8f9266a544de67a087e5d9e5c 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 ccdab8d33297988572afc98e39c4ce9d86b148a7..c9e9e3533d6ef892d42f56fe1ffd7a2a852778df 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 7ee035ce80cebc09c66dfb6ce37f38d8c3f11d04..a860186e474161a15df42cc8642b4d13f87c6dbb 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 95280b888f0f067993ef8dc5983723009e3c619c..4fcee6ec143d8d1bc64ba981110fe51f6e1e8800 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 42c40337a80f895aa5a2172fb488b2745593bbcd..c0cd6e48a15954f9d0dfec1329fe94f861321108 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 e93b74169bc570e7ea035a92f734932e9434698a..1fa7fc594c87be289b1999e37a875d65a19eebd2 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 6cd032806e1e425c399562ec7b642f6d46e94062..ecf0bf822bdcca12ab8390c462f9d67c146c1e30 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 9b56d0b8ce62a5f6ae96bdd8ae84582b2df20c21..7c672c7ae89fd56285f4994c17531b1aeee79b22 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 de07da8fe0cd292c6272c505d62faeb1650902d1..94b6fc3f8f4a04cb24bf752a007f1372efdb6bd6 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 503c0433fc35fac0a5cea135972eac22a666faf0..065e4d39de9d90e8a53000d970006409a53f4ebe 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 2db9f86ff1051a9ed293c3cff942ead872111c3b..d354f8ceed7e57fdcdb4f9c63567a537114c4b9b 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 0fb51d1b4395ef0c545a64717f79e97aea501e70..b915df317127b1e1b5a29a9964c8627c6c8c5250 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 5790eba8cfa50403721909f90a290c8889586d7f..ea639872be52cc0bb8178e3bbc5c535f52520adf 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 8ba29be761aefe917ea8225b18effcc5157d5fec..ae588f4fb825a1153a3d3abbd5e9d8de72de445a 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 bfdc768375d77cd739305a8378353a1adbf1c32f..fa2424de07a10124afb787b55cc683f72a8aa745 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 5241e31323ea4e3b14e9d55e9392897b5dafffc4..c9e205a495904557384c055179cac4d2fe87e848 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 5f86093a6d6704f3a14549cba6800d4be55f4c41..b5a2238621fc4cc69fcc301e0d57a8266c71bdde 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 d6f810793f4df1f4704b329b526b655ee5436d1d..d74ac86148390f99686c1e7dad6dce055f2a1bab 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 36f4c28e29c364f9c42cdac0651bed9aa2109d7c..7e17f422bb583636fd265104d4fde4f473cd0640 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 6895e8a76976307a6adfedd23dfebc87612d6285..fc7f4e9ea8a092a57bb0c011b037f36ca3f496db 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 e4d90c395e67dc7007893c2e529e58b2e69c64db..e874da0bb941a004c09af718a8650b195326f7fc 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 5261a25f80c1f6cc0ef76d7fc7febed8864312cd..68e13e41bfcbb15fefcdf8ffc26b50410d81b9f6 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 75c5c15ec153b183ea701e2ab76d2482a9507030..62bedeaa49e8119ff25d75584fd9af0a79b93e0a 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 718bbcd47633254e984e0ad8a5490f11a058e937..e1297b11bc709466dcbd0ddd1e76b55532c3b1c8 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 57f6620d77ca3ab6d7883948e10d2dd7a94f576b..f3e51e542ed194fcb84145b953553a490f5c41e1 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 5e347f86f6caf7c204344966e8ae2a16d883d46c..871fa38449ad83deb2269d06e16ab5200bb3b3a5 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 c00098a5a72ed5b3c13a75082f8c01af1c6d06ca..590f36bb18d9329fe346ee1d731b68fb92c40db4 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 6469f388352fdb709164ad1e9ed03adeb944f20c..e0eadd0d00421c66e481c73e6b30d8a784835fbd 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 e5ff2b1fc1a74b53d36e474bc243319a5f1dcc75..f2cabe8f029c7be107019b2f56134de7eda67305 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 19c306fa2a3b001f70b29856ba09699d86ec75b6..014593cda5f95696a0a1a0b7222e3f674cdd4e69 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 2759cd64923d96de294858d56e34eaa6972bfe7f..93705ae6a4aa15f0ef65cff6e7985619b3366124 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 c15da1495e86201f359d3dba2b8ca734ca948cd2..59116014b3ed37f46628d3f0a706c3f0696aceb1 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 fe4158a6dd13fa311184cf6bd1e8c35fdd74ef7a..8d23bb09a0edb09d5adf12b61d96549906ee7418 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 99eba668f9b4ead5b888defc476b0d797951802c..3d23a0f3bf2970adf0bdfcb4f1de40be8acc2013 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 37934f4cf44e1ef9d5845758ca2f89a54805f975..d691068be56e3b5562202be934934562caff05cf 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 cf8cd2e1c25cffc74e104b895b804cae31dbb9b0..ac865f0d0c60ba7a8430bb93de3c6729f3701560 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 f8611ef80528b011e3375c17200dd755b78987c5..01d919d41776319b3e3a0c035a0614f4318bc69d 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 c5d4c9ff2573218bfc548485dc71d1cfa398e966..362e44a869a8065630578edaee62953fcd314dc5 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 77f3639fd296403086a46030d6f0f68ca4fcd320..84dbcf939d79fb70c89df8da8de9c0f2595810f8 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 9b0bc3ac52c794c5ee7254cc7162a4761f0cdeb3..a4b3fef26b56d674de5707514ef254cd95d3a17f 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 bae6deb53698a9aa78afa564f05044bfecad1edf..047e089a91a7785105b59129b5f912d67c06435d 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 88450a7ffdd1623abc4dc6d842419017c2d89a4f..47b214d6cf5232743a3284211d9d8907b9c34ec2 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 92194d4c7599fd604ab3616f56fdd3531afe302d..6567cbc9ed9d69a42dcf81401531feb829ccf2da 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 0b80a46ce5b6abf5be9788cd5250452afca84e7f..adedbf2e940e6adbc3a7e2fb1e2919b356fa6855 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 d5716d621ca33c73a25b3f234e6ad32ca0e3c588..e3c457ade59b056c4186fcd06d30a4c1b4b9446d 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 e5c5909292fffa7dbcb355b0d52138b6a5f2f14f..f20753f2ff8f42b2ab6ac56fffd3626b8632c5dd 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 ee07b4f85e118829737334581dcd0b70a97f5c75..3baa730123ba44672a8271ddf283f10a346f8bff 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 73ee65ea6f0ec5c51581639849f67de4c441ee34..c9718e3ce2149c5998c170d33e858bc844c0bed4 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 30af5915d40fa98680bf3a09ce4d68b7431beddc..1b74c34edaff97a1383f0b45b1196353cb2513be 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 049c85df12d50413b91b8d965d3e80bdc0571fd1..1a027cf403f34f2e48ee4824d9fb8a4c8f1aa654 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 48d26d091e416566eab332bd72ff5ba3808a9151..ced5f58bcc03fb46af24a1791c5452adac7a5bdc 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 219bcd49146fd7fa0383f1de21aec5dbd5650865..56a842345c269b1c3b06b65e4852308daac454fc 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 89248283786c89856c9a4988d2354856a4bd42f3..19e9634d5a6165d714b507cb04ab276486c3d7a6 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 b29eb6020106470f35569ffa320ed3cfaa50cd6a..ded5aa4b1a0899d7a955dc060192e194ca7c482b 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 43be7f3dfb4290caae7da5e3236d958374cea339..8857b4aa9e1dff0b3bd597b36644f498d8bdd3e0 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 95036707b6d19305a2da5dc293e8ededead40f4c..fcb64d029a1366a474bccefae68c90c09c2cbdd0 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 6803006bf175e949cf7aa12708eba66d5ade94c4..c0f02c9a0bcbf53bf9a22c1078adaf969b838682 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 87d89df7d8f823daa3f288157bd9dcb539237c32..042857b7501d147d5c97c0112674da4e73fd52ff 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 0fd528b0c0da82d447bb5731d59225431b8f10ab..e101337c3ad586b20d5377530707656d66aca0c8 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 a7dedefb43626b1e471ffe4b6b590293ba2ea0ca..618a21f4568ccc129e9e7490ad8ea4e6a28c33ea 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 c7371fc28d6d2ca003e9eea0dc0da14fc375b961..c457e10bebf40b4e0cefc1bf3cbf584c387ab261 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 b8d8a1636bb4abd329056e59d3ce628eb50bc09f..ac2bb3bfdfdfb823dd221d68a2f2c328bf7401b5 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 791bec6a1282178ad17683fae2c1d2055d48d4c1..60408c1e84344a1aae79f75c00f7c6c981846cdf 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 64facede89915a0e819708801596849e95cf4962..b7c59a9039a6f1ed99f01140e7baaaa1ad914afb 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 86d54bfbf8885294fa169f73446ec4c057050748..d3e00b8673954094b849c2046a4e40c3c58ea734 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 e0e4687c9fb815c5dbabf39c765b49241e1d17e0..d037b3c6aee2fe87af6bd34c5c014b2073996873 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 1d615483969a0c1464126c57e0e3d495e4ce6f8b..741f108eea258e17c455f12ee95e055eb4749f9c 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 c8c99c6a59179390e96e2aeb18e5474c9354618d..43425129416bb06533cc7b376094c5cf25a31628 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 9d111d98ae3bd63093a767a99b7cd93ff280b994..190b7ffe08893a04e013ae77950eb4567c5bc5bd 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 5cbab2d33be5aab321214277355afcef88bb2b24..c22d701bf2f1748dbcf42c0fb2ddf0007270832e 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 7a2b2c6b6b0ded59816da570f04ba6b00388fbc6..8e4a9b5d6a9cf7f2c23b69faad8890c46f2fb16f 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 a081e03c5fc4355047571fa345a1889f5c58553f..bf54f6937f3ed3e1508d7cb227ff37919005a7a9 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 e14a60e2aecbeca653e71d1d2ec5430d954c8429..2cd1583f637a7c834372048a3cde961f0778586c 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 995248415be1c35fc8cd60f2e431286eb820199e..c29d3eeb2b38a7dc4dee12474aedf3570c902f23 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 3bbbde782e3e3ab8cfe669034e55e8ef582b7ccb..7db153575560ba0fa79b55e4284c3469e4b871be 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 378a92992fdda5f506c0f67b994403675a355e4e..c5758dd6e7ff690fcdf3d9c763999476af26e9e2 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 473d2d4e330d562c93e84da165e1c83b28f608b2..145c8897d5eae46078ac2a4bb34bfb33d0df5022 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 0a09f616e945b18686fb2f31b53ab733f2ba3827..1fbb618b1e10a9b5af194974f8d577ec1dc3dd83 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 1654c1f08bb1b0510738b7f28432bc660027e558..e3dd1819c35d1bd28ea8c5406f92bd951c6b44ff 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 099b737976380c94bab03376292c15282dca436e..af991b37e923cfbc4b363dc0654ed4e6297ba756 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 f97e2474be369942733b98ade6d1ec53bccce4fc..95dc8786302610dde75888a4bcbf8998376de5b5 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 e99e0bb3dd44a8288aab0109de18d3fa2eda2bc2..4468da4fbedaa626ed94e2235cd695f709388c3f 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 05e59745582e9aeeef5e4381e0388f6a44ac900a..e9730184551905b1bac835743fef3b2d0019a706 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 072feaec675ec92d17431fc48eaf1b3dfc577977..9937b09497e96cbffc3466306c3d8c5d4c3a0f3f 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 447653fbe1ccf2682cb79cb0fc576a258e4b9137..4ee2eed36cfa2bff63c4943758b3c0db695bb52e 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 e1c1babae7fee43c79cc1e6a44cbd0cf21fc271d..8601cfae030c2f3e47aac8cd076cbbf14c23d5f0 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 e10667843fe8f9883d2cb5badaf585f840e382cd..3bdc5164e220163156bd5c2e0177daca83bc73f8 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 6f8111c8fbc7bf39577eac05192849dfe3dc0176..aa2faae90119b0599c7480c0cb77d8021c469f37 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 1ba8a4f87d68dc9ff20a612360cc40ae0f37e11a..e06d641824e88ca69d57677839766aa33a957491 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 fa5ff72e8f21700224449ec86b26dcd98a1a917b..da53468c7da8d850317314333c110d53e02f26ff 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 4ab2c04cd1bfc693d333840e194ba79a3637a5d7..b0c9049ba85742ad50279f7280daf8d98ba5d83b 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 fd31798cc2f9e8c5bd28826ed509997f2d7b66f5..426ee1d58acf41b9dbb48ce26fe21b64d984953a 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 a876e17263399eb6909f36852c2cdb45282cd9b1..d5f7b3898d2341d92041572e9df4733de21dccca 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 bfd715425c50a7af721af59261512fc220af5e19..02844946a7845be17d567565af0d991cb1922a71 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 30406fea22d69b956a1346cb5814a527b81f3aff..69d8309de0715a6e058305ab23e461894d31081c 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 7136f7cfe865008ea0bad1eb85637b0d7ebdc40e..cecfeda557adc20cd95d167d97be4031dd2804fc 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 7c6354764263f88771b7501c554afba7d4d1408a..b45001e18eef939eddac0959530d09f120bfc126 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 da769089df02f950b5d7f212974327518731bcad..c6f66239950b5a70af62f984f505c1ce36834e81 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 02dba7fd61341dc484f548eed4e89b934b0f4419..b36c5beb4eb678a404265c3ae3224d4bb5cd017d 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 55a113b3689b619ec67ccb1dfd97ebd73de6d415..977d3c16c9899dc5a588d095e40b258bf53e57bb 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 e7096369122ad0026d4180d9f47b83796cfc6949..286567629a3f7afe45fb746b4ee95915ab672344 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 833e4779ddc634eb775b4396a6f4573be56e00c0..62a9bbfecfb8c4a5832f34083cbd11ef11309fbc 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 7e05a3ebf7f39d5876281cb0ee81f0fd81b2b655..714681834d26bd60b193c46cfddb5a2602980021 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 42ef6df7e449c88e7136c4ddeff4788f0dc7ae74..1e83674598a097ed6ec1a3c67821efa3142c5500 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 f397d130ef71bab040d46c45eed660a1253737cc..0c02bfff1f5057d5c27c7303eea7a2b036f266e0 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 b05282e29376f3c7fe0e677dab52d89a552e8377..aac22e36d0125a231501d07cd22d3183936a6832 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 efeb4c267257bad46fdebd9e1a7f09a5d3a1778a..d744009aeaa708d43772c0166ed01ff056855d82 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 2cd38c73084bee3b85003c00f9e1ded0527d3245..5d3a201058b6feca46721966575e36af30b26d21 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 1b42b267d9609708e49fb74b418a8f706c36d482..e450ad9a48108d68f3d3799b5d11fb66bd719797 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 eddcf92efd67584aaa61dc53ff19d672f6cbfb03..f92942e0347ab3134c138a9854238fac141924f9 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 51d40ad26f627dd1227da67297c233cd5af52f45..11ee0b49a4da4931439a3045c457d40d3d2b7a52 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 1c0c0fc043375eb9e0807e7f2ca4246c7a49e8b9..57dc38532174095c9fda6f4cc028bf5bbc3766d0 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 7700777c16646b507ccaf60dfb5de3a9b099672d..3efc5a9ac64d45248c5e8181eef1f67ce120a688 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 82e9ef32536de53192ef92a797b345c52295d5c1..21c7fd1f974599e547ddc0d84f1f278509710d79 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 7575c770440fd3250fd4b59631cfb60dbc969203..803d60e8fa827988847d5ab62d953c0b9669e80a 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 ccde8e3e6cf813b19b0b7cb57f7435312910b755..ad6ad43808058eec06ef0a45bde65a079d9a3f4f 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 00144a8839b8a89df8eadbb6bdc5cb55a9e967a5..f94a13e04f9b8ead3b4c305e50bb5392755fbdd3 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 799b1f575d7de2fe3bf9652da7009ad1b811bbe7..f3b74b85d9080153abcb4df3a3f61eff3eb9e2f8 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 b71a503c1dbf9a9c39a44cc84217f5ff40b25359..c4be085d62b111ed2cb8d93a7c14c3e057aee681 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 bedcbcd1de202460c8a6ac8d0dd98dfb2148fbed..fe02786e15bd1dc918497d7ca570989907e4b588 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 e4c4aa38a72f88a9d637e4b02938cc243e5f36a8..d231c0d41655e0dcb687d09b40e4ac19ee87ff23 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 eccf7efb7e4c04f4844e828682e467f72258483b..d1dd837ddc2ba4cf64250c4574002cd6d157448e 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 c3066153f31d0cbbf3a0414aa21e5465cc8637f4..96fb7b3bdd32c02b8adf20917bcd452895389f9c 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 d297312b4eb430d54aa41c48c62b2c858cf8479f..d84ef473474a47385ab776ad9a16617f3f5d13fa 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 fbfb1afd1e10124242ac4b7f35c44748618c0ca8..4e1535405501e36083899feda03eb0fe764e4fef 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 04dbb908e29609e99b546e3fbc12208dd866063d..716c999577931083b52cae1407177ddb72f13801 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 2e961471665ec5c89a048a80406eb2d02dd59162..5509f5f9dd2b227e3d005a00d325c7b560046c66 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 0d7f79dfa2ab293ac9521b12bf4609f6acc40d91..a8ebbbd8a4002b6ed75b58678e5e2ab759c61dbc 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 acae0b64c79c1d5c4251b8ed75f6691862f628c6..a6bdff4a023db6915ffea1d6c84b0e1ac526e152 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 28bd287c8a55501fba71912d1cbcc2830e770b28..28497ad6f1aea13ff7f6069993c05b5e153d7ba8 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 996cfc29e4e2bd1b832608916223ed7d9fdec2b5..81ba8e941cd9d7bc658c6a03394a7adfeb2c2de7 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 19488ba87317843caeb823df6e3f20cd95bb16c7..b401b25aded199a7cf75bf835e3718bdb75c9d12 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 cbc74c8be27fef5db7c1cf875b48bd3e6e82cf3a..4c0cc236322f3a0f96b7644582790da58cce9e2d 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 6cdc5d1cda0c2f658040e4f28b9cd401003d7c4d..c7f286ce3f969ea5653200ac4853297e3247282a 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 95d2dbac93beaac5c741e429fd6481934fddd340..49b757451b27d0aa42a09e3f1f5bd01e9a538b2b 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 bb40270cdad81ad503e07c6e1678a295e01973a0..7f9ccaff1eb844e663ab73abbe2d8efd025feb5e 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 462977066e46e1befe9e06b1f306b31772bb8e02..f9ca1efdb9232f681c603bfc947574f0181ef902 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 3fe0654a6ac59cd5d5e90ed5f14bb652577fad0f..9278d45d5d1eb936e379000bdc6b7eb8332094ef 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 8445bcb5b25b8b84ba08030d4ef86e5494aa47d3..99efa0e7be5042f428078a96889a0d1a01e7b32e 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 8c4a186032b00b154498b9f3109722ebcade319e..d49589bdcca33a2b9b72e7a6dff387d0cb1f55c6 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 2b0eb71fb69cddad291df8d3a6a1ffa8fa7399b1..8de2d5d2ca4bd7c29457fe0da22932a3ef62d591 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 dfc22790052ed9cf52e842eda2f2f0880b26ae0a..ef9383244e7f0563cf5a11dc237d2e3cabad4b30 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 f1d61baa3af106e89913386bd95acd56e1c04514..3231a985e77f135b564913e7bca90e3b8927ef4c 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 48cf1ae2a6c09189cf3a4d627424ecf98fa2fd40..da0ba41680371d730ba919f751b715d691e77054 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 e266279564d847288db9f6fbca192b320b5de748..5b664e64efa1265e82ce5e929f594c1e3882a4b7 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 709198fd584eeebec9368d64ab9107e863ddc17c..b62474f9ba1201c96675e821fd476ceecd27d1fe 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 5408b893f55a801f3bbaad9487bb080b4057fa90..c799ba484968b5612eebb3b03a7b660da8d50dd0 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 e5650bc3fc036c7beedcc83dbd7dca12f4be00db..c4fcbce0c1e467af3f9dca38826efd09aa700aa6 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 6c0e2a432a25bfe2f70b6e099dd4a526a5368d58..5a643609fdefbf98ffd8db03fefc0e160b5e23e4 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 6084dad3cb92bb5d68e79da757e61273e392a55c..f20523487d7f1be4996004f25fe043a4f38acb17 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 983f790cbee93d90e78ed1c1a04aa6f87cc153bf..8ee1b3090782a77b255c4746db00de2bb144c963 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 58d662d76879cd71053ec02cda56927225da7544..fa899d0cb212fb34c7c072c642752090ef7373b1 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 de2f6815a6231c8da112bd63e65fb97bef5b2d2a..eb386d75f96349870e5ac8f24f329076ea176688 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 6b9c8b8fe7fc2f4d5540291e29876e3b1879eb08..1fc586f39f806309b14fa52b879107db2322c1d2 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 d299817f465b35234fc23ac14045e9cfc7ffa0ea..9e93ceb656c7e512b209eed49b9ec4351e8c6f06 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 aa6e9d82bae9077dc98512f4ed8e63ecd574bbca..2aa2ec4e600443b997417c1981183556d77dd513 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 1ff63e3e23127c4c9021bfad96b91e1a247643ce..37a23fa325b8a9cd01a9d627b4fe93a6eba01e27 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 65ac83bcf077cccf092e456c265fcd077872960c..75bf23622acc877f146288a963c407aee033bb68 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 044864cedee2b31345119e0d6ab46ae15214a3b1..884a7bdb6d32d413bca454293fcbf50ecbbb4eac 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 6275be7a0190204d60129926f26add2c4f2b3347..0613df94d9ad4735166fb3ffc0407bd3ffa318d2 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 a8daf6557a5430d9a12afc9e18667476782b32c1..1985c8dc76abae31adefdb4e8a84e85834a81461 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 b86b38beaf5308ae8781c59709c57caff2793dba..c0eb4a8f9b76bd71c2400044843089fd4811f9c6 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 ede31c0162e21014c179c51b6c320d81d87224df..76ecad6b4301d3149db11174bf7a4707396ccc38 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 936dbed786f7d1eedc7029657705439212832492..1a18a5c4400673348dbd88cf93edd1462c36fd01 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 9c700f6260ae019e4f7a7ccc54e0037a0d2953b5..9e93183c3b63f3fac427549c64c7ad475db64a05 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 aafce2990cc8c1b69419377fa629562fea974c76..ed64e3e4300622502e4ca8d20283704121451eb7 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 40adf601c454703e65510813ca3613eb18787bb1..40af5c4fd451b774941d16cf22434037cca3c99a 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 191893ff8bd9394938b46793353a9f9955b7c89b..19df436481627e3625d356f867ec3a59f5ce7a41 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 f747f7c1843eb21f65feb9f2f2e10d7804586a5e..f7b98b294f8135a28658cceb5e596497301ef995 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 19e879d1570d328fd146a15a7ff3a619e90808dc..80df9fe4f94344ea8f167ea9d79be66e6daf4826 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 58ff713c23e7474b118abdf6cd98cba9ff53164c..0d0ef3a69f8f0751306a770ba5f8dc23fcc12b73 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 84a9c979cd2c2630007ec065a7dfc09055350af7..2bb0f33487715da4d8f2db920177d3113e3c319f 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 a79d12fbfb76ab82539dbfe8080a15926a8d2666..54e41311550ed0fce25752933555dbeca3a96ca3 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\""; \\} \\ -- 2.54.0 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 ae5987d03015e1026abd416bd99532abbd2f8072..4ce988e689aada944bc05c91c1c1c93e54b44b3e 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 49b757451b27d0aa42a09e3f1f5bd01e9a538b2b..d786090dc12b8c8fa1e24620d38955429c9e7ef7 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 75bf23622acc877f146288a963c407aee033bb68..1a227a5b935cbbf7e2d7ad3917af384757b25a60 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); } -- 2.54.0 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 4ce988e689aada944bc05c91c1c1c93e54b44b3e..f7bfba6a9950ed12f80ca8be7668be48c82b3d68 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 d786090dc12b8c8fa1e24620d38955429c9e7ef7..d0d38d844dbc928e129b3d5fb15984554843d710 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 c4fcbce0c1e467af3f9dca38826efd09aa700aa6..98d987a73f2126893cf3841e5f6a74db7083d4b9 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); } -- 2.54.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 f7bfba6a9950ed12f80ca8be7668be48c82b3d68..148be3b507da2ec3bc9814401fdecc90c050e3b5 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 d0d38d844dbc928e129b3d5fb15984554843d710..95d2dbac93beaac5c741e429fd6481934fddd340 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"); -- 2.54.0 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 2734e7d54fb715255106115d1450074912b17cf6..6c4d713076d76648f56037aebec105befe9ba5fd 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 223d65f8f42d333eb3eaad96be2b08517354b121..cd908b08685408407bc24a6bb61d86bd00b9fac7 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 ee1d1ac9eec60e509d45bc2fe1c4ac0bdc4b274c..dba57e1f979131b4e577a4af518a0c3b99787b64 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 c6f788deee78bf93cf28e3010a7b22adab0403f3..e901d8d3f78a614fc1d75b63866f4a851e305965 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 aa3ac6d45870325dfcd8788a5545cc490b4b29ff..78ce0b7d0abbf63b290195dfc9157fd0adae2cf9 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 c9e9e3533d6ef892d42f56fe1ffd7a2a852778df..24ab39573413166287b42a79fd69dced5f4df7e7 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 4fcee6ec143d8d1bc64ba981110fe51f6e1e8800..f2cbeff922ed075a8ee6ad1ea62f5d601a91b909 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 1fa7fc594c87be289b1999e37a875d65a19eebd2..28b8371d9d490616e05547d8c281558fcbeae8e6 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 7beabb9cdeeb948c3fe6b4107009dfd091af4907..add40a372d8d482393395600759895aec1d0eb33 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 7c672c7ae89fd56285f4994c17531b1aeee79b22..8e08cacc420aeb3f91501ab7eb6cfb23cef24677 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 fa2424de07a10124afb787b55cc683f72a8aa745..0459b0b15828bb8c1e8350b24fb973622dd95ea2 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 e5574f9ceed4dfbe14e74f05c2b4a3d04d5abf9b..8bff2313fc1def2eadb1bd05e1184710288cbf45 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 f3526cc9fff5c9615846151805ddf04357953cf9..b078ebf3458f86198fd10ed4749a7421c10022a9 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 d74ac86148390f99686c1e7dad6dce055f2a1bab..d5d4cc64a6d63f0d5ccdf595a57112243286344a 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 e1297b11bc709466dcbd0ddd1e76b55532c3b1c8..986c35bf0d2cf55fc02c66c785ea4a3f83b29935 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 362e44a869a8065630578edaee62953fcd314dc5..fd5741a8184311f59ff67ef6add01c1d1fd6c2ed 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 84dbcf939d79fb70c89df8da8de9c0f2595810f8..40b716b00597cbfb475a235ce6a3f4924bec7bb1 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 a4b3fef26b56d674de5707514ef254cd95d3a17f..f895e102a0405f9686e51b49b8227dc147f31428 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 1b74c34edaff97a1383f0b45b1196353cb2513be..89eda4ea2b6966430b09259d16d570cb4482a8ef 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 ded5aa4b1a0899d7a955dc060192e194ca7c482b..903c3a12b33627941aa31f3e563d84bdc3d7be40 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 fcb64d029a1366a474bccefae68c90c09c2cbdd0..d1db1478661d2ec6971b261f281bc20858f44aba 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 e089a024457cd0d45c0f6d926868da8aab084775..bccb7beb1e3ac072e16b1215992c93b1c5d8c699 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 c22d701bf2f1748dbcf42c0fb2ddf0007270832e..d8c77db59b4a48e53f8b610245798ae1d289d73d 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 2cd1583f637a7c834372048a3cde961f0778586c..1fea0526edefc3391d5fe1272a17d91eb531fd79 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 5509f5f9dd2b227e3d005a00d325c7b560046c66..726b84f1250aa6a3ca40f296c81735de309d0cb2 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 3524c4f5b5fed922151172c0b0f7b72dbc9beca3..e84f7b0ac1bc310c645f51cabfcf896335be8caa 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 b4f69753b1a85686d5b29361d24fcf21d1d9fa60..0d3a99a68307cdaacc0c155e34705f878b7a5255 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 c7f286ce3f969ea5653200ac4853297e3247282a..e3d80e4b63d8e7579dd437b40a20f2636c44d79f 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)); } -- 2.54.0 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 3eb30c30586206b32f1822a638fd5cb3275697db..a4000f1b47c5248c82525a4c2a09481c3803dd53 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#}

-- 2.54.0 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 148be3b507da2ec3bc9814401fdecc90c050e3b5..bf558cb8a23f260969620a399971bf612f2d1ad0 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); -- 2.54.0 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 7cd6d1b7bb113e162bd13647451424d53028f42a..cd25001eef07757969db396e72cec43e2a277be3 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 07a7f23968b6dc2fa850e2d896162e6d7c81035b..b25a9035018a6a8c36cb13220d7ed06e3236cbe9 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 a4000f1b47c5248c82525a4c2a09481c3803dd53..627709ec84f94bb92ae06f8c6cb1eb6f7adf60a9 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 d5d73dabbc38f85e758997dbb708a79e0c24c7f9..543863c71e3f1fa98397774c8a634431b29a0d7f 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 2a96fd3fbcd6d2e05ae7df22195a7fb11896d4d7..3f20c66102a48464c086b94b30849cf4f418f6fb 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 c0f02c9a0bcbf53bf9a22c1078adaf969b838682..68a3a6e9f65f416a3d6c9d99a8cfad22f3a0b8f6 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 43425129416bb06533cc7b376094c5cf25a31628..9cdf8e93178404820a75bf8cf529c969ee854f3a 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 214f75186f2e98e2c3a5e3f5c868a83cffda0c3d..951edf2d670882088c60a75ca3f27ca90272088b 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 0d3a99a68307cdaacc0c155e34705f878b7a5255..f8d3a12343a17f0e9624d9efa539d03187db9738 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 bf558cb8a23f260969620a399971bf612f2d1ad0..9225968ce9a1c9b5e0576cce29e48f2e31be7a79 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 6765bf45fb92e9ce2b81500506bac702c70d87e2..2214dc7d547c29f108a82ed6c1c7e0c1776c4b73 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 4c0cc236322f3a0f96b7644582790da58cce9e2d..4e55b374b6ab1367c52755f48618d51c815a8434 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 e3d80e4b63d8e7579dd437b40a20f2636c44d79f..0917c3dbb451a4e20a94c29290990e12a4e73a49 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 54e41311550ed0fce25752933555dbeca3a96ca3..17b089d1dbac633401f153cf1f43216bb1c656ef 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( -- 2.54.0 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 e6d81aeb4fd5cfd9c9cc60555accb39c6529673f..e6e284db1899d30f46feacc0cfcef28e0732a70b 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 }; -- 2.54.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 95036707b6d19305a2da5dc293e8ededead40f4c..d805aeb238bb9d202402966e99a1358cc5661e1f 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 90986049dab68983004c1b0e669b730e73831b37..8ea3218e01a94389b92e618c3e560178e4ebdca2 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(); -- 2.54.0 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 d805aeb238bb9d202402966e99a1358cc5661e1f..215c0ed6fa46e43c70c1f7505e9a1142f3dfbb34 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 8ea3218e01a94389b92e618c3e560178e4ebdca2..1bdd20983736ad82a641629f5eaeffbf1f773b9e 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(); -- 2.54.0 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 d84ef473474a47385ab776ad9a16617f3f5d13fa..4d600d4d38d627aedbfb2a636fd1859367960dc5 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) { -- 2.54.0 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 215c0ed6fa46e43c70c1f7505e9a1142f3dfbb34..af3ac5475d6db741fef0c68d1f19633035157362 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, } } -- 2.54.0 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 899e74105b6eaebff50f98e603771b93e23c2c2f..3388e35128e49054f0240a13ad20e497f6a4e701 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 4d600d4d38d627aedbfb2a636fd1859367960dc5..5c0ac3d905dbea213f3faa86327b4fbac8311fc4 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? -- 2.54.0 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 af3ac5475d6db741fef0c68d1f19633035157362..0f7c76438f84e54a711dd5107d58f9cceb43e79f 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 1bdd20983736ad82a641629f5eaeffbf1f773b9e..49dbdbb2180dc6d0e3589745ac9136e5cad60d72 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; -- 2.54.0 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 0f7c76438f84e54a711dd5107d58f9cceb43e79f..1f680cd3ecd2f144fae0e71c7a682584ff57caad 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); -- 2.54.0 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 9225968ce9a1c9b5e0576cce29e48f2e31be7a79..507b3e445989d899d03ebf9a5cbfa31e93d402a8 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 85b58faefc177a0dc531e99ee7dc530e49218e82..89cfab22c2927cd6eec4e1132d5f6bcd6c717e4e 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 e3947077c8f018a98da79922ef00559237c2308f..64af959f53f548022be9830c67174bc892f25f19 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 40af5c4fd451b774941d16cf22434037cca3c99a..497aa7e5740fc04494067b7fae9c672d1d15c882 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); +} -- 2.54.0 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 1f680cd3ecd2f144fae0e71c7a682584ff57caad..24d312e3f6b08b16cac7edddc2595c460091ba40 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); -- 2.54.0 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 d6dba254e5e64711d6b488a3d649959bbaa7e448..98400f23cbcfd8337cd407bd9d0943aaff4d6a7e 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 { -- 2.54.0 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 98400f23cbcfd8337cd407bd9d0943aaff4d6a7e..bbfa47f407a097c13d1ab1f64840cb6fab1f7c3c 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 { -- 2.54.0 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 3f20c66102a48464c086b94b30849cf4f418f6fb..0d9de44f79b7aedfda4a710a2abb916584c70868 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(); } -- 2.54.0 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 bbfa47f407a097c13d1ab1f64840cb6fab1f7c3c..7ee8b9a7561d9f38207c147573b7c493cf228bc2 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, -- 2.54.0 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 7ee8b9a7561d9f38207c147573b7c493cf228bc2..af79f227572a9e1ee56e694be9100ba842b3ab08 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; -- 2.54.0 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 178811bb1e80e3c715e8f86c27c583c788e6310f..b5b8a9c2d4df0de2ca3b49b86311c338a26d96bf 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; -- 2.54.0 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 af79f227572a9e1ee56e694be9100ba842b3ab08..531b8ce7972492a80291e9ab61394885ea2321e0 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, -- 2.54.0 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 899e74105b6eaebff50f98e603771b93e23c2c2f..ade3dabea3313a8c2d0c0810ea69a17b682965e5 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 e6e284db1899d30f46feacc0cfcef28e0732a70b..d329855c03319f29dad7b878877e6cf824179e97 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); } -- 2.54.0 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 e901d8d3f78a614fc1d75b63866f4a851e305965..743ca4d9201a4a1b667b7768cc31115740c55cd3 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; -- 2.54.0 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 28497ad6f1aea13ff7f6069993c05b5e153d7ba8..e9b4cd6455226068235a1849f43d8a6eaabdff72 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 81ba8e941cd9d7bc658c6a03394a7adfeb2c2de7..c6912087cf6ae2622cc978cd5fcd9b3618010c73 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 b401b25aded199a7cf75bf835e3718bdb75c9d12..ae82cb7602f14d7dc7705fae65312c6865c74c43 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 674f0c2b963e2802bd9aeb4244dfa5b2971575cd..8b301f85ac6876571fa26fc844b33e733b27b71f 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 4e55b374b6ab1367c52755f48618d51c815a8434..dfa33e26bde620616e9d5f7093d44332611c7625 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; ); -- 2.54.0 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 a1ece3ed10b86e75003f55ad82ce415e2b7eb360..484e145cfa0a59be451e73b4aab7c892d8c21db2 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? -- 2.54.0 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 8315cd84cf4798c8710631648237bc5d42fc8b0a..8052f0b31a152b552ea6f1362916ffd8ce8a6985 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 8ba2bfc50351a0c78045d25661746d57d48eadd4..4d751bae2c757aabd356e6373f59497c29b5f5d3 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 66e1f8984bc7eff56786579c49932ff3fd017e60..ae5b626c293c642f6ddaa3975a4549b3c66ef42c 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 c016f629d1eaf1feec66581a340de5c1a222e658..34cbed245a193dc4f67433195b31b5a3c50971f6 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 507b3e445989d899d03ebf9a5cbfa31e93d402a8..f1b31af58261f9cd04f45886bf3cf8695f8413ad 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 89cfab22c2927cd6eec4e1132d5f6bcd6c717e4e..da7ae38e5ffd080b4b4beec2d2e0e32aa04af530 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 0917c3dbb451a4e20a94c29290990e12a4e73a49..c64f5b38a56cf8ee8b3d9019b8d2b7fc84c92b40 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 99efa0e7be5042f428078a96889a0d1a01e7b32e..f44ca541ebadedb029aa2154bcfa25c7de8e64da 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 76ecad6b4301d3149db11174bf7a4707396ccc38..571343e2818d3984ad9cf8eb4490a15b9a72d389 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(); +} -- 2.54.0 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 497aa7e5740fc04494067b7fae9c672d1d15c882..de98a26d55db163c2dd6213983f69692c54e7526 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(); +} -- 2.54.0 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 f9ca1efdb9232f681c603bfc947574f0181ef902..0558a47fa44862a48f3f20cca29ffe4c5ae3d121 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(); +} -- 2.54.0 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 9f32c6e54b5531297160f54b877d5088b337879b..e705aea477f2cadf2f26cbe3654caa834ac39692 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 4c6c461c0139577a187c98e2f5e921833e69f5cd..6d5d4b5f2d9224ed38a53038a35650ef489d6951 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 e9b4cd6455226068235a1849f43d8a6eaabdff72..f61442adfc95ce7b8a99403ef3b1f93fca63e66a 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 c6912087cf6ae2622cc978cd5fcd9b3618010c73..c824939296a2b5e29d06cdf405f8ad02fb4a6099 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: { -- 2.54.0 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 f1b31af58261f9cd04f45886bf3cf8695f8413ad..e278193785a83da14b3660eee478783166b26640 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 de98a26d55db163c2dd6213983f69692c54e7526..caad1d474fb9c930fc1c547ce95e47f974bd17bd 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(); -- 2.54.0 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 4d751bae2c757aabd356e6373f59497c29b5f5d3..e38e8572093aef2357812ba90ecde61d9e93c695 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 ae5b626c293c642f6ddaa3975a4549b3c66ef42c..d8ff4f2848bcff5187c900ee889150672e90d07b 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 a6af371e25eaa5ba91cda02ef5f88220fb6e395a..7de51092e8521ffaec0a8161160b2b6f57130ab4 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 e278193785a83da14b3660eee478783166b26640..fb2b0ed841c26545f7622eae6382c2161184ab5d 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 571343e2818d3984ad9cf8eb4490a15b9a72d389..6b9ddacabc81f942c9e302a791ae75d3c569fea6 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(); +} -- 2.54.0 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 c64f5b38a56cf8ee8b3d9019b8d2b7fc84c92b40..1adf3c3f8e9dd7f617d1629e81986b4da0ecb07a 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; -- 2.54.0 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 d8ff4f2848bcff5187c900ee889150672e90d07b..316fa52ac59353279149816ef90a5e4e15f241f5 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 7de51092e8521ffaec0a8161160b2b6f57130ab4..06c8847edac678d5f5a59d5fa8c4a3c43994c85d 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 fb2b0ed841c26545f7622eae6382c2161184ab5d..9d15e341daf4551d72264c3c2418df2f8a2b495e 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 6b9ddacabc81f942c9e302a791ae75d3c569fea6..a42c261e3b042bcd1089fc1a411c8b7fa92c4cd2 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(); +} -- 2.54.0 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 627709ec84f94bb92ae06f8c6cb1eb6f7adf60a9..b0003a714b98f2f696b4866df1c291506b4ec65f 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#} -- 2.54.0 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 4861def16cac5302665c4bf82dd671fec292d0f0..a2fc0c0687da466482cd2d419b60d10cea285071 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) { -- 2.54.0 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 316fa52ac59353279149816ef90a5e4e15f241f5..4c63c566e9aae37af5f3807d327e7c82ce8b1ae7 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; -- 2.54.0 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 9d15e341daf4551d72264c3c2418df2f8a2b495e..1e08598eca75eedcd345565fa43e7cec05772530 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 d49589bdcca33a2b9b72e7a6dff387d0cb1f55c6..c6344b17cab81411dc379cc3a6c8c3ddce376596 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); +} -- 2.54.0 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 356d9cac79d5d41d4d945cbd02dbdfbf57e8e13d..43593b348ab35822cbb331c1311b69c3961cf483 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 c05e740b093b1e456a8b774f52316231228878df..3a64b9df8c0560e01bf62662fa54637f2aa448ae 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 add40a372d8d482393395600759895aec1d0eb33..dc792b398c28e1fa23fd60fddbb319740bd12514 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 9b44e2edc3b2dc85b2d7fa97be5b4636c3ad8c8b..706c699a8771ba3295aea5ed852c34d0301876bf 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)); } } }; -- 2.54.0 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 9d15e341daf4551d72264c3c2418df2f8a2b495e..f193f5d0b9b04098676c4edf305a6c85c12a1d3f 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")); -- 2.54.0 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 b0003a714b98f2f696b4866df1c291506b4ec65f..f5fbb4e3a302d92d0d7ef503f5a6ff25cf495ec3 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 e38e8572093aef2357812ba90ecde61d9e93c695..1acd855b96a70d3f3b5af7b512db29c71c051376 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 a2fc0c0687da466482cd2d419b60d10cea285071..3ed269e621a435e485b3b9e270c2d76f2840711f 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 4727c32d5d81f02c60d215945be8cc1368707a64..f5f1ea3e80e29db38ebe89448651ff4e0d0546a1 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 da7ae38e5ffd080b4b4beec2d2e0e32aa04af530..03224d803788e9970224443f132da974a406058d 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 c6344b17cab81411dc379cc3a6c8c3ddce376596..9e41863fd12f8bd59ac99c0f8d79d5e66a796fe1 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 -- 2.54.0 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 173355eb3b7f29ab53eb13989f1388c38c7fedc6..9d6b15ff4a1005489495bdec90377aabb6a090a5 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 664191eb7773b632b0c50ff2fc8e341f5e76a4f3..4246e15985474239b70904f4dffd5cf4d75473d0 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 2ea99d234d6d84ec63019f6e5fcb083caa4680cc..ac5a65e1b0d1b297e1a435c347ae6ee6e1da9df6 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 43593b348ab35822cbb331c1311b69c3961cf483..5261db990c8cd5e90e94b257889192bc99467ab2 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 576a09064f9027c12f956eee8030413dd03d20f7..a95c5bf7e2425c31141f5e586bc7d781fe1e2ea7 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 543863c71e3f1fa98397774c8a634431b29a0d7f..a6284411eb123e9056d4312a8f2d24f04b3cc6ca 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 3a64b9df8c0560e01bf62662fa54637f2aa448ae..ec4ab8f6d00de4a964bcf53413f0628b26e7ca06 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 618a21f4568ccc129e9e7490ad8ea4e6a28c33ea..7e2f14021fd1b6dd7b13aea543175e2bd70cfcc3 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 3bed3d3891fec6c9ba060d5ff892488d73660bca..bd811f709cbf46cdb367c4851c248ed8b118d772 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 9e41863fd12f8bd59ac99c0f8d79d5e66a796fe1..894f99b7e077f7aa9d7fc876af0930723983ccd3 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 +} -- 2.54.0 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 f5f1ea3e80e29db38ebe89448651ff4e0d0546a1..e794e8db0362098a219c63b396e51efb9a6421b5 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 1adf3c3f8e9dd7f617d1629e81986b4da0ecb07a..c42c95465a9720dbdc7da7ac9270f80ec2d2d8dc 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 894f99b7e077f7aa9d7fc876af0930723983ccd3..694eb160e4b2580238dc23d3210f9ce80f8a1a39 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 -- 2.54.0 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 b0003a714b98f2f696b4866df1c291506b4ec65f..bca12c62d75de6648a781c5f7cf37a8d03d0100a 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 543863c71e3f1fa98397774c8a634431b29a0d7f..588cd3c8b51a21b149f67109dcfa9c1f268b47f7 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 e38e8572093aef2357812ba90ecde61d9e93c695..1464dfba598bc4ac911043d0548eb96b5a7777de 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 a2fc0c0687da466482cd2d419b60d10cea285071..558a7011f0ed430f179d82c04182a46f32c30e84 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 4727c32d5d81f02c60d215945be8cc1368707a64..3b7ef42f044127e737ca2fa435ef29e12a20e4b2 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 1adf3c3f8e9dd7f617d1629e81986b4da0ecb07a..47333b7db4107279389354130c3274723b431a0a 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 1fc586f39f806309b14fa52b879107db2322c1d2..99d145f1b1eb7fc6a32db95d267d10861bba5af4 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(); +} -- 2.54.0 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 4c63c566e9aae37af5f3807d327e7c82ce8b1ae7..1232cebe8b5d891d223dd2a3f9dfbaad01eea3ad 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 06c8847edac678d5f5a59d5fa8c4a3c43994c85d..884f525717b1ff95b18f55fb23caf6ae401d7fe0 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 558a7011f0ed430f179d82c04182a46f32c30e84..387c6120c21a519b2ae2b1e05218f6a60a7b1e67 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 3b7ef42f044127e737ca2fa435ef29e12a20e4b2..676f69dea749e1f7089e387922e14bae1fe91eca 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 a42c261e3b042bcd1089fc1a411c8b7fa92c4cd2..722f44d352e28742396575e7ffb2b69b20d1c4db 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); +} -- 2.54.0 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 5d989c1bbdb634a67e2ba827a2c4c63b4fd432ca..dc44dd287fdd6b97aae8a8c1a235d0954972e87c 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 7b0747da7b0783fe9e8c2f2e32e00de6908d766c..05edae0b9b8daeb6e7b71deef461fb1387b130ef 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 02305086cc5ea6904474d0d9c6d001b25db5f6ba..3cf4306ea589a7476e10f579cb89c9c74f8173f0 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 f2cbeff922ed075a8ee6ad1ea62f5d601a91b909..a5a8b6efbca1b4f4fc2671b5ececf9f72631f9db 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 ecf0bf822bdcca12ab8390c462f9d67c146c1e30..6946ba0170d9eee92962348de49556fa3850c87e 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 fba77092b30ae47cb8fe92a4e245f601b0e50748..034d7ade26eb8abf4bc5c10cee4f718f477488a1 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 efe3275fe6f1563cd8bdd3ae8d061a59a1f3c226..fdf5193c0339290d29706c1a8ef575fe9f2f0ad1 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 f8b18af73410cfd583f6e849754ceacd9af539a9..8122e537ed4b162f253a7cae01129896755c2474 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 f61442adfc95ce7b8a99403ef3b1f93fca63e66a..cabbe823f6ebd29c63ff1271fe7b3ca36110c449 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 a2e77394ce2008e177a50cac923bc59822d6990a..71f978118613655102d94b1eb161da3d1fc4d366 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 e84f7b0ac1bc310c645f51cabfcf896335be8caa..37945bf02952146d25ab18aefb02f068f2ca06da 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 ce51de9a7b6315e9f142029b09ba4c5bcc3faf55..496a7e05042dfd422b4d7660259348c865e1ba2f 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 dfa33e26bde620616e9d5f7093d44332611c7625..0842fc46298730d6aacaf3e9bd6dcdd382664cf6 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 c1b8106e07e7115048d0d5f5f548e272ea81bbcc..e291f2313bc79f0a64f80b76cb57ed952ec6b7da 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 c57c1e4bcbffa7b8b33a258ea6075184c97bf909..7c15c15e53cbfffa6dd5e60c155121088c096d35 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 b1e557fd20c51cd6a39766236bb9772a772ea114..8119b70d7e26ec9c09d7b57dc6e4e25a48892663 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 cb7d5ef157e051c5f286a1014562caeab65c5bb4..2ae5782328e6ad04e0e496c879f462809018296a 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"); -- 2.54.0 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 d5199a1fa8fefdcfd7adba00145969741b26b93e..d4475fcf810cae8e7e5eef60a4e0b0fc51c766dd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![ZIG](https://ziglang.org/zig-logo.svg) -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 dc44dd287fdd6b97aae8a8c1a235d0954972e87c..5ecf312044237c39228ebcb52c76013d31cf0bcd 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 -- 2.54.0 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 b6cc3cd4cb71c79bbdb7b2bc790896748442c23d..e5afc882d47da02bedf78529f4dff95af66eb360 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 63d7240d4231e3739d760fff3faf9b60b5a999c8..d4c16a7d5f3589975a453a53552b1cc3fc2d5183 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 { -- 2.54.0 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 951edf2d670882088c60a75ca3f27ca90272088b..bf71ca22aacb1b3c53dfd4c7566bac3153c3d3d0 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)); -- 2.54.0 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 bf71ca22aacb1b3c53dfd4c7566bac3153c3d3d0..eb37a7e3964dfc11321de9251559c993d7d83add 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)); -- 2.54.0 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 eb37a7e3964dfc11321de9251559c993d7d83add..3dc772a7c3566e8b290379bd7dfc75c3defa44e1 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)); -- 2.54.0 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 3dc772a7c3566e8b290379bd7dfc75c3defa44e1..2f65c27e47852d5a99a08a751ad922f676d974d6 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)); -- 2.54.0 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 b5b8a9c2d4df0de2ca3b49b86311c338a26d96bf..a1ceb8ff5ce8c72a3a326bffb1c6654d340824ae 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; -- 2.54.0 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 9cdf8e93178404820a75bf8cf529c969ee854f3a..bc360e7e7021629fb825050fa2a289031d62493f 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 0000000000000000000000000000000000000000..1fe5d87496820b52ef40c3cdb7b6989b05b4dfb6 --- /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; -- 2.54.0 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 bc360e7e7021629fb825050fa2a289031d62493f..4d2944b563a39d5d97c74c5d80d3a95a7a41ff10 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 d466f9946dbabb0b2d74ee158985a801c665679a..30c4cf4785716f0538d254f1d887bd7e80909834 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; -- 2.54.0 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 4d2944b563a39d5d97c74c5d80d3a95a7a41ff10..e8011b753409d34f19e92fd124e1d9dfd53cc8bb 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 { -- 2.54.0 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 25815ef64a7326a499a640b190c59a79089ecac4..e246016006de9ba3bf2c4c2a9d4d9916beeb9209 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 1232cebe8b5d891d223dd2a3f9dfbaad01eea3ad..ee95e5d2460ac63f07398210f51ce96990ee9749 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 884f525717b1ff95b18f55fb23caf6ae401d7fe0..0cca75891ac7d78abf22ef7891a7e998cea5f207 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 a0666a35224b51f39fe65339c9d30540ce7fe700..ed9b69e52966b19ba48b8196d52bba2470870276 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 e5afc882d47da02bedf78529f4dff95af66eb360..d52daacc424ced035ef36dbb97113c4e4270a04b 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); -- 2.54.0 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 e246016006de9ba3bf2c4c2a9d4d9916beeb9209..a1e9d76be7d8e9245809cd942b6217ebf3b89eee 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 ee95e5d2460ac63f07398210f51ce96990ee9749..0a8b32dca7b6ebde8e4a359fca345c32b1e925a9 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 0cca75891ac7d78abf22ef7891a7e998cea5f207..ddfb31c286f52381933ce7767cfd1eeac2bc702e 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 ed9b69e52966b19ba48b8196d52bba2470870276..a97f5cbd55046363d224219e5bee92a017d07687 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 9703d3e57d107b157e5de956c048c24942fe473f..b5fd38e26689deb90bed527c7a901f38013eecfb 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 d52daacc424ced035ef36dbb97113c4e4270a04b..99af2e7861aa763e3c1a256cfb6305bef8e839fb 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; -- 2.54.0 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 e705aea477f2cadf2f26cbe3654caa834ac39692..65fbc51606389c0be945b955c2e33e0cdf620071 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 6d5d4b5f2d9224ed38a53038a35650ef489d6951..d803beeffa87ace3c7209903f3eb4e281edb9cf4 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 cabbe823f6ebd29c63ff1271fe7b3ca36110c449..b429a575a3b9a330591db4bf3e3df2ec6581c7e5 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 c824939296a2b5e29d06cdf405f8ad02fb4a6099..258a5493de312aea38133310ef0043c447685910 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 ae82cb7602f14d7dc7705fae65312c6865c74c43..d3646a6a6b0c86d6890b450c2efddff82da6f36d 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 f8d3a12343a17f0e9624d9efa539d03187db9738..e91997711649666227e6a6bc94c1c9d114ce9816 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, }; -- 2.54.0 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 a97f5cbd55046363d224219e5bee92a017d07687..a288f397fd2c0d706e6307b33cb4334fdf6962dd 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 caad1d474fb9c930fc1c547ce95e47f974bd17bd..d7481b21c71dd7b71963e7bed8cc519109e4180e 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); +} -- 2.54.0 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 2ae5782328e6ad04e0e496c879f462809018296a..e3fc5c0e3eab4b688f1e77c2ff6cd0661436eb5f 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. -- 2.54.0 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 e8011b753409d34f19e92fd124e1d9dfd53cc8bb..e55ac3fe8ff744fe7d64957d204b954b854ce372 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 1fe5d87496820b52ef40c3cdb7b6989b05b4dfb6..d47c5a3d1d81edf2c331ed772a0ecff917805293 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, -- 2.54.0 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 293891123e4dfff52dd3fae19b0fea41bea0701e..d70b1cfefa31dfa842b74f6cd78dd2cfe19a0293 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, -- 2.54.0 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 e55ac3fe8ff744fe7d64957d204b954b854ce372..06da223d5c3804ea8818919737787c379ae96c10 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 d47c5a3d1d81edf2c331ed772a0ecff917805293..c34077a9dc0d4262b369de5f891e39f6b175161f 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; -- 2.54.0 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 a1e9d76be7d8e9245809cd942b6217ebf3b89eee..c4178cb130e66f29c424378509a6d4d92de8c54e 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 484e145cfa0a59be451e73b4aab7c892d8c21db2..eef832e32c33597af8b9f9e4703b85d9ffa7eeef 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 8b301f85ac6876571fa26fc844b33e733b27b71f..7ece5ff3fe1a996d26c9aa347a127bd340eb0ffc 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 ee336123bb2fc1e6fe0969b7457473859f53e4c5..149e58b6a7fd2a1b59873a5e2a56d46e127d11b5 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -43,6 +43,7 @@ enum TokenId { TokenIdDash, TokenIdDivEq, TokenIdDocComment, + TokenIdContainerDocComment, TokenIdDot, TokenIdDotStar, TokenIdEllipsis2, -- 2.54.0 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 81df8f30f1aea0cacbe223c07beae79a070cf79e..b170ad4a1423bc1fe41b9ea99ac23989f7bd7446 100644 --- a/lib/std/special/docs/index.html +++ b/lib/std/special/docs/index.html @@ -484,7 +484,7 @@ doc comments.

    - +